당김 동안 변경 사항에 찬성하여 Git 병합 충돌 해결


1225

변경 사항을 가져 오기 위해 git merge 충돌을 어떻게 해결합니까?

기본적으로 충돌없는 git mergetool모든 변경 사항을 유지하면서 잠시 동안 모든 충돌 을 거치지 않고 작업 트리에서 충돌하는 모든 변경 사항을 제거해야합니다 . 나중에 당기지 않고 당기는 것이 좋습니다.




3
@DanDascalescu 수락 된 답변이 질문에 대한 답변이 없으므로 분명히 중복되지 않습니다. 또한, 그 다른 질문은 매우 모호합니다. 요청 된 내용을 말하기는 매우 어렵습니다. 전혀 동의하지 않습니다. 이것에서 무엇을 지적하고 있습니까?
sanmai

2
@sanmai 두 가지 답변이 있으며 그 중 하나를 수락했습니다. 답변에서 기대하는 내용과 여기에서 얼마나 자세한 정보를 더 잘 설명 할 수 있습니까?
Edward Thomson

2
@EdwardThomson 글쎄, 실제로 나는 첫 번째 답변에 대해이 평판을 줄려고 생각했지만, 당신이 묻는다면, 더 나은 답변이
나오는지

답변:


1217
git pull -s recursive -X theirs <remoterepo or other repo>

또는 간단히 기본 저장소의 경우 :

git pull -X theirs

이미 충돌 상태 인 경우 ...

git checkout --theirs path/to/file

40
참고 것을 -s recursive그 기본 병합 전략이기 때문에 여기에 중복입니다. 따라서을 단순화 할 수 있습니다. git pull -X theirs기본적으로와 같습니다 git pull --strategy-option theirs.

5
이렇게하면 MERGING상태로 돌아갑니다 . 그런 다음 git merge --abort다시 시도 할 수 있지만 매번 병합이 발생합니다. … 나는 rebase가 나의 업스트림으로 밀려났다는 것을 알고 있습니다.
벤존

22
주의하십시오 git checkout --theirs path/to/file. 리베이스 중에 사용하여 예기치 않은 결과가 발생했습니다. doc에서 설명을 찾았습니다 : git rebase와 git pull --rebase 중에 우리와 그것들이 서로 바뀔 수 있습니다. --ours는 변경 사항이 기반으로하는 지점의 버전을 제공하는 반면, --res는 기반이되는 작업을 보유한 지점의 버전을 제공합니다.
Vuk Djapic

10
참고 git checkout --theirs/--ours path이를 위해 작동 매뉴얼 페이지 상태를 병합 경로 . 따라서 경로에 충돌이 없으면 이미 병합되어이 명령은 아무 작업도 수행하지 않습니다. 예를 들어 전체 하위 폴더의 '그들의'버전과 같은 경우 문제가 발생할 수 있습니다. 따라서 이러한 경우 git checkout MERGE_HEAD path커밋 해시를 사용하거나 사용하는 것이 더 안전합니다 .
fsw

4
git pull -X theirs충돌이있는 경우 (예 : 다른 커미터가 git push -f원격으로 실행 된 경우) 병합 커밋을 만듭니다 . 병합 커밋을 원하지 않으면 대신 실행하십시오 git fetch && git reset --hard origin/master.
Dan Dascalescu

985

재귀적인 "그들의"전략 옵션을 사용할 수 있습니다 .

git merge --strategy-option theirs

로부터 사람 :

ours
    This option forces conflicting hunks to be auto-resolved cleanly by 
    favoring our version. Changes from the other tree that do not 
    conflict with our side are reflected to the merge result.

    This should not be confused with the ours merge strategy, which does 
    not even look at what the other tree contains at all. It discards 
    everything the other tree did, declaring our history contains all that
    happened in it.

theirs
    This is opposite of ours.

참고 : man 페이지 말한대로의 "우리"병합 전략 옵션 은 "우리의"병합 매우 다르다 전략 .


자세한 설명은 다음과 같습니다. lostechies.com/joshuaflanagan/2010/01/29/…
mPrinC

227
또한 git checkout --theirs하나의 상충되는 파일에 대한 작업
dvd

48
이미 충돌 해결 상태 인 경우 작동하지 않습니다. 이 경우 해결하는 가장 좋은 방법은 다음과 같습니다 git checkout <ref to theirs> -- the/conflicted.file. 그리고 git add그들의 변화.
ThorSummoner

54
@ThorSummoner이 경우 git checkout이 있습니다. 경로 / 파일 / 파일입니다. 그렇게하면 올바른 해시를 수동으로 찾을 필요가 없습니다.
Ikke

8
@ Ikke 그것은 당신이 저에게 묻는다면 기본적으로 자신의 대답 (그리고 그에 대한 대답)이어야합니다.
ThorSummoner

473

이미 충돌 상태에 있고 모든 것을 수락하려면 다음을 수행하십시오.

git checkout --theirs .
git add .

당신이 반대를하고 싶다면 :

