Git에서 충돌을 이해하고 해결하는 방법

모든 개발자가보기 싫어하는 단어는 바로 갈등입니다. ? Git (또는 다른 버전 제어 시스템)으로 작업 할 때 가끔 발생하는 병합 충돌을 피할 방법이 없습니다.

하지만 개발자와 이야기 할 때 병합 충돌이라는 주제에 대해 불안감 이나 불편 함 이 있다는 말을 자주 듣습니다 .

갈등을 처리하는 것은 종종 어둡고 신비한 곳으로 남아 있습니다. 상황이 심하게 망가졌고 상황을 악화시키지 않고 벗어나는 방법이 불분명 한 상황입니다.

병합 충돌이 개발자의 삶에서 피할 수없는 부분이라는 것은 사실이지만 이러한 상황에서의 불편 함은 완전히 선택 사항입니다.

이 기사의 의도는이 주제를 명확하게하는 것입니다. 충돌이 일반적으로 발생하는 방법과시기, 실제로 발생하는 내용, 해결 방법 또는 실행 취소 방법입니다.

이러한 사항을 제대로 이해하면 훨씬 더 편안하고 자신있게 병합 충돌을 처리 할 수 ​​있습니다. ?

충돌이 발생하는 방법과시기

이름은 이미 다음과 같이 말합니다. "병합 충돌"은 다른 소스의 커밋을 통합하는 과정에서 발생할 수 있습니다.

그러나 "통합"은 "분기 병합"에만 국한되지 않습니다. 리베이스 또는 인터랙티브 리베이스, 체리 픽 또는 풀을 수행 할 때 또는 Stash를 다시 적용 할 때도 발생할 수 있습니다.

이러한 모든 작업은 일종의 통합을 수행하며 병합 충돌이 발생할 수 있습니다.

그러나 물론 이러한 작업이 매번 병합 충돌을 일으키는 것은 아닙니다 (신께 감사드립니다!). 이상적으로는 이러한 상황에 처한 경우는 거의 없습니다. 그러나 정확히 언제 충돌이 발생합니까?

실제로 Git의 병합 기능은 가장 큰 장점 중 하나입니다. Git은 일반적으로 자체적으로 문제를 파악할 수 있기 때문에 브랜치 병합은 대부분의 경우 쉽게 작동합니다.

그러나 모순적인 변화 가 일어나고 기술이 옳고 그름을 결정할 수없는 상황이 있습니다 . 이러한 상황은 단순히 인간의 결정을 요구합니다.

진정한 고전은 두 개의 다른 브랜치에서 두 개의 커밋에서 똑같은 코드 줄 이 변경 되었을 때 입니다. Git은 당신이 선호하는 변화를 알 수있는 방법이 없습니다! ?

다른 유사한 상황이 있습니다. 예를 들어 파일이 한 브랜치에서 수정 되고 다른 브랜치에서 삭제 된 경우가 있습니다.하지만 덜 일반적입니다.

"타워"망할 놈의 바탕 화면 GUI는 , 예를 들어, 이런 상황을 시각화의 좋은 방법이 있습니다 :

충돌이 발생한시기를 아는 방법

걱정하지 마십시오. Git은 충돌이 발생했을 때 매우 명확하게 알려줍니다. ?  

첫째, 충돌로 인해 병합 또는 리베이스가 실패 하는 경우와 같은 상황에서 즉시 알려줍니다 .

$ git merge develop Auto-merging index.html CONFLICT (content): Merge conflict in index.html CONFLICT (modify/delete): error.html deleted in HEAD and modified in develop. Version develop of error.html left in tree. Automatic merge failed; fix conflicts and then commit the result.

위의 예에서 볼 수 있듯이 병합을 수행하려고 할 때 병합 충돌이 발생했으며 Git은 문제를 매우 명확하고 신속하게 전달합니다.

  • "index.html"파일에서 충돌이 발생했습니다.
  • "error.html"파일에서 또 다른 충돌이 발생했습니다.
  • 마지막으로 충돌로 인해 병합 작업이 실패했습니다.

이것이 우리가 코드를 파헤쳐 서 무엇을해야하는지 확인해야하는 상황입니다.

충돌이 발생했을 때 이러한 경고 메시지를 간과 한 경우, Git은 다음을 실행할 때마다 추가로 알려줍니다 git status.

