나뉘어진 branch들은 서로 merge할 수 있고, 이것이 branch를 나눈 가장 큰 이유이다.
branch 간의 merge는 commit간의 merge가 아니다. 즉, branch 끼리의 merge이고, 항상 branch의 HEAD와 병합하는 것이다.
[Master] <- HEAD
|
|
(987fac...) --> (236ff...) --> (92faa...) --> (2456...)
|
|
[Bugfix] <- HEAD
다음의 경우 Master
branch를 Bugfix
branch와 merge하는 것이다. 그런데, 잘보면 이들은 분기되어 있지 않고, 하나의 라인이 쭉 이어진 모습이다. 따라서 Master
branch가 Bugfix
branch를 따라 잡는 것이 전부이다. 따라서 'fast-forward' merge라고 하는 것이다.
git merge bugfix
이렇게 merge하면 다음과 같이 된다.
[Master] <- HEAD
|
|
(987fac...) --> (236ff...) --> (92faa...) --> (2456...)
|
|
[Bugfix] <- HEAD
이를 실제로 사용해보기 위해서 master
branch에서 다음과 같이 실행해보도록 하자.
echo "playlist" >> ./playlist.txt
git add .
git commit -m "add: playlist.txt"
다음으로 bugfix
branch를 만들고, playlist.txt
에 다른 문장을 추가로 넣도록 하자.
echo "goodbye world" >> ./playlist.txt
git add .
git commit -m "update playlist.txt"
git log
를 통해서 확인해보도록 하자.
git log
commit b0ca514a88a87c85100c3e4fa6f78fd0d2131f27 (HEAD -> bugfix)
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:03:03 2024 +0900
update playlist.txt
commit 5e0b744603ffe57d69bf755d92fbde76191d150a (master)
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:01:23 2024 +0900
add: playlist.txt
master
의 HEAD와 bugfix
의 HEAD가 다르다는 것을 볼 수 있다. 이제 master
에서 bugfix
의 변동 사항을 반영해보도록 하자.
git switch master
git merge bugfix
Updating 5e0b744..b0ca514
Fast-forward
playlist.txt | 1 +
1 file changed, 1 insertion(+)
Fast-forward
가 나오는 것을 볼 수 있다. git log를 통해서 확인해보도록 하자.
git log
commit b0ca514a88a87c85100c3e4fa6f78fd0d2131f27 (HEAD -> master, bugfix)
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:03:03 2024 +0900
update playlist.txt
commit 5e0b744603ffe57d69bf755d92fbde76191d150a
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:01:23 2024 +0900
add: playlist.txt
성공적으로 merge된 것을 볼 수 있다. 이렇게 성공적으로 merge된 이유는 fast-forward 자체가 굉장히 쉬운 merge이기 때문이다. 즉, 기존 code에 대한 conflict가 없기 때문이다.
세상 모든 merge가 fast-forward처럼 단순하지 않다. 이번에는 다음과 같은 경우를 생각해보도록 하자.
[Master] <- HEAD
(987fac...) --> (236ff...) --> (92faa...)
|
|
(92faa...) --> (2456...)
[Bugfix] <- HEAD
다음과 같이 236ff...
commit 이후로 master branch와 bugfix branch가 분기되었다고 하자. 어떻게 이들을 merge시킬 수 있을까??
사실 이 경우 두 branch가 분기되어 충돌이 발생했거나, 안했거나를 생각할 수 있다. 먼저 충돌이 발생하지 않은 경우를 생각해보도록 하자.
이 경우 새로운 commit을 생성하는데, 이를 병합 commit이라고 한다.
[Master] <- HEAD
(987fac...) --> (236ff...) --> (92faa...) --> (NEW COMMIT)
|
|
(92faa...) --> (2456...)
[Bugfix] <- HEAD
다음과 같이 새로운 commit을 만드는데 이를 병합 commit이라고 한다. 이 병합 commit을 분기된 branch인 bugfix
와 연결하면 된다.
[Master] <- HEAD
(987fac...) --> (236ff...) --> (92faa...) --> (NEW COMMIT)
| |
| |
(92faa...) --> (2456...)--------------
[Bugfix] <- HEAD
이렇게 merge하면 성공이다.
test하기 위해서 test.txt
를 만들자.
touch ./test.txt
다음으로 out
branch를 만들고 test.txt
를 수정해보도록 하자.
git switch -c out
echo "test opt" >> ./test.txt
git add ./test.txt
git commit -m "update test.txt"
master branch로 돌아가서, playlist.txt
를 수정해보도록 하자.
git switch master
echo "playlist3" >> ./playlist.txt
git add .
it commit -m "update playlist.txt"
이제 master branch와 out branch를 merge하도록 하자.
git merge out
...
Merge branch 'out'
# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit
위와 같이 merge commit에 대한 message를 쓰라고 나올 것이다. merge해주면 다음과 같은 결과가 나온다.
Merge made by the 'recursive' strategy.
test.txt | 1 +
1 file changed, 1 insertion(+)
create mode 100644 test.txt
이제 git log
를 확인해보면 다음과 같다.
(HEAD -> master)
Merge: 2d27a7c ca17051
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:33:40 2024 +0900
Merge branch 'out'
commit 2d27a7c1fbf6ea03626a6f1d676cee4feaf0ccaf
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:32:43 2024 +0900
update playlist.txt
commit ca17051e828837dd6b89e66e8390754be48a9090 (out)
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:29:24 2024 +0900
update test.txt
merge에 성공한 것이다. 이제 merge 도중에 충돌이 발생한 경우를 확인해보도록 하자.
conflict가 발생하는 경우는 대부분 하나의 file을 여러 branch가 수정하는 경우에 발생한다. 이 경우 직접 merge conflict를 해결해야한다.
conflict가 발생한 부분을 보면 다음과 같이 표시될 것이다.
<<<<<<< HEAD
I have 2 cats
I also have chickens
=======
I used to have a dog
>>>>>>> bug-fix
HEAD
부분이 현재 branch에 대한 내용이고, =======
아래에서 bug-fix
까지가 merge하려는 branch의 부분이다. 이 둘 중에 어느 것을 쓸 것이며, 어떻게 합칠 것인지 스스로 결정하면 된다.
먼저 새로운 branch인 conflict
를 만들고, playlist.txt
를 다음과 같이 수정하도록 하자.
git switch -c conflict
echo "playlist conflict" >> ./playlist.txt
git add ./playlist.txt
git commit -m "Overwrire playlist.txt"
다음으로 master
branch로 돌아와서 playlist.txt
를 다음과 같이 수정해주도록 하자.
git switch master
echo "master playlist" > ./playlist.txt
git add ./playlist.txt
git commit -m "Overwrite playlist.txt"
이제 이 둘을 master branch에서 conflict branch의 내용을 merge하도록 하자.
git merge conflict
Auto-merging playlist.txt
CONFLICT (content): Merge conflict in playlist.txt
Automatic merge failed; fix conflicts and then commit the result.
playlist.txt
에 CONFLICT
가 발생했다는 것을 알 수 있다.
<<<<<<< HEAD
master playlist
=======
playlist
goodbye world
playlist3
playlist conflict
>>>>>>> conflict
다음과 같이 HEAD
와 conflict
가 있다. HEAD
가 우리의 원본 내용이고, =======
에서 >>>>>>>
까지가 merge하려는 branch의 내용인 것이다. 이 중에 어느 것을 어떻게 선택하고 사용할 것인지는 오로지 개발자의 몫에 달렸다. 일부만 반영할 수도 있고, 둘 다 반영할 수 있도 있다. 우리의 경우는 모두 반영하도록 하자.
master playlist
playlist
goodbye world
playlist3
playlist conflict
이 다음 merge commit을 만들어줘야 한다. 즉 working directory에 있는 merge된 playlist를 repository로 반영해야한다는 것이다.
git add ./playlist.txt
git commit -m "merge master and conflict"
[master b0c183c] merge master and conflict
git log
를 통해서 확인해보도록 하자.
git log
commit b0c183c7d04941777ff0a844d8c5d998018388fb (HEAD -> master)
Merge: 6ccaa88 028445e
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:52:13 2024 +0900
merge master and conflict
commit 6ccaa884193b3ffbc4028e895f77441150a08248
Author: calo <calo@calo.com>
Date: Wed Jul 31 19:47:40 2024 +0900
Overwrite playlist.txt
정리하자면 다음과 같다.
git merge
git commit
을 통한 merge commit 생성