git checkout --ours .
git add .

이것은 매우 과감하므로 수행하기 전에 이와 같이 모든 것을 지우고 싶은지 확인하십시오.


47
또는을 사용하지 말고 .체크 아웃하려는 점 대신 파일을 지정하십시오. 덜 "과감한"& 정확하게하고 싶은 일, 아마도.
manroe

10
파일이 다른 분기에서 제거 된 경우에는 작동하지 않습니다 : '<file>'버전이 없습니다
Japster24

3
내가 할 수 있다면 더 많이 찬양하고, 계속 해서이 대답으로 돌아 오십시오.
tarikki

6
git add -u버전 관리를받지 않는 파일을 건너 뛰려면 대신 사용하십시오 .
Sudipta Basak

3
가상의 경우, 파일의 세 가지 변경 사항, 하나의 충돌, 두 개의 충돌 없음이 솔루션이 충돌하지 않는 변경 사항을 적용하고 충돌하는 변경 사항을 해결합니까? 아니면 충돌하지 않는 변경 사항을 무시하고 버전 만 사용합니까?
pedromarce

222

좋아, 내가 방금 있었던 시나리오를 상상해보십시오.

당신은 시도 merge, 또는 어쩌면 cherry-pick, 당신은 함께 중지하고

$ git cherry-pick 1023e24
error: could not apply 1023e24... [Commit Message]
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'

이제 충돌 된 파일을보고 변경 사항을 유지하고 싶지 않습니다. 위의 경우 파일이 IDE에 자동 추가 된 줄 바꿈으로 충돌했습니다. 변경 사항을 취소하고 변경 사항을 승인하려면 가장 쉬운 방법은 다음과 같습니다.

git checkout --theirs path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

이것의 반대는 (들어오는 버전을 당신의 버전으로 덮어 쓰는 것입니다)

git checkout --ours path/to/the/conflicted_file.php
git add path/to/the/conflicted_file.php

놀랍게도, 나는이 답변을 인터넷에서 매우 쉽게 찾을 수 없었습니다.


15
하나가 행하는 경우에는, 그 주 git status사이 checkoutadd같이, 파일이 아직 방송이 "모두 수정".
주교

충돌 상태에있는 모든 파일에 대해이를 수행 할 수있는 방법이 있는지 알고 있습니까? 그렇다면 대답에 대한 훌륭한 확장이 될 것입니다.
Drew Noakes

2
나는 이것을한다 : git reset --hard 그리고 나서 git pull [remote server name] [branch name] -Xtheirs(병합을 취소 한 다음 내 물건 위에 새로운 물건을 가져옵니다)-이것이 원하는 것인지 확실하지 않습니다.
ssaltman

38

git pull -X theirs대답은 못생긴 병합 커밋을 만들거나

오류 : 다음 파일에 대한 로컬 변경 사항을 병합하여 덮어 씁니다.

예를 들어 항상 원점의 미러 여야하는 클라이언트와 같이 리포지토리의 파일에 대한 로컬 수정 사항을 단순히 무시하려면 다음을 실행하십시오 ( master원하는 분기로 교체 ).

git fetch && git reset --hard origin/master

어떻게 작동합니까? 하지만 병합 git fetch하지 않습니다git pull . 그런 다음 git reset --hard작업 트리를 마지막 커밋과 일치시킵니다. 리포지토리의 파일에 대한 모든 로컬 변경 내용은 삭제 되지만 새 로컬 파일은 그대로 유지됩니다.


1
+ git fetch && git reset --hard {remote}/{branch}1-내 문제를 해결 한 것이 었습니다. 나는 지점의 "그들의"상태에 유리하게 내 자신의 변화를 완전히 버려야했다 git pull -X theirs. 감사!
Ivaylo Slavov

23

git merge 후 충돌이 발생하고 자신 또는 자신이 원하는 경우

git checkout --theirs .
git checkout --ours .

충돌하는 청크 단위로 어떻게해야합니까? 위의 내용은 파일 수준에서 작동하여 충돌하는 파일이 가지고있는 충돌하지 않는 덩어리를 버립니다.
Jani

21

특정 분기의 버전과의 모든 충돌을 해결하려면

git diff --name-only --diff-filter=U | xargs git checkout ${branchName}

따라서 이미 병합 상태에 있고 충돌하는 파일의 마스터 버전을 유지하려는 경우 :

git diff --name-only --diff-filter=U | xargs git checkout master

파이프 xargs에 접근 할 수없는 창문에있는 사람들에게 이것은 어떻게 해석됩니까?
tsemer

변경 사항을 완전히 건너 뛰지 않습니까? 충돌 상태에 있지 않은 사람들조차도?
Valentin Heinitz

이것이 내가 한 일입니다. 불행하게도 그 이후 중 하나가 필요 git cherry-pick --continue 하거나git commit --allow-empty 이러한 변경 사항을 커밋 명령을,이 고통을 자동화하게 명령이 요구되는 뒤에 어떤 시스템 없을 것 같습니다. 나는 현재 .git/COMMIT_EDITMSG파일 의 존재 여부를 테스트 하여이 문제를 해결하고 있지만 해킹되고 부서지기 쉬운 것처럼 보이지만 아직 그것이 항상 작동한다고 확신하지는 않습니다.
Konrad Rudolph