$ git status On branch main You have unmerged paths. (fix conflicts and run "git commit") (use "git merge --abort" to abort the merge) Unmerged paths: (use "git add/rm ..." as appropriate to mark resolution) deleted by us: error.html both modified: index.html

즉, 병합 충돌을 알아 차리지 않도록 걱정하지 마십시오 . Git은 당신이 그들을 간과 할 수 없도록합니다.

Git에서 충돌을 취소하고 다시 시작하는 방법

병합 충돌은 특정 긴급한 분위기와 함께 발생합니다. 그리고 당연히 그렇습니다. 작업을 계속하려면 먼저 처리해야합니다.

그러나이를 무시하는 것은 선택 사항이 아니지만 "병합 충돌 처리"가 반드시 해결해야한다는 의미는 아닙니다. 실행 취소 도 가능합니다!

반복 할 가치가 있습니다. 항상 병합 충돌을 취소하고 이전 상태로 돌아갈 수있는 옵션이 있습니다. 충돌하는 파일을 이미 해결하기 시작했고 막 다른 골목에있는 경우에도 마찬가지입니다.

이러한 상황에서는 충돌이 발생하기 전에 항상 다시 시작하여 깨끗한 상태로 돌아갈 수 있다는 점을 명심하는 것이 좋습니다.

이를 위해, 대부분의 명령은 함께 --abort예를 들어, 옵션 git merge --abortgit rebase --abort:

$ git merge --abort $ git status On branch main nothing to commit, working tree clean

이것은 당신이 정말로 엉망이 될 수 없다는 자신감을 줄 것 입니다. 언제든지 중단하고 깨끗한 상태로 돌아간 다음 다시 시작할 수 있습니다.

Git에서 충돌이 실제로 어떻게 보이는지

이제 아무것도 깨질 수 없다는 것을 알고 안전하게 충돌이 실제로 어떻게 보이는지 보자 . 이것은 그 작은 벌레를 이해하는 동시에 그들에 대한 존경심을 잃고 자신에 대한 자신감을 얻는 데 도움이 될 것입니다.

예를 들어, 편집기에서 (현재 충돌하는) "index.html"파일의 내용을 살펴 보겠습니다.

Git was kind enough to mark the problem area in the file, enclosing it in <<<<<<< HEAD and >>>>>>> [other/branch/name]. The content that comes after the first marker originates from our current working branch. Finally, a line with ======= characters separates the two conflicting changes.

How to Solve a Conflict in Git

Our job as developers now is to clean up these lines: after we're finished, the file has to look exactly as we want it to look.

It might be necessary to talk to the teammate who wrote the "other" changes and decide which code is actually correct. Maybe it's ours, maybe it's theirs - or maybe a mixture between the two.

This process - cleaning up the file and making sure it contains what we actually want - doesn't have to involve any magic. You can do this simply by opening your text editor or IDE and starting to making your changes.

Often, however, you'll find that this is not the most efficient way. That's when dedicated tools can save time and effort:

  • Git GUI Tools: Some of the graphical user interfaces for Git can be helpful when solving conflicts. The Tower Git GUI, for example, offers a dedicated "Conflict Wizard" that helps visualize and solve the situation:
  • Dedicated Merge Tools: For more complicated conflicts, it can be great to have a dedicated "Diff & Merge Tool" at hand. You can configure your tool of choice using the "git config" command. (Consult your tool's documentation for detailed instructions.) Then, in case of a conflict, you can invoke it by simply typing git mergetool. As an example, here's a screenshot of "Kaleidoscope" on macOS:

After cleaning up the file - either manually or in a Git GUI or Merge Tool - we have to commit this like any other change:

  • By using git add on the (previously) conflicted file, we inform Git that the conflict has been solved.
  • When all conflicts have been solved and added to the Staging Area, you need to complete the resolution by creating a regular commit.

How to Become More Confident and Productive

Many years ago, when I started using version control, merge conflicts regularly freaked me out: I was afraid that, finally, I had managed to break things for good. ?

Only when I took the time to truly understand what was going on under the hood was I able to deal with conflicts confidently and efficiently.

The same was true, for example, when dealing with mistakes: only once I learned how to undo mistakes with Git was I able to become more confident and productive in my work.

I highly recommend taking a look at the free "First Aid Kit for Git", a collection of short videos about how to undo and recover from mistakes with Git.

Have fun becoming a better programmer!

About the Author

Tobias Günther is the CEO of Tower, the popular Git desktop client that helps more than 100,000 developers around the world to be more productive with Git.