.공개용버전
Git을 사용한 시행착오를 하며 남긴 글이다.
dev 브랜치에 정기적으로 동기화해가며 feature 브랜치에서 작업을 하는 경우를 따져보자.
dev의 881
커밋까지 동기화 한 뒤에 feature 브랜치에서 아래와 같이 c1b
작업을 해놨을 때에 그래프는 이렇다.
* c1b - Add B - Me (HEAD -> feature)
* 881 (origin/dev, dev)
(대략 git log --graph --oneline
을 하면 이 그래프와 비슷하게 출력된다. 그래프처럼 안 보이지만 그래프이다.)
여기서 아래와 같이 merge하면
git checkout dev
git pull
git merge dev
아래처럼 된다. dev에 새로운 커밋이 올라왔으므로 두 개의 브랜치가 머지되며 머지 커밋이 생긴다.
* fc3 - Merge branch 'feature' into dev - Me (HEAD -> feature, dev)
|\
| * c1b - Add B - Me
* | 9c0 - Add A - Another
|/
* 881
(이렇게 보니까 좀 그래프같지?)
rebase를 사용해 머지 커밋을 만들지 말고 동기화해보자. 다시 feature 브랜치가 아래와 같을 때에,
* c1b - Add B - Me (HEAD -> feature)
* 881 (origin/dev, dev)
fetch와 리베이스를 해서 머지 커밋을 만들지 않을 수 있다.
git branch # feature
git fetch origin dev:dev # origin dev dev fetch.
git rebase dev # feature dev .
그럼 아래처럼 된다.
* ca1 - Add B - Me (HEAD -> feature)
* 9c0 - Add A - Another (origin/dev, dev)
* 881
dev에서 머지해주면 dev의 그래프는 feature와 같아진다.
git checkout dev
git merge feature
만약 feature에서 git fetch origin dev:dev git rebase dev
할 때에, 컨플릭이 날 수 있다.
git rebase dev
First, rewinding head to replay your work on top of it...
Applying: Add B
error: Your local changes to the following files would be overwritten by merge:
path/of/conflicted/file.txt
Please commit your changes or stash them before you merge.
Aborting
error: Failed to merge in the changes.
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Patch failed at 0001 Add B
Use 'git am --show-current-patch' to see the failed patch
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
위와 같은 메시지가 나왔을 때에 해결 방법은?
1. 시키는 대로 적절하게 리베이스해준다.
2. 잘 모르면 포기한다.
나는 잘 몰라서 리베이스 하는것을 포기한다. 메시지 마지막줄에서 abort 하라고 한다.
git rebase --abort
하면 feature 브랜치는 리베이스를 시도하기 전으로 돌아간다. 위에서했던 머지를 한다.
git checkout dev
git pull
git merge feature
Git은 checkout 하게 되면 워킹 디렉토리를 건드리기 때문에 로컬 파일을 수정한다. 별로 느리지는 않지만, 나는 계속해서 feature 브랜치에서 작업하고 싶은거지, dev로 왔다갔다 할 필요가 없다. 체크아웃하지 않고 이런저런 브랜치로 fetch, rebase, merge 등을 할 수 있으면 좋겠다.
위의 git fetch origin dev:dev
는 그래서 찾아낸 명령어 중 하나다. 이전에는 git checkout dev; git pull
을 했다. pull은 origin에서 커밋을 당겨와서 머지하기 때문에 브랜치가 fast-forward 된다.
만약 feature 브랜치에서 git fetch를 실행하면 git은 origin/dev에서 커밋을 당겨는 오지만, 머지는 하지 않는다. origin/dev와 dev가 다른 커밋을 바라보기 때문에, git rebase dev
한다면 origin/dev와 그래프가 달라지게 되고 충돌이 날거다.
그래도 origin/dev로 리베이스 하면 된다. 단점은 글자수가 많기도 하며 하다보면 잊어버릴 위험이 있다. GUI를 사용하고 있다면 글자수는 상관없으니까 origin/dev로 하면 괜찮겠다.
참고로 feature 브랜치에서 git fetch origin feature:feature
를 하면 fatal: Refusing to fetch into current branch refs/heads /feature of non-bare repository
에러를 뿜고 fetch는 하지 않는다. 현재 브랜치에는 안된다고 한다. 그냥 pull을 하면 된다.
git add/rm, git rebase --continue, --skip
를 할 줄 알기https://git-scm.com/book/ko/v2/Git-%EB%B8%8C%EB%9E%9C%EC%B9%98-%EB%B8%8C%EB%9E%9C%EC%B9%98%EB%9E%80-%EB%AC%B4%EC%
97%87%EC%9D%B8%EA%B0%80