2013-10-17 1 views
12

Github에서 자동으로 병합 할 수 없다고 말하는 풀 요청이 있습니다. 이 변경은 몇 가지 커밋이지만 충돌이없는 마스터의 배후에 있습니다.Github은 분기를 병합 할 수없고 충돌도없고 수동으로 자동 병합합니다.

수동으로 내가 충돌을하지 않는 병합, 나는이 출력 얻을 :

(on master) 
$git merge otherbranch 
[vim pops up for commit message, :wq] 
Auto-merging <file> 
Merge made by the 'recursive' strategy. 
<file> | 1 + 
1 file changed, 1 insertion(+) 

는 Github에서 자동으로 병합 할 수 없습니다 이유가 있습니까? 그것은 어쨌든 명령 행에서 자동으로 병합되었습니다. Github이 자동으로 충분하지 않습니까?

답변

12

이유는 git merge은 기본적으로 "재귀 적"병합이라는 전략을 사용하기 때문입니다. 3 방향 병합을 수행 할 수 있습니다. 한 쪽에서 패치를 가져 와서 다른쪽에 패치를 적용하여 새 파일을 생성 할 수 있습니다. 또한 분기 및 병합이 많이 발생하는 복잡한 상황에서이 작업을 재귀 적으로 수행합니다. 여러 병합베이스이 병합됩니다. 3 방향 병합 할 수없는,이 개 병합 기지로

$ git merge-base --all 90d64557 05b3dd8f 
711d1ad9772e42d64e5ecd592bee95fd63590b86 
f303c59666877696feef62844cfbb7960d464fc1 
$ 

:

는 최근이 같은 상황이 발생했습니다. '순환'전략은 따라서 두 커밋의 병합에 처음 재귀하여이를 해결 :

$ git merge-base 711d1ad9 f303c596 
3f5db59435ffa4a453e5e82348f478547440e7eb 
$ 

OK, 하나 개의 병합 기지, 그래서 3 방향 병합을 시작할 수 있습니다. 양쪽에 어떤 변화가 있습니까?

$ git diff --stat 3f5db594 711d1ad9 
normalize/coll.py  | 116 ++++++++++++++++++++++++++++++++++++++----------- 
normalize/visitor.py | 49 ++++++++++----------- 
tests/test_property.py | 10 +++-- 
3 files changed, 120 insertions(+), 55 deletions(-) 
$ git diff --stat 3f5db594 f303c596 
normalize/identity.py | 38 +++++++++++++++++++++++++++++++------- 
tests/test_property.py | 2 ++ 
2 files changed, 33 insertions(+), 7 deletions(-) 
$ 

이 두 차이점은 모두 같은 파일을 변경, 그래서 그들은 단지 (AN 지수는 병합) 각 측면에서 각 파일의 최신 버전을 복용하는 간단한 전략을 사용하여 해결 될 수 없다. 대신 git은 한 쪽에서 새 파일을 가져 와서 다른 쪽에서 패치를 적용하려고합니다.그 결과, 결합이 같은 시뮬레이션 할 수있는 저지된다

$ git checkout -b tmp 
Switched to a new branch 'tmp' 
$ git reset --hard f303c59666877696feef62844cfbb7960d464fc1 
HEAD is now at f303c59 record_id: throw a more helpful error if record identity is not hashable 
$ git merge 711d1ad9772e42d64e5ecd592bee95fd63590b86 
Auto-merging tests/test_property.py 
Merge made by the 'recursive' strategy. 
normalize/coll.py  | 116 ++++++++++++++++++++++++++++++++++++++----------- 
normalize/visitor.py | 49 ++++++++++----------- 
tests/test_property.py | 10 +++-- 
3 files changed, 120 insertions(+), 55 deletions(-) 
$ git diff --stat 3f5db594 HEAD tests/test_property.py 
tests/test_property.py | 12 +++++++++--- 
1 file changed, 9 insertions(+), 3 deletions(-) 
$ 

그런 다음 그 시작점이 병합의 결과를 이용하여, 원래의 3 방향 병합 반환 이 또한 같은 파일에 대한 변경 사항을 포함한다 :

$ git diff --stat HEAD 90d64557| grep selector 
normalize/selector.py   | 17 +-- 
tests/test_selector.py   | 19 ++-- 
$ git diff --stat HEAD 05b3dd8f| grep selector 
normalize/selector.py | 29 +++++++++++++++++------------ 
tests/test_selector.py | 9 +++++++++ 
$ 

그러나 다시 변경은 파일의 다른 섹션에 있습니다, 그래서 DIFF을 복용하고 다른면에 적용하는 것은 성공이다.

그래서 C git은 먼저 두 시작 지점의 두 병합 기준을 3 방향 병합 한 다음 병합중인 두 원래 커밋에 다른 3 방향 병합을 수행하여이 병합을 해결할 수있었습니다. 첫 번째 병합의 중간 결과.

Github의 자동 해상도는이 작업을 수행하지 않습니다. 꼭 필요한 것은 아니며 반드시 구현되는 반복적 인 전략이 얼마나 많은지 잘 모르겠지만 조심성있는 측면에서 잘못 생각하고 있습니다. 바로 그 점에서 큰 녹색 버튼을 기대합니다 :-).

+0

재귀 적 병합 전략에 좋은 추가. +1 내 자신의 대답을 잘 보완합니다. – VonC

5

아니요, 약 merging. It is about rebasing이 아닙니다.

당신은 시도 및 지역의 repo에, 리베이스해야

master 위에, otherbranch (your fork의 복제). 먼저

, 반드시 마스터가 원래 상류의 repo에서 가장 최근의 하나입니다합니다

fork 당신이 해결해야 충돌, git add를 생성 리베이스하고 git rebase --continue

cd /your/local/repo 
git remote add upstream /url/original/repo 
git fetch upstream 

# Make sure you don't have any local commmit on your master 
git branch -f master upstream/master # reset your master branch 
            # to the one from upstream repo 
git checkout otherbranch 
git rebase master 

.

마지막으로, 포크 단순히 push --force 지사 : 자동 (다른 아무것도 할 수 없습니다) 당신의 풀 요청을 업데이트합니다 .

git push -u -f otherbranch origin 

more tips about pull-requests here를 참조하십시오 (이미 한 번 밀어 경우, 혼자 git push이 충분해야한다).

+0

좋아, 나는 그것이 맞는 것 같아요. 감사! – jpimentel

0

기본적으로 Git은 병합 커밋에 대한 커밋 메시지를 확인하기 전에 분기를 자동 병합 할 수 있는지 여부를 알지 못합니다. 당신은 당신이 어떤 충돌이되지 않습니다 알고있는 경우

, 당신은 cat 또는 true을 추가하여, 예를 들어, 비 대화 형 도구에 GIT_EDITOR을 변경하여 재귀 자동 병합의 과정을 자동화 할 수 있습니다 :

GIT_EDITOR=true git merge otherbranch 

pull에 대해서도 동일합니다. -X theirs 또는 -X ours과 같은 병합 전략을 지정할 수도 있습니다.

또는 다른 방법은 rebase (pull 명령에 -r 추가)입니다.