Git의 작동 방식에 대한 Bottom-Up 방식의 설명
Git
Git의 본질은 분산 버전 관리 시스템(DVCS) 으로, 협업을 전제로 하는 브랜치 기반 워크플로우이다. Git은 루트 디렉토리 전체의 디렉토리 구조 및 파일 내용을 스냅샷으로 관리하는 시스템을 의미한다. Git이 관리 중인지 아닌지에 따라 파일은 Tracked / Untracked 로 구분된다.
Git에는 세 단계가 있다: 1. 작업폴더(Working Directory): 작업 중인 폴더 2. 대기실(Stage): 커밋을 실행하기 전에 작업폴더와 저장소 사이에 존재하는 가상의 준비 공간 3. 저장소(Head-Repository): 스냅샷이 기록된 영구 저장소

git init
작업폴더를 git으로 관리하려면 먼저 git 리포지토리로 변환해야한다.
git init 명령어를 사용하면 작업 폴더 내에 .git/ 이라는 Git의 로컬 DB가 생성되며 git 리포지토리가 된다.
staging
git으로 관리 중인 작업 폴더에서 git add를 통해 파일을 스테이지에 복사할 수 있다.
git add <path> # <path>를 스테이징.commit
verb. 현재 스테이지에 있는 파일들을 포함한 새로운 스냅샷을 만들어 히스토리를 기록하는 행위. noun. 커밋 행위의 결과물인 스냅샷 자체를 의미.
git commit -m "의미 단위 커밋을 위한 메시지"patch 패치
두 버전(커밋) 사이의 차이(diff)만 모아놓은 변경 기록.
주 용도: • 코드 리뷰 용(diff 보내기) • 다른 저장소에 변경 사항 전달 • 작은 수정만 패치로 받아서 적용
git diff > patch.diff
git apply patch.diff즉, patch는 diff 묶음이고, commit은 스냅샷 전체이다.
git rm —cached path git add -u
snapshot 스냅샷
스냅샷 = 특정 시점의 디렉터리 구조와 파일 내용을 그대로 찍어서 저장한 상태.
Git은 매 커밋마다 폴더 전체 사진(snapshot)을 찍는다. 근데 이미 이전 사진과 같은 픽셀은 새로 찍지 않고 기존 사진 조각을 재활용한다. → diff 이용.
GitHub 원격 이용하기
이미 있는 원격 git 리포지토리를 로컬로 가져올때 → git clone
하지만 git init은 원격 리포지토리를 만드는 작업이 아니다. GitHub를 사용하는 경우, GitHub 웹에서 repository를 생성 후 로컬 저장소에 원격 저장소를 연결해야 한다.
push 푸시
로컬 Git 저장소의 커밋들을 원격 저장소로 업로드하는 과정.
git push origin main• 로컬의 새로운 commit들이 원격에 반영됨
• push는 commit을 전송하는 것이지, 파일을 직접 업로드하는 것이 아님
• push하려면 먼저 commit되어 있어야 함
pull 풀
원격 저장소에서 새로운 커밋들을 내려받고, 내 로컬 브랜치에 병합하는 과정.
pull은 사실상 fetch + merge 따라서 pull은 단순 파일 다운로드가 아니라 새로운 commit을 통합하는 작업이다.
여러 클라이언트에서 개별로 작업을 하고, 합치는 과정은 생각보다 간단하지 않다. push와 pull만으로는 공동작업의 히스토리와 동기화 문제를 해결하기 어렵다.
여러가지 시나리오와 병합 방법에 대해 이해해보자.
merge commit(3-way merge)
두 브랜치(분기)의 히스토리(변경 사항)를 모두 유지하며 main에 병합한다. 각 브랜치의 변경사항들이 그대로 보존된다.

3-way merge (1) main과 feature의 공통조상인 main 2번 노드 → 분기점 (2) main의 최신 커밋이었던 main 4번 노드 → 수정점1 (3) feature의 최신 커밋이었던 feature 2번 노드 → 수정점2
squash and merge
squash: 분기점 이후의 변경사항을 하나의 커밋으로 합치는 것

rebase and merge
분기점 이후 feature 변경사항을 재위치 시켜서 병합한다.

fast-forward merge
분기점 이후 메인에 변화가 없다면, feature 변화를 그대로 main에 병합하면 되기 때문에 발생한다.

Resolving Conflicts
브랜치 병합시에 충돌이 나면, 사람이 직접 충돌을 해결해야 한다. 깃허브에서 직접 충돌 해결창에 들어가면 다음과 같은 모습을 볼 수 있다.
Accept current | Accept incoming change | Aceept both changes
<<<<<<< current (기존 코드)
A
=======
B
>>>>>>> incoming (가져온 코드)
A는 기준으로 대체 당하는 쪽. B는 대체하려는 후보이다.
여기서 both changes를 고르게 되면, 순서대로 둘다 넣는다.