Git에서 병합 충돌을 해결하는 방법 충돌을 어떻게 해결합니까?

Git에서 병합 충돌을 어떻게 해결합니까?



답변

시험: git mergetool

충돌이 발생할 때마다 단계별로 안내하는 GUI가 열리고 병합 방법을 선택할 수 있습니다. 때로는 나중에 약간의 편집 작업이 필요하지만 일반적으로 충분합니다. 손으로 모든 일을하는 것보다 훨씬 낫습니다.

@JoshGlover 의견에 따라 :

명령

GUI를 설치하지 않으면 반드시 GUI를 열 필요는 없습니다. git
mergetool
나를 위해 달리는 결과 vimdiff가 사용되었습니다. 당신은 대신를 사용하려면 다음 도구 중 하나를 설치할 수 있습니다 : meld, opendiff,
kdiff3, tkdiff, xxdiff, tortoisemerge, gvimdiff, diffuse,
ecmerge, p4merge, araxis, vimdiff, emerge.

다음은 vimdiff병합 충돌을 해결하는 데 사용되는 샘플 절차 입니다. 이 링크를 기반으로

1 단계 : 터미널에서 다음 명령 실행

git config merge.tool vimdiff
git config merge.conflictstyle diff3
git config mergetool.prompt false

이렇게하면 vimdiff가 기본 병합 도구로 설정됩니다.

2 단계 : 터미널에서 다음 명령 실행

git mergetool

3 단계 : 다음 형식의 vimdiff 디스플레이가 표시됩니다

  ╔═══════╦══════╦════════╗
  ║       ║      ║        ║
  ║ LOCAL ║ BASE ║ REMOTE ║
  ║       ║      ║        ║
  ╠═══════╩══════╩════════╣
  ║                       ║
  ║        MERGED         ║
  ║                       ║
  ╚═══════════════════════╝

이 4 가지 견해는

LOCAL – 현재 지점의 파일입니다.

BASE – 공통 조상, 파일이 두 변경 전에 어떻게 보였는가

REMOTE – 브랜치에 병합 할 파일

MERGED – 병합 결과, 이것이 repo에 저장되는 것입니다

ctrl+를 사용하여 이러한보기를 탐색 할 수 있습니다 w. 직접 사용하여 병합 뷰에 도달 할 수 있습니다 ctrl+ w다음에 j.

여기여기 에 vimdiff 탐색에 대한 추가 정보

4 단계 . 다음과 같은 방법으로 MERGED보기를 편집 할 수 있습니다

REMOTE에서 변경 사항을 받으려면

:diffg RE

BASE에서 변경 사항을 가져 오려면

:diffg BA

LOCAL에서 변경 사항을 받으려면

:diffg LO

5 단계 . 저장, 종료, 커밋 및 정리

:wqa vi에서 저장하고 종료

git commit -m "message"

git clean diff 도구로 만든 추가 파일 (예 : * .orig)을 제거하십시오.


답변

다음은 가능한 유스 케이스입니다.

몇 가지 변경 사항을 가져와야하지만 죄송합니다.

git fetch origin
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Updating a030c3a..ee25213
error: Entry 'filename.c' not uptodate. Cannot merge.

따라서 최신 정보를 얻고 다시 시도하지만 충돌이 있습니다.

git add filename.c
git commit -m "made some wild and crazy changes"
git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Auto-merging filename.c
CONFLICT (content): Merge conflict in filename.c
Automatic merge failed; fix conflicts and then commit the result.

따라서 변경 사항을 살펴보기로 결정합니다.

git mergetool

오 마이, 오 마이, 업스트림은 몇 가지 사항을 변경했지만 내 변경 사항을 사용하려면

git checkout --ours filename.c
git checkout --theirs filename.c
git add filename.c
git commit -m "using theirs"

그리고 마지막으로 시도합니다

git pull origin master

From ssh://gitosis@example.com:22/projectname
 * branch            master     -> FETCH_HEAD
Already up-to-date.

타다!


답변

병합 도구를 사용하면 충돌이나 해결 방법을 이해하는 데 거의 도움이되지 않습니다. 나는 일반적으로 텍스트 편집기에서 충돌 마커를보고 git log를 보충으로 사용하는 것이 더 성공적입니다.

다음은 몇 가지 팁입니다.

팁 하나

내가 찾은 가장 좋은 것은 “diff3″병합 충돌 스타일을 사용하는 것입니다.

git config merge.conflictstyle diff3

다음과 같은 충돌 마커가 생성됩니다.

<<<<<<<
Changes made on the branch that is being merged into. In most cases,
this is the branch that I have currently checked out (i.e. HEAD).
|||||||
The common ancestor version.
=======
Changes made on the branch that is being merged in. This is often a
feature/topic branch.
>>>>>>>

중간 부분은 공통 조상의 모습입니다. 이것은 각 브랜치에서 변경된 사항을 더 잘 이해할 수 있도록 상위 및 하위 버전과 비교할 수 있기 때문에 유용합니다. 그러면 각 변경의 목적이 무엇인지 더 잘 알 수 있습니다.

