본문 바로가기
기타/Git

[Git] Conflict 기초

by 코딩하는 랄로 2024. 1. 8.
728x90

Conflict

처음 branch를 다루고 merge를 하다보면, conflict 오류가 발생하면서 merge 가 실패했다는 메세지를 자주 접하게 된다. fast forward 방식보다 3-way merge 방식에서 conflict가 발생하는데 그 이유는 2개의 branch에서 같은 파일의 똑같은 부분을 동시에 수정하고 merge를 시도하였기 때문이다.

 

Git은 이러한 경우의 merge 하지 못하고 아래와 같은 conflict 메시지를 출력한다.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git branch ralro

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ echo "master branch" > file1.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git commit -am "modified file1"
warning: in the working copy of 'file1.txt', LF will be replaced by CRLF the next time Git touches it
[master ca0873f] modified file1
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git checkout ralro
Switched to branch 'ralro'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (ralro)
$ echo "ralro branch" > file1.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (ralro)
$ git commit -am "modified file1"
warning: in the working copy of 'file1.txt', LF will be replaced by CRLF the next time Git touches it
[ralro f2709be] modified file1
 1 file changed, 1 insertion(+), 1 deletion(-)

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (ralro)
$ git checkout master
Switched to branch 'master'

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git merge ralro
Auto-merging file1.txt
CONFLICT (content): Merge conflict in file1.txt
Automatic merge failed; fix conflicts and then commit the result.

 

ralro branch를 생성하고 master와 ralro branch 모두 file1.txt의 내용을 변경해주었다. 이 때 echo를 이용해서 새로운 내용을로 덮어씌워주었기 때문에 두 branch 모두 file1.txt의 첫번째 줄을 변경해주게 되고 commit 시에 이러한 변경사항을 띄우는 것 또한 확인할 수 있다.

 

이 상황에서 merge를 진행하니 file1.txt에서 conflict가 발생했고 이로 인해 auto-merging이 실패했다는 메세지를 띄운 후 conflict를 고치고 다시 커밋을 하라는 메세지 또한 볼 수 있다. conflict를 해결하지 않으면 merge는 진행할 수 없기 때문에 이를 빨리 해결해보자.

 

먼저, conflict가 발생한 후에 git status 명렁어를 사용하면 어떤 파일을 merge할 수 없는지를 확인할 수 있다.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master|MERGING)
$ git status
On branch master
You have unmerged paths.
  (fix conflicts and run "git commit")
  (use "git merge --abort" to abort the merge)

Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   file1.txt

no changes added to commit (use "git add" and/or "git commit -a")

 

git status 명렁어를 입력해보니, 위와 같이 conflict가 일어난 파일을 unmerged 상태로 표시하여 준다. 이제 conflict 난 파일을 수동으로 수정을 해주어야 하는데 vim 편집기를 이용하여 파일을 열어보면 아래와 같이 conflict 난 부분을 git 이 표시해준다.

<<<<<<< HEAD
master branch
=======
ralro branch
>>>>>>> ralro

 

======= 위쪽의 내용은 HEAD branch의 내용이고 ( merge 했을 당시 기준 ) 아래쪽은 HEAD branch에 merge 하려고 했던 branch의 내용이다. 이번 예제에서는 HEAD는 master이고 상대 branch는 ralro branch 인 것이다.

 

현재 상태에서 conflict를 해결하기 위해서는 위쪽 또는 아래쪽 내용 중 하나를 고르거나 또는 새로 작성하여 충돌이 일어나지 않게끔 merge 하여야 한다. 이번 글에서는 ralro branch를 한 줄 아래로 내려서 두개의 branch에서 작성한 내용 모두 merge하였을 때 file1.txt 에 담기게 해보겠다.

master branch
ralro branch

 

<<<, ===, >>> 에 해당하는 행을 모두 삭제해주고 저장해주었다. 이제 다시 git add 명렁어로 git 에 저장하고 git status를 출력해보면,

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master|MERGING)
$ git add file1.txt

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master|MERGING)
$ git status
On branch master
All conflicts fixed but you are still merging.
  (use "git commit" to conclude merge)

Changes to be committed:
        modified:   file1.txt

 

모든 conflict가 고쳐졌고 아직 merging이 끝난것이 아닌 진행중이고 merge를 마무리하기 위해서는 git commit을 하라는 메세지를 보여준다.

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master|MERGING)
$ git commit -m "success merge"
[master 8dc2453] success merge

user@DESKTOP-UCJOAKJ MINGW64 /d/git/example (master)
$ git log --format=oneline --graph
*   8dc2453a69b8dc6bc03e48ae0a23c72e6d35b591 (HEAD -> master) success merge
|\
| * f2709be39ebb28b2d2f05b2f28f7671c79f943a8 (ralro) modified file1
* | ca0873fdbd9968bd7dd8201f2a284a5be7fe2d2a modified file1
|/
*   ec6a6685ee40ed3081ebec88b9fb3fbb324363a0 Merge branch 'iss53'

 

여기서 중요한 점은, conflict를 해결하고 난 후에 진행하는 add와 merge는 merge된 파일을 대상으로 한다는 점이다. 지금 작업하는 branch의 파일을 수정한 뒤, staging area에 올리고 하는 것이 아니라 merge 시에 conflict 난 파일을 merge를 진행하였을 때 어떻게 파일을 생성하게 할 지를 수동으로 작성하고 해당 파일을 staging area에 올리고 merge commit을 진행한 것이다.

 

위에서 살펴본 방식으로 직접 conflict 된 파일을 수정해도 되지만, 또 다른 merge 도구로도 conflict를 해결할 수 있다. 이를 사용하기 위해서는 git mergetool 명렁을 실행하면 된다. 

$ git mergetool
This message is displayed because 'merge.tool' is not configured.
See 'git mergetool --tool-help' or 'git help config' for more details.
'git mergetool' will now attempt to use one of the following tools:
opendiff kdiff3 tkdiff xxdiff meld tortoisemerge gvimdiff diffuse
diffmerge ecmerge p4merge araxis bc3 codecompare vimdiff emerge
Merging:
index.html
Normal merge conflict for 'index.html':
  {local}: modified file
  {remote}: modified file
Hit return to start merge resolution tool (opendiff):

 

이를 사용하면 one of the following tools : 뒤에 명시도니 tool 들 중 하나를 선택하여 merge를 진행할 수 있다. ( mac에선 opendiff 가 실행됨 ) mergetool을 종료하면 git은 merge를 잘 했는지 물어본 뒤, 잘 끝냈다고 하면 자동으로 git add가 실행되어 해당 파일을 staging area에 올리게 된다. 이후 수동으로 merge commit을 진행하면 merge가 끝나게 된다.

 

 

 

 

reference : pro git

728x90

'기타 > Git' 카테고리의 다른 글

[Git] branch workflow  (0) 2024.01.09
[Git] branch 관리  (1) 2024.01.09
[Git] Merge 기초  (0) 2024.01.04
[Git] checkout  (1) 2024.01.03
[Git] branch 생성  (1) 2024.01.02