커밋은 git 저장소에 작업 디렉토리에 있는 파일의 스냅샷을 기록하는 것.
디렉토리 전체를 복사 붙여넣기 하는 것과 유사하지만 훨씬 유용하다.
git은 커밋을 가능한 가볍게 유지하기 위해 커밋할 때마다 이전 버전과 현재 버전의 변경내역을 저장하고, 이전 커밋을 가리킨다.
$ git commit -m "commit message"
브랜치는 특정 커밋을 가리키는 포인터다. 따라서 브랜치를 많이 만들어도 메모리나 디스크 공간에 부담이 되지 않는다.
다음 명령어로 브랜치를 생성하면, 현재 작업 중이던 브랜치의 마지막 커밋을 가리키는 브랜치가 생성된다.
$ git branch feature
HEAD
는 현재 작업 중인 로컬 브랜치를 가리킨다.
위의 브랜치를 만드는 명령어는 브랜치를 새로 만들기만 할 뿐, 현재 작업 중인 브랜치(HEAD의 포인터)를 변경하지는 않는다.
작업할 브랜치를 변경하는 것은 checkout
명령으로 가능하다.
$ git checkout feature
브랜치 간 병합.
Fast-forward는 현재 브랜치가 가리키는 커밋이 merge 할 브랜치가 가리키는 커밋의 조상일 경우의 merge 방식이고, 3-way merge는 그렇지 않을 경우이다.
Fast-forward merge는 단순히 머지할 브랜치가 가리키는 커밋으로 포인터를 이동시키는 것 뿐인 반면,
3-way merge는 각 브랜치의 마지막 커밋과 공통 조상의 마지막 커밋을 비교해서 새로운 커밋을 만들고, 브랜치가 그 커밋을 가리키도록 이동시킨다.
merge 하려는 두 브랜치에서 동일한 위치의 코드를 수정했을 때, merge conflict가 발생할 수 있다.
$ git merge iss53
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
이 경우, git status
로 어떤 파일을 merge 할 수 없었는지 확인할 수 있다.
$ git status
On branch master
You have unmerged paths.
(fix conflicts and run "git commit")
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: index.html
no changes added to commit (use "git add" and/or "git commit -a")
충돌을 해결하기 위해 코드를 수동으로 수정해주어야 하며(올바르지 않은 쪽 코드를 제거하는 등), 수정된 내용을 커밋할 때 merge에 대한 내용으로 자세히 작성해야 한다.
브랜치 간 작업을 합치는 또 다른 방법.
리베이스는 기본적으로 커밋들을 모아 복사한 뒤, 다른 곳에 떨궈 놓는다.
리베이스를 하면 커밋의 흐름을 보기 좋게 한 줄로 만들 수 있다는 장점이 있다.
(rebase는 말그대로 base를 재설정한다는 의미로, 커밋 흐름을 조작하는 것이다)
로컬에는 없지만 remote 저장소에는 있는 데이터(커밋)을 모두 가져오기.
$ git fetch origin
git fetch는 데이터를 로컬로 가져오기만 할 뿐, merge는 하지 않는다. merge 까지 한 번에 하려면 git pull
을 사용할 수 있다.
git fetch + git merge origin main = git pull
https://learngitbranching.js.org/?locale=ko
https://git-scm.com/book/ko/v2