이것은 좋으며, 일부를 수동으로 해결하고 ( git add) 수행 하면 나머지를 대량으로 해결할 수 있습니다. git checkout --ours/ git checkout --theirs도 유용합니다.
rcoup

18

때때로 이것은 작동하지 않습니다 .

git checkout-경로 / 파일 / 파일

또는

자식 체크 아웃-경로 / 파일 / 파일

HEAD가 우리 이고 MERGE_HEAD가 그들의 것이라고 가정하면 대신이 작업을 수행했습니다.

git checkout HEAD -- path/to/file

또는:

git checkout MERGE_HEAD -- path/to/file

우리가 이것을 한 후에 우리는 좋다 :

git add .

자세한 내용을 보려면 여기에서 멋진 torek 게시물을 참조하십시오 : git checkout-우리는 병합되지 않은 파일 목록에서 파일을 제거하지 않습니다


12

VS 코드 (통합 Git) IDE 사용자 :

충돌 파일에서 들어오는 모든 변경 사항 을 승인 하려면 다음 단계를 수행하십시오.

1. Go to command palette - Ctrl + Shift + P
2. Select the option - Merge Conflict: Accept All Incoming

마찬가지로 모두 수락, 모두 현재 수락 등의 다른 옵션에 대해서도 수행 할 수 있습니다 .


2
그것은 하나의 파일에서만 작동하는 것으로 보이지만 모든 파일이 충돌하는 것은 아닙니다.
Yoryo

1

next-version변경 된 develop파일, 두 지점의 다른 위치에 추가 된 파일 등 이 많이 삭제 된 장기 실행 브랜치 가있었습니다.

next-version분기 의 전체 내용을 develop하나로 병합하고 병합 커밋 을 수행하고 싶었습니다 .

나를 위해 일한 위의 명령 조합은 다음과 같습니다.

git merge -X theirs next-version
# lots of files left that were modified on develop but deleted on next-version
git checkout next-version .
# files removed, now add the deletions to the commit
git add .
# still have files that were added on develop; in my case they are all in web/
git rm -r web

새로운 답변이 아니며 많은 답변의 비트를 결합하여 부분적으로 이러한 답변이 모두 필요할 수 있음을 보장합니다 .


1

이미 충돌 상태에 있고 경로를 하나씩 체크 아웃하지 않으려는 경우. 당신은 시도 할 수 있습니다

git merge --abort
git pull -X theirs

-1

에서 https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging

이것은 기본적으로 가짜 병합을 수행합니다. 두 분기를 모두 부모로하여 새 병합 커밋을 기록하지만 병합하려는 분기도 보지 못합니다. 병합 결과로 현재 분기의 정확한 코드를 기록합니다.

$ git merge -s ours mundo

'우리의'전략에 의해 합병.

$ git diff HEAD HEAD~

우리가 있던 브랜치와 병합 결과 사이에 차이가 없음을 알 수 있습니다.

이것은 종종 나중에 병합을 할 때 브랜치가 이미 병합되었다고 생각하도록 Git을 속이는 데 유용 할 수 있습니다. 예를 들어 릴리스 지점을 분기하고 어느 시점에서 마스터 지점으로 다시 병합하려는 일부 작업을 수행했다고 가정합니다. 그 동안 마스터의 일부 버그 수정을 릴리스 브랜치로 백 포트해야합니다. 버그 수정 브랜치를 릴리즈 브랜치에 병합 할 수 있으며, 동일한 브랜치를 마스터 브랜치에 병합 할 수 있습니다 (수정이 이미 존재하더라도) 나중에 릴리스 브랜치를 다시 병합 할 때 버그 수정과 충돌이 없습니다.

마스터가 새로운 토픽 브랜치의 변경 사항을 반영하기를 원할 때 유용한 것으로 나타났습니다. -Xtheirs는 일부 상황에서 충돌없이 병합되지 않습니다. 예 :

$ git merge -Xtheirs topicFoo 

CONFLICT (modify/delete): js/search.js deleted in HEAD and modified in topicFoo. Version topicFoo of js/search.js left in tree.

이 경우 내가 찾은 해결책은

$ git checkout topicFoo

topicFoo에서 -s ours 전략을 사용하여 마스터에서 먼저 병합하면 topicFoo의 상태 인 가짜 커밋이 생성됩니다. $ git merge -s 우리의 마스터

생성 된 병합 커밋 확인

$ git log

이제 마스터 지점을 체크 아웃하십시오.

$ git checkout master

토픽 브랜치를 다시 병합하지만 이번에는 -Xtheirs 재귀 전략을 사용하십시오. 그러면 topicFoo 상태의 마스터 브랜치가 표시됩니다.

$ git merge -X theirs topicFoo
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.