Git에서 병합 충돌을 어떻게 해결합니까?
git
설치로 즉시 작동하지 않는 명령이 언급되어 있습니다. 2017 년 현재 1.3m의 조회수와 수천 개의 투표로 SE 시작 페이지를 열었습니다. 매혹적인.
Git에서 병합 충돌을 어떻게 해결합니까?
git
설치로 즉시 작동하지 않는 명령이 언급되어 있습니다. 2017 년 현재 1.3m의 조회수와 수천 개의 투표로 SE 시작 페이지를 열었습니다. 매혹적인.
답변:
시험: 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 mergetool -y
로 한 번에 많은 파일을 병합하는 경우 몇 가지 키 입력을 저장하는 데 사용할 수 있습니다 .
git mergetool
나를 위해 달리는 결과 vimdiff
가 사용되었습니다. 다음 도구 중 하나를 설치하여 대신 사용할 수 meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis vimdiff emerge
있습니다..
git mergetool -t bc3
)를 사용할 수도 있습니다 .
다음은 가능한 유스 케이스입니다.
몇 가지 변경 사항을 가져와야하지만 죄송합니다.
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 merge --help
this question
병합 도구를 사용하면 충돌이나 해결 방법을 이해하는 데 거의 도움이되지 않습니다. 나는 일반적으로 텍스트 편집기에서 충돌 마커를보고 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도 포함하므로 병합 도구를 사용하는 것과는 다릅니다. 주의가 산만 해지는 것을 알았습니다.
누군가 이미 이것을 언급했지만 각 diff hunk의 의도를 이해하면 일반적으로 충돌이 발생한 위치와 처리 방법을 이해하는 데 매우 도움이됩니다.
git log --merge -p <name of file>
이것은 공통 조상과 병합하는 두 헤드 사이에서 해당 파일을 터치 한 모든 커밋을 표시합니다. (따라서 병합하기 전에 두 브랜치에 이미 존재하는 커밋은 포함되지 않습니다.) 이렇게하면 현재 충돌에 영향을 미치지 않는 다른 덩어리를 무시할 수 있습니다.
자동화 된 도구로 변경 사항을 확인하십시오.
자동화 된 테스트가있는 경우 테스트를 실행하십시오. 보풀 이 있으면 실행하십시오. 빌드 가능한 프로젝트 인 경우 커밋하기 전에 빌드하십시오. 모든 경우에 변경 사항이 적용되지 않는지 확인하기 위해 약간의 테스트를 수행해야합니다. (충돌없이 병합하더라도 작업 코드가 손상 될 수 있습니다.)
미리 계획하십시오. 동료들과 의사 소통합니다.
미리 계획하고 다른 사람들이 무엇을하고 있는지 알면 병합 충돌을 방지하고 더 일찍 해결하는 데 도움이 될 수 있습니다.
예를 들어, 귀하와 다른 사람이 모두 동일한 파일 세트에 영향을 줄 수있는 다른 리팩토링 작업을하고 있다는 것을 알고 있다면, 미리 서로 대화하고 각각의 변경 유형에 대해 더 잘 이해해야합니다. 만들기. 계획된 변경을 병렬로 수행하지 않고 순차적으로 수행하면 상당한 시간과 노력을 절약 할 수 있습니다.
많은 양의 코드를 처리하는 주요 리팩토링의 경우 직렬 작업을 강력히 고려해야합니다. 한 사람이 전체 리팩토링을 수행하는 동안 모든 사람이 해당 코드 영역에서 작업을 중지합니다.
시간 압력으로 인해 연속적으로 작업 할 수없는 경우 예상되는 병합 충돌에 대해 통신하면 최소한 세부 사항을 계속 염두에두고 문제를 더 빨리 해결하는 데 도움이됩니다. 예를 들어, 1 주일 동안 동료가 중단적인 일련의 커밋을 수행하는 경우 해당 주 동안 매일 1 ~ 2 회 해당 동료 지점을 병합 / 리베이스하도록 선택할 수 있습니다. 이렇게하면 병합 / 리베이스 충돌이 발견되면 몇 주 동안 기다렸다가 한 번에 모든 것을 병합하는 것보다 더 빨리 해결할 수 있습니다.
병합이 확실하지 않은 경우 강제로 병합하지 마십시오.
특히 충돌하는 파일이 많고 충돌 마커가 수백 줄을 포함하는 경우 병합이 압도적으로 느껴질 수 있습니다. 종종 소프트웨어 프로젝트를 평가할 때 심하게 병합을 처리하는 등의 오버 헤드 항목에 충분한 시간을 포함하지 않기 때문에 각 충돌을 해체하는 데 몇 시간을 소비해야하는 실제 드래그처럼 느껴집니다.
장기적으로 미리 계획하고 다른 사람들이 무엇을하고 있는지 알고있는 것은 머지 충돌을 예상하고 더 짧은 시간 내에 올바르게 해결할 수 있도록 준비하는 가장 좋은 도구입니다.
p4merge
도구이며 Perforce의 다른 도구와 별도로 설치하여 사용할 수 있음 을 보여줍니다 (사용하지 않았지만 불만이 있음).
git config merge.conflictstyle diff3
- 감사합니다. 이것은 놀랍고 좋은 3 웨이 병합 GUI를 찾고 (그리고 $$를 지불하려는) 자유롭게했습니다. IMO는 공통 조상뿐만 아니라 로컬 / 원격 을 보여주고 GUI가없는 (AFAIK) 마지막 커밋 로그 라인을 보여주기 때문에 더 좋습니다 . 커밋은 어떤 코드가 어떤 브랜치에 속하는지 식별하는 데 도움이됩니다.
충돌하는 파일을 식별하십시오 (Git에서 알려야합니다).
각 파일을 열고 diff를 검사하십시오. 힘내는 그들을 구분합니다. 바라건대 각 블록의 버전을 유지하는 것이 분명 할 것입니다. 코드를 커밋 한 동료 개발자와 논의해야 할 수도 있습니다.
당신은 파일의 충돌을 해결하면 git add the_file
.
모든 충돌을 해결 한 후 git rebase --continue
또는 Git이 완료했을 때 수행 한 명령을 수행하십시오.
git add
는 색인에서 파일을 준비합니다. 저장소에 아무것도 추가 하지 않습니다 . git commit
저장소에 항목을 추가합니다. 이 사용법은 병합에 적합합니다. 병합은 자동으로 병합 될 수있는 모든 변경 사항을 자동으로 준비합니다. 나머지 변경 사항을 병합하고 완료되면 색인에 추가해야합니다.
스택 오버플로 질문에서 답변을 확인하십시오 .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-수정 병합 충돌을 확인하십시오 .
Windows, macOS 및 Linux / Unix에서 파일을 시각적으로 비교하고 병합 할 수있는 DiffMerge 를 성공적으로 사용했습니다 .
3 개의 파일 간 변경 사항을 그래픽으로 표시 할 수 있으며 자동 병합 (안전한 경우)하고 결과 파일 편집을 완벽하게 제어 할 수 있습니다.
이미지 출처 : DiffMerge (Linux 스크린 샷)
간단히 다운로드하여 repo에서 다음과 같이 실행하십시오.
git mergetool -t diffmerge .
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 "$@"
그런 다음 다음 단축키를 사용할 수 있습니다.
또는 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
병합을 완료합니다.
병합 충돌 마커가 무엇인지 이해하려면 충돌이 표시되는 방법 또는 Git의 git merge
설명서를 참조하십시오 .
또한 충돌 해결 방법 섹션에서는 충돌을 해결 하는 방법에 대해 설명합니다.
충돌을 본 후 두 가지 작업을 수행 할 수 있습니다.
병합하지 않기로 결정하십시오. 필요한 정리는 인덱스 파일을
HEAD
커밋 으로 재설정하여 2를 반대로하고 2와 3으로 작성된 작업 트리 변경을 정리하는 것입니다.git merge --abort
이것을 위해 사용될 수 있습니다.충돌을 해결하십시오. 힘내 작업 트리에서 충돌을 표시합니다. 파일을 모양으로 편집하고 색인으로 편집하십시오
git add
.git commit
거래를 봉인하는 데 사용 합니다.여러 도구와의 충돌을 통해 작업 할 수 있습니다.
mergetool을 사용하십시오.
git mergetool
병합 과정을 안내하는 그래픽 병합 도구를 시작합니다.차이점을보세요. 와 버전의
git diff
변경 사항을 강조 표시하는 3 방향 차이를 표시 합니다.HEAD
MERGE_HEAD
각 지점의 diff를보십시오. 버전에
git log --merge -p <path>
대해 먼저 diff를 표시HEAD
한 다음MERGE_HEAD
버전을 표시합니다.원본을보십시오.
git show :1:filename
쇼 공통의 조상git show :2:filename
보여줍니다HEAD
버전 및git show :3:filename
표시MERGE_HEAD
버전을.
또한 통합 충돌 마커 및이를 해결하는 방법은 Pro Git 서적 섹션의 기본 병합 충돌 에서 읽을 수 있습니다 .
내 버전 또는 전체 버전을 원하거나 개별 변경 사항을 검토하고 각 변경 사항을 결정하려고합니다.
내 또는 그들의 버전을 완전히 수락하십시오 .
내 버전 (로컬, 로컬 버전)을 수락하십시오.
git checkout --ours -- <filename>
git add <filename> # Marks conflict as resolved
git commit -m "merged bla bla" # An "empty" commit
그들의 버전을 수락하십시오 (원격, 그들의 것) :
git checkout --theirs -- <filename>
git add <filename>
git commit -m "merged bla bla"
당신은하고 싶은 경우 모든 충돌 파일을 실행합니다 :
git merge --strategy-option ours
또는
git merge --strategy-option theirs
모든 변경 사항을 검토하고 개별적으로 승인
git mergetool
git add <filename>
git commit -m "merged bla bla"
기본값 mergetool
은 명령 행 에서 작동 합니다 . 명령 행 mergetool을 사용하는 방법은 별도의 질문이어야합니다.
이를 위해 시각적 도구 를 설치할 수도 meld
있습니다.
git mergetool -t meld
로컬 버전 (우리), "기본"또는 "병합"버전 (현재 병합 결과) 및 원격 버전 (그들의)이 열립니다. 완료되면 병합 된 버전을 저장하고 git mergetool -t meld
"파일을 병합 할 필요가 없습니다"가 표시 될 때까지 다시 실행 한 다음 3 단계 및 4 단계로 이동하십시오.
수동으로 병합 충돌을 해결하려는 Emacs 사용자의 경우 :
git diff --name-status --diff-filter=U
충돌 해결이 필요한 모든 파일을 표시합니다.
다음과 같이 각 파일을 하나씩 또는 한 번에여십시오.
emacs $(git diff --name-only --diff-filter=U)
Emacs에서 편집이 필요한 버퍼를 방문 할 때 다음을 입력하십시오.
ALT+x vc-resolve-conflicts
이렇게하면 3 개의 버퍼 (광산, 버퍼 및 출력 버퍼)가 열립니다. 'n'(다음 영역), 'p'(제공 영역)를 눌러 탐색하십시오. 'a'와 'b'를 눌러 광산 또는 해당 지역을 출력 버퍼에 각각 복사하십시오. 출력 버퍼를 직접 편집하십시오.
완료되면 : 'q'를 누르십시오. Emacs는이 버퍼를 저장할 것인지 묻습니다. 예. 버퍼를 완료 한 후 터미널에서 실행하여 해결 된 것으로 표시하십시오.
git add FILENAME
모든 버퍼 유형으로 완료되면
git commit
병합을 완료합니다.
위의 답변에서 끌어 오기 / 가져 오기 / 병합에 대해 흥미롭고 생산적인 트릭을 공유하고 싶습니다.
git pull --rebase
이 위의 명령은 내 자식 생활에서 가장 유용한 명령으로 많은 시간을 절약했습니다.
새로 커밋 된 변경 사항을 원격 서버로 푸시하기 전에 git pull --rebase
오히려 git pull
수동으로 시도 merge
하면 최신 원격 서버 변경 사항 (페치 + 병합)을 자동으로 동기화하고 로컬 최신 커밋을 git 로그의 맨 위에 놓습니다. 수동 풀 / 병합에 대해 걱정할 필요가 없습니다.
충돌이 발생할 경우
git mergetool
git add conflict_file
git rebase --continue
리포지토리 중 하나의 변경이 중요하지 않다는 것을 잘 알고 있고 다른 변경 사항을 위해 모든 변경 사항을 해결하려면 다음을 사용하십시오.
git checkout . --ours
저장소에 유리하게 변경 사항을 해결 하거나
git checkout . --theirs
다른 저장소 나 주요 저장소 를 위해 변경 사항을 해결 합니다 .
또는 GUI 병합 도구를 사용하여 파일을 하나씩 단계별로 살펴 p4merge
보거나 병합 도구라고 말 하거나 이미 설치 한 이름을 작성해야합니다.
git mergetool -t p4merge
파일을 완성한 후에는 저장하고 닫아야하므로 다음 파일이 열립니다.
Git에서 병합 충돌을 해결하려면 다음 단계를 따르십시오.
힘내 상태 확인 : 자식 상태
패치 세트 받기 : git fetch (Git 커밋에서 올바른 패치를 확인하십시오)
로컬 브랜치를 체크 아웃하십시오 (여기의 예제에서는 temp1) : git checkout -b temp1
git pull --rebase origin master 에서 최근 내용을 가져옵니다.
mergetool을 시작하고 충돌을 확인하고 수정하십시오 ... 현재 지점으로 원격 지점의 변경 사항을 확인하십시오 : git mergetool
상태를 다시 확인하십시오 : 자식 상태
mergetool에 의해 로컬로 생성 된 원하지 않는 파일을 삭제하십시오. 일반적으로 mergetool은 확장자가 * .orig 인 추가 파일을 작성합니다. 중복 된 파일이므로 해당 파일을 삭제하고 로컬에서 변경 사항을 수정하고 올바른 버전의 파일을 추가하십시오. git add #your_changed_correct_files
상태를 다시 확인하십시오 : 자식 상태
동일한 커밋 ID로 변경 사항을 커밋하십시오 (이것은 새로운 별도의 패치 세트를 피합니다) : git commit --amend
마스터 브랜치로 푸시 : git push (Git 저장소로)
3 단계가 있습니다.
명령으로 충돌을 일으키는 파일 찾기
git status
다음과 같이 충돌이있는 파일을 확인하십시오.
<<<<<<<<head
blablabla
원하는 방식으로 변경 한 다음 명령으로 커밋
git add solved_conflicts_files
git commit -m 'merge msg'
다른 방법과 같이 여러 가지 방법으로 병합 충돌을 해결할 수 있습니다.
진짜 열쇠는 로컬 및 원격 리포지토리에서 변경 사항이 어떻게 흐르는 지 아는 것입니다. 이것의 핵심은 추적 지점을 이해하는 것입니다. 나는 추적 지점이 내 로컬, 실제 파일 디렉토리와 원점으로 정의 된 원격 사이의 '중간에 누락 된 부분'으로 생각한다는 것을 알았습니다.
나는 이것을 피하기 위해 개인적으로 2 가지 습관을 들었습니다.
대신에:
git add .
git commit -m"some msg"
두 가지 단점이 있습니다-
a) 모든 새로운 / 변경된 파일이 추가되며 원치 않는 변경이 포함될 수 있습니다.
b) 먼저 파일 목록을 검토 할 수 없습니다.
대신에 나는 :
git add file,file2,file3...
git commit # Then type the files in the editor and save-quit.
이렇게하면 어떤 파일이 추가되는지 더 신중하게 알 수 있으며 메시지 편집기를 사용하는 동안 목록을 검토하고 조금 더 생각하게됩니다. -m
옵션 대신 전체 화면 편집기를 사용하면 커밋 메시지가 향상됩니다 .
[업데이트-시간이 지남에 따라 더 전환했습니다 :
git status # Make sure I know whats going on
git add .
git commit # Then use the editor
]
또한 (그리고 당신의 상황과 더 관련이 있습니다), 나는 피하려고합니다 :
git pull
또는
git pull origin master.
pull은 병합을 의미하기 때문에 로컬에서 병합하지 않으려는 변경 사항이있는 경우 병합되지 않아야하는 코드에 대해 병합 된 코드 및 / 또는 병합 충돌로 쉽게 끝날 수 있습니다.
대신 나는 노력하려고
git checkout master
git fetch
git rebase --hard origin/master # or whatever branch I want.
도움이 될 수도 있습니다.
git checkout master
하고 git fetch
와 git rebase --hard origin/master
git add .
로컬 수정 사항을 저장하여 후속 조치를 취할 수 git checkout master
있습니까? 아니면 두 가지 다른 시나리오입니까?
$ git rebase --hard origin/master b5a30cc159ba8dd error: unknown option
hard '사용법 : git rebase [-i] [옵션] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>] 또는 : git rebase [-i] [ 옵션] [--exec <cmd>] [--onto <newbase>] --root [<branch>] 또는 : git rebase --continue | -중단 | -건너 뛰기 | --edit-할 일`
CoolAJ86의 답변은 거의 모든 것을 요약합니다. 동일한 코드에서 두 가지 모두에 변경 사항이있는 경우 수동 병합을 수행해야합니다. 텍스트 편집기에서 충돌로 파일을 열면 다음 구조가 나타납니다.
(Code not in Conflict)
>>>>>>>>>>>
(first alternative for conflict starts here)
Multiple code lines here
===========
(second alternative for conflict starts here)
Multiple code lines here too
<<<<<<<<<<<
(Code not in conflict here)
등호와 꺾쇠 괄호를 제거하면서 새 코드를 원하는 방식으로 대안 중 하나 또는 둘의 조합을 선택하십시오.
git commit -a -m "commit message"
git push origin master
git log --merge -p [[--] path]
항상 나를 위해 작동하는 것 같지 않으며 일반적으로 두 분기 사이에 다른 모든 커밋을 표시합니다 --
. 이는 경로를 명령과 분리하는 데 사용할 때도 발생 합니다.
이 문제를 해결하기 위해해야 할 일은 두 개의 명령 줄을 열고 한 번에 실행하는 것입니다.
git log ..$MERGED_IN_BRANCH --pretty=full -p [path]
그리고 다른
git log $MERGED_IN_BRANCH.. --pretty=full -p [path]
대체 $MERGED_IN_BRANCH
내가와 합병 분기와 [path]
충돌하는 파일. 이 명령은 ( ..
) 두 커밋 사이의 모든 커밋을 패치 형식으로 기록합니다 . 위의 명령과 같이 한쪽을 비워두면 git이 자동으로 사용합니다 HEAD
(이 경우 병합중인 분기).
이를 통해 두 분기에서 커밋 된 파일이 분기 된 후에 확인할 수 있습니다. 일반적으로 충돌을 해결하기가 훨씬 쉽습니다.
patience
나는 patience
병합 재귀 전략을 사용하여 갈등을 해결하는 것에 대해 아무도 이야기하지 않은 것에 놀랐습니다 . 큰 병합 충돌의 patience
경우 좋은 결과를 제공했습니다. 아이디어는 개별 라인이 아닌 블록을 일치 시키려고한다는 것입니다.
예를 들어 프로그램의 들여 쓰기를 변경하면 기본 Git 병합 전략 {
이 다른 기능에 속하는 단일 중괄호와 일치 하는 경우가 있습니다. 이것은 피할 수 있습니다 patience
:
git merge -s recursive -X patience other-branch
설명서에서 :
With this option, merge-recursive spends a little extra time to avoid
mismerges that sometimes occur due to unimportant matching lines
(e.g., braces from distinct functions). Use this when the branches to
be merged have diverged wildly.
병합 충돌이 발생하고 분기를 수정할 때 다른 사람들이 염두에두고있는 것을보고 싶다면 분기가 아닌 공통 조상과 분기를 직접 비교하는 것이 더 쉬운 경우가 있습니다. 이를 위해 다음을 사용할 수 있습니다 merge-base
.
git diff $(git merge-base <our-branch> <their-branch>) <their-branch>
일반적으로 특정 파일에 대한 변경 사항 만보고자합니다.
git diff $(git merge-base <our-branch> <their-branch>) <their-branch> <file>
2016 년 12 월 12 일부터 github.com에서 브랜치를 병합하고 충돌을 해결할 수 있습니다
따라서 이전 답변에서 제공되는 명령 줄 또는 타사 도구 를 사용하지 않으려면 GitHub의 기본 도구를 사용하십시오.
이 블로그 게시물 은 자세하게 설명하지만 기본 사항은 UI를 통해 두 가지 분기를 '병합'하면 이러한 충돌 충돌을 처리 할 수있는 편집기로 이동하는 '충돌 해결'옵션이 표시된다는 것입니다.
지점 (테스트)에서 마스터로 병합하려는 경우 다음 단계를 수행 할 수 있습니다.
1 단계 : 지점으로 이동
git checkout test
2 단계 :
git pull --rebase origin master
3 단계 : 충돌이있는 경우이 파일로 이동하여 수정하십시오.
4 단계 :이 변경 사항 추가
git add #your_changes_files
5 단계 :
git rebase --continue
6 단계 : 여전히 충돌이 있으면 3 단계로 다시 돌아가십시오. 충돌이 없으면 다음을 수행하십시오.
git push origin +test
7 단계 : 테스트와 마스터 사이에 충돌이 없습니다. 병합을 직접 사용할 수 있습니다.
나는 항상 충돌을 피하기 위해 아래 단계를 따릅니다.
이제 원하는 지역 지점과 동일한 작업을 수행하고 유지 관리하고 필요할 때 지점에 git checkout을 수행하는 동시에 작업 할 수 있습니다.
서로 다른 상황에서 병합 충돌이 발생할 수 있습니다.
충돌을 해결하려면 Git과 호환되는 병합 도구를 설치해야합니다. 나는 개인적으로 KDiff3를 사용하고 있으며 멋지고 편리하다는 것을 알았습니다. Windows 버전은 여기에서 다운로드 할 수 있습니다.
https://sourceforge.net/projects/kdiff3/files/
BTW Git Extensions를 설치하면 설정 마법사에 Kdiff3를 설치하는 옵션이 있습니다.
그런 다음 git configs를 설정하여 Kdiff를 mergetool로 사용하십시오.
$ git config --global --add merge.tool kdiff3
$ git config --global --add mergetool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add mergetool.kdiff3.trustExitCode false
$ git config --global --add diff.guitool kdiff3
$ git config --global --add difftool.kdiff3.path "C:/Program Files/KDiff3/kdiff3.exe"
$ git config --global --add difftool.kdiff3.trustExitCode false
(경로를 Kdiff exe 파일의 실제 경로로 바꾸십시오.)
그런 다음 병합 충돌이 발생할 때마다이 명령을 실행하면됩니다.
$git mergetool
그런 다음 Kdiff3을 열고 먼저 병합 충돌을 자동으로 해결하려고 시도합니다. 대부분의 충돌은 자발적으로 해결되므로 나머지는 수동으로 수정해야합니다.
Kdiff3의 모습은 다음과 같습니다.
그런 다음 파일을 저장하면 파일이 저장되고 충돌이 발생한 다음 파일로 이동하여 모든 충돌이 해결 될 때까지 동일한 작업을 다시 수행합니다.
모든 것이 성공적으로 병합되었는지 확인하려면 mergetool 명령을 다시 실행하면 다음과 같은 결과가 나타납니다.
$git mergetool
No files need merging
이 답변은 편집기 내에서 모든 작업을 선호하는 VIM 사용자를위한 대안을 추가하는 것입니다.
Tpope는 VIM 용 fugitive 라는 훌륭한 플러그인을 개발했습니다 . 일단 설치되면 :Gstatus
충돌하는 파일을 확인하고 :Gdiff
3 가지 방법으로 Git을 열 수 있습니다.
3 웨이 병합에서 비산 하면 다음과 같은 방식으로 병합하려는 분기의 변경 내용을 얻을 수 있습니다.
:diffget //2
, 원래 ( HEAD ) 브랜치 에서 변경 사항 가져 오기 ::diffget //3
병합 지점에서 변경 사항을 가져옵니다. 파일 병합을 마치면 병합 :Gwrite
된 버퍼를 입력 하십시오. Vimcasts는 이 단계를 자세히 설명 하는 훌륭한 비디오를 발표했습니다 .
git fetch
git check 브랜치
git rebase 마스터
이 단계에서는 선호하는 IDE를 사용하여 충돌을 해결하려고합니다.
이 링크를 따라 https://help.github.com/articles/resolving-a-merge-conflict-using-the-command-line/ 파일에서 충돌을 해결하기 위해 ho를 확인할 수 있습니다.
git add
git rebase
-git commit 계속
-git push origin HEAD : refs / drafts / master 수정 (초안처럼 누름)
이제 모든 것이 잘되고 gerrit에서 커밋을 찾을 수 있습니다.
이것이이 문제에 관한 모든 사람들에게 도움이되기를 바랍니다.
Visual Studio Code를 아직 편집하지 않은 경우 편집 해보십시오. 병합을 시도한 후 병합 충돌이 발생하면 VS 코드는 병합 충돌을 자동으로 감지합니다.
원래 변경 사항이 무엇인지 표시하고 수락해야하는지 incoming
또는
current change
(병합 전 원본 의미) '?.
그것은 나에게 도움이되었고 그것은 당신을 위해 일할 수 있습니다!
추신 : 코드와 Visual Studio Code로 git을 구성한 경우에만 작동합니다.
충돌을 해결하는 더 안전한 방법은 git-mediate 를 사용 하는 것입니다 (여기서 제안 된 일반적인 솔루션은 오류가 발생하기 쉽습니다).
사용 방법에 대한 빠른 소개는 이 게시물 을 참조하십시오 .
Visual Studio를 사용하는 사람들 (내 경우에는 2015)
VS에서 프로젝트를 닫습니다. 특히 큰 프로젝트에서 VS는 UI를 사용하여 병합 할 때 놀라게하는 경향이 있습니다.
명령 프롬프트에서 병합을 수행하십시오.
git checkout target_branch
자식 병합 source_branch
그런 다음 VS에서 프로젝트를 열고 팀 탐색기-> 분기로 이동하십시오. 이제 병합이 보류 중이며 충돌하는 파일이 메시지 바로 아래에 나열된다는 메시지가 나타납니다.
충돌하는 파일을 클릭하면 병합, 비교, 소스 가져 오기, 대상 가져 오기 옵션이 있습니다. VS의 병합 도구는 사용하기가 매우 쉽습니다.
intelliJ를 IDE로 사용하는 경우 다음 방법으로 부모를 지점에 병합하십시오.
git checkout <localbranch>
git merge origin/<remotebranch>
이 같은 모든 충돌을 보여줍니다
A_MBPro : 테스트 anu $ git merge origin / 자동 병합 src / test / java / com /.../ TestClass.java CONFLICT (콘텐츠) : src / test / java / com /.../ TestClass.java에서 병합 충돌
이제 TestClass.java 파일이 intelliJ에서 빨간색으로 표시됩니다. 또한 git status가 표시됩니다
Unmerged paths:
(use "git add <file>..." to mark resolution)
both modified: src/test/java/com/.../TestClass.java
intelliJ에서 파일을 열면 섹션이 있습니다.
<<<<<<< HEAD
public void testMethod() {
}
=======
public void testMethod() { ...
}
>>>>>>> origin/<remotebranch>
여기서 HEAD는 로컬 지점에서 변경되고 origin /은 원격 지점에서 변경됩니다. 여기에 필요한 물건을 보관하고 필요없는 물건을 제거하십시오. 그 후 정상적인 단계를 수행해야합니다. 그건
git add TestClass.java
git commit -m "commit message"
git push