갈등이 몇 줄에 불과한 경우 일반적으로 갈등이 매우 분명합니다. (충돌을 해결하는 방법을 아는 것은 매우 다릅니다. 다른 사람들이 무엇을하고 있는지 알고 있어야합니다. 혼란 스러우면 상대방을 방으로 불러서 자신이보고있는 것을 볼 수 있도록하는 것이 가장 좋습니다 에서.)

충돌이 더 길면 세 섹션을 각각 잘라내어 “mine”, “common”및 “thes”와 같은 세 개의 별도 파일로 붙여 넣습니다.

그런 다음 다음 명령을 실행하여 충돌을 일으킨 두 개의 diff hunk를 볼 수 있습니다.

diff common mine
diff common theirs

병합 도구는 충돌하지 않는 모든 diff hunk도 포함하므로 병합 도구를 사용하는 것과는 다릅니다. 주의가 산만 해지는 것을 알았습니다.

팁 2

누군가 이미 이것을 언급했지만 각 diff hunk의 의도를 이해하면 일반적으로 충돌이 발생한 위치와 처리 방법을 이해하는 데 매우 도움이됩니다.

git log --merge -p <name of file>

이것은 공통 조상과 병합하는 두 헤드 사이에서 해당 파일을 터치 한 모든 커밋을 표시합니다. (따라서 병합하기 전에 두 브랜치에 이미 존재하는 커밋은 포함되지 않습니다.) 이렇게하면 현재 충돌에 영향을 미치지 않는 다른 덩어리를 무시할 수 있습니다.

팁 3

자동화 된 도구로 변경 사항을 확인하십시오.

자동화 된 테스트가있는 경우 테스트를 실행하십시오. 보풀 이 있으면 실행하십시오. 빌드 가능한 프로젝트 인 경우 커밋하기 전에 빌드하십시오. 모든 경우에 변경 사항이 적용되지 않는지 확인하기 위해 약간의 테스트를 수행해야합니다. (충돌없이 병합하더라도 작업 코드가 손상 될 수 있습니다.)

팁 4

미리 계획하십시오. 동료들과 의사 소통합니다.

미리 계획하고 다른 사람들이 무엇을하고 있는지 알면 병합 충돌을 방지하고 더 일찍 해결하는 데 도움이 될 수 있습니다.

예를 들어, 귀하와 다른 사람이 모두 동일한 파일 세트에 영향을 줄 수있는 다른 리팩토링 작업을하고 있다는 것을 알고 있다면, 미리 서로 대화하고 각각의 변경 유형에 대해 더 잘 이해해야합니다. 만들기. 계획된 변경을 병렬로 수행하지 않고 순차적으로 수행하면 상당한 시간과 노력을 절약 할 수 있습니다.

많은 양의 코드를 처리하는 주요 리팩토링의 경우 직렬 작업을 강력히 고려해야합니다. 한 사람이 전체 리팩토링을 수행하는 동안 모든 사람이 해당 코드 영역에서 작업을 중지합니다.

시간 압력으로 인해 연속적으로 작업 할 수없는 경우 예상되는 병합 충돌에 대해 통신하면 최소한 세부 사항을 계속 염두에두고 문제를 더 빨리 해결하는 데 도움이됩니다. 예를 들어, 1 주일 동안 동료가 중단적인 일련의 커밋을 수행하는 경우 해당 주 동안 매일 1 ~ 2 회 해당 동료 지점을 병합 / 리베이스하도록 선택할 수 있습니다. 이렇게하면 병합 / 리베이스 충돌이 발견되면 몇 주 동안 기다렸다가 한 번에 모든 것을 병합하는 것보다 더 빨리 해결할 수 있습니다.

팁 5

병합이 확실하지 않은 경우 강제로 병합하지 마십시오.

특히 충돌하는 파일이 많고 충돌 마커가 수백 줄을 포함하는 경우 병합이 압도적으로 느껴질 수 있습니다. 종종 소프트웨어 프로젝트를 평가할 때 심하게 병합을 처리하는 등의 오버 헤드 항목에 충분한 시간을 포함하지 않기 때문에 각 충돌을 해체하는 데 몇 시간을 소비해야하는 실제 드래그처럼 느껴집니다.

장기적으로 미리 계획하고 다른 사람들이 무엇을하고 있는지 알고있는 것은 머지 충돌을 예상하고 더 짧은 시간 내에 올바르게 해결할 수 있도록 준비하는 가장 좋은 도구입니다.


답변

  1. 충돌하는 파일을 식별하십시오 (Git에서 알려야합니다).

  2. 각 파일을 열고 diff를 검사하십시오. 힘내는 그들을 구분합니다. 바라건대 각 블록의 버전을 유지하는 것이 분명 할 것입니다. 코드를 커밋 한 동료 개발자와 논의해야 할 수도 있습니다.

  3. 당신은 파일의 충돌을 해결하면 git add the_file.

  4. 모든 충돌을 해결 한 후 git rebase --continue또는 Git이 완료했을 때 수행 한 명령을 수행하십시오.


