Git에서 병합 충돌을 어떻게 해결합니까?
답변
시험: git mergetool
충돌이 발생할 때마다 단계별로 안내하는 GUI가 열리고 병합 방법을 선택할 수 있습니다. 때로는 나중에 약간의 편집 작업이 필요하지만 일반적으로 충분합니다. 손으로 모든 일을하는 것보다 훨씬 낫습니다.
@JoshGlover 의견에 따라 :
명령
GUI를 설치하지 않으면 반드시 GUI를 열 필요는 없습니다.
git
나를 위해 달리는 결과
mergetoolvimdiff
가 사용되었습니다. 당신은 대신를 사용하려면 다음 도구 중 하나를 설치할 수 있습니다 :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
병합이 확실하지 않은 경우 강제로 병합하지 마십시오.
특히 충돌하는 파일이 많고 충돌 마커가 수백 줄을 포함하는 경우 병합이 압도적으로 느껴질 수 있습니다. 종종 소프트웨어 프로젝트를 평가할 때 심하게 병합을 처리하는 등의 오버 헤드 항목에 충분한 시간을 포함하지 않기 때문에 각 충돌을 해체하는 데 몇 시간을 소비해야하는 실제 드래그처럼 느껴집니다.
장기적으로 미리 계획하고 다른 사람들이 무엇을하고 있는지 알고있는 것은 머지 충돌을 예상하고 더 짧은 시간 내에 올바르게 해결할 수 있도록 준비하는 가장 좋은 도구입니다.
답변
-
충돌하는 파일을 식별하십시오 (Git에서 알려야합니다).
-
각 파일을 열고 diff를 검사하십시오. 힘내는 그들을 구분합니다. 바라건대 각 블록의 버전을 유지하는 것이 분명 할 것입니다. 코드를 커밋 한 동료 개발자와 논의해야 할 수도 있습니다.
-
당신은 파일의 충돌을 해결하면
git add the_file
. -
모든 충돌을 해결 한 후
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
충돌 상태가 될 때 수행 할 간단한 단계는 다음과 같습니다.
- 충돌하는 파일 목록은 다음과 같습니다
git status
(Unmerged paths
섹션 아래 ). -
다음 방법 중 하나를 사용하여 각 파일의 충돌을 개별적으로 해결하십시오.
-
GUI를 사용하여 충돌을 해결하십시오 :
git mergetool
(가장 쉬운 방법). -
원격 / 기타 버전을 승인하려면 다음을 사용하십시오
git checkout --theirs path/file
.. 해당 파일에 대한 로컬 변경 사항이 거부됩니다. -
로컬 / 당사 버전을 수락하려면 다음을 사용하십시오.
git checkout --ours path/file
그러나 어떤 이유로 인해 충돌하는 원격 변경이 수행되었으므로주의해야합니다.
-
충돌 한 파일을 수동으로 편집하고
<<<<<
/ 사이의 코드 블록을>>>>>
찾은 다음 위 또는 아래에서 버전을 선택하십시오=====
. 충돌이 표시되는 방법을 참조하십시오 . -
경로와 파일 이름 충돌에 의해 해결 될 수있다
git add
/git rm
.
-
-
마지막으로 다음을 사용하여 커밋 할 준비가 된 파일을 검토하십시오
git status
.아래에 여전히 파일이
Unmerged paths
있고 수동으로 충돌을 해결 한 경우 Git에 다음을 통해 해결했음을 알립니다git add path/file
. -
모든 충돌이 성공적으로 해결되면 다음을 수행하여 변경 사항을 커밋하고
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 "$@"
그런 다음 다음 단축키를 사용할 수 있습니다.
- ⌘– Alt– Up/ Down이전 / 다음 변화로 이동합니다.
- ⌘– Alt– Left/ 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
병합을 완료합니다.