답변

스택 오버플로 질문에서 답변을 확인하십시오 .Git에서 병합 중단 , 특히 Charles Bailey의 답변 은 문제가있는 다른 버전의 파일을 보는 방법을 보여줍니다.

# Common base version of the file.
git show :1:some_file.cpp

# 'Ours' version of the file.
git show :2:some_file.cpp

# 'Theirs' version of the file.
git show :3:some_file.cpp

답변

파일을 동시에 변경하면 병합 충돌이 발생합니다. 해결 방법은 다음과 같습니다.

git CLI

충돌 상태가 될 때 수행 할 간단한 단계는 다음과 같습니다.

  1. 충돌하는 파일 목록은 다음과 같습니다 git status( Unmerged paths섹션 아래 ).
  2. 다음 방법 중 하나를 사용하여 각 파일의 충돌을 개별적으로 해결하십시오.

    • GUI를 사용하여 충돌을 해결하십시오 : git mergetool(가장 쉬운 방법).

    • 원격 / 기타 버전을 승인하려면 다음을 사용하십시오 git checkout --theirs path/file.. 해당 파일에 대한 로컬 변경 사항이 거부됩니다.

    • 로컬 / 당사 버전을 수락하려면 다음을 사용하십시오. git checkout --ours path/file

      그러나 어떤 이유로 인해 충돌하는 원격 변경이 수행되었으므로주의해야합니다.

      관련 : “우리”와 자식에 “그들의”의 정확한 의미는 무엇입니까?

    • 충돌 한 파일을 수동으로 편집하고 <<<<</ 사이의 코드 블록을 >>>>>찾은 다음 위 또는 아래에서 버전을 선택하십시오 =====. 충돌이 표시되는 방법을 참조하십시오 .

    • 경로와 파일 이름 충돌에 의해 해결 될 수있다 git add/ git rm.

  3. 마지막으로 다음을 사용하여 커밋 할 준비가 된 파일을 검토하십시오 git status.

    아래에 여전히 파일이 Unmerged paths있고 수동으로 충돌을 해결 한 경우 Git에 다음을 통해 해결했음을 알립니다 git add path/file.

  4. 모든 충돌이 성공적으로 해결되면 다음을 수행하여 변경 사항을 커밋하고 git commit -a평소처럼 원격으로 푸시하십시오.

참조 : GitHub 의 명령 줄 에서 병합 충돌 해결

실용적인 자습서를 보려면 Katacoda의 시나리오 5-수정 병합 충돌을 확인하십시오 .

DiffMerge

Windows, macOS 및 Linux / Unix에서 파일을 시각적으로 비교하고 병합 할 수있는 DiffMerge 를 성공적으로 사용했습니다 .

3 개의 파일 간 변경 사항을 그래픽으로 표시 할 수 있으며 자동 병합 (안전한 경우)하고 결과 파일 편집을 완벽하게 제어 할 수 있습니다.

이미지 출처 : DiffMerge (Linux 스크린 샷)

간단히 다운로드하여 repo에서 다음과 같이 실행하십시오.

git mergetool -t diffmerge .

맥 OS

macOS에서는 다음을 통해 설치할 수 있습니다.

brew install caskroom/cask/brew-cask
brew cask install diffmerge

그리고 아마도 (제공되지 않은 경우) PATH에 다음과 같은 추가 간단한 래퍼가 있어야합니다 (예 🙂 /usr/bin.

#!/bin/sh
DIFFMERGE_PATH=/Applications/DiffMerge.app
DIFFMERGE_EXE=${DIFFMERGE_PATH}/Contents/MacOS/DiffMerge
exec ${DIFFMERGE_EXE} --nosplash "$@"

그런 다음 다음 단축키를 사용할 수 있습니다.

  • AltUp/ Down이전 / 다음 변화로 이동합니다.
  • AltLeft/ Right왼쪽 또는 오른쪽에서 변경 내용을 적용합니다

또는 opendiff (Xcode Tools의 일부)를 사용하여 두 파일 또는 디렉토리를 병합하여 세 번째 파일 또는 디렉토리를 만들 수 있습니다.


답변

자주 작은 커밋을 수행하는 경우로 커밋 주석을 살펴보십시오 git log --merge. 그런 다음 git diff갈등을 보여줄 것입니다.

몇 줄 이상이 관련된 충돌의 경우 외부 GUI 도구에서 진행중인 작업을보다 쉽게 ​​확인할 수 있습니다. 나는 opendiff를 좋아한다-Git은 vimdiff, gvimdiff, kdiff3, tkdiff, meld, xxdiff를 지원하며 다른 git config merge.tool "your.tool"도구를 설치할 수 있으며 다른 도구를 설치할 수 있습니다 git mergetool.

충돌을 해결하기 위해 파일을 편집 할 때마다 git add filename색인이 업데이트되고 diff는 더 이상 표시하지 않습니다. 모든 갈등의 처리와 그 파일이되었을 때 git add-ed, git commit병합을 완료합니다.