2013-08-02 1 views
2

은의 원격와 동기화되는 지역 Git 저장소에서 시나리오 다음을 고려하자마스터 브랜치가 분기되었을 때 한 번만 병합하는 방법은 무엇입니까?

 
──(A)─┬─(B)── master 
     │ 
     └─(C)── branch 

마스터로 병합 분기 (로컬, (C) = 많은 커밋하기 때문에 시간이 오래 걸립니다) 후 :

 
──(A)─┬─(B)─┬─(D)── master 
     │  │ 
     └─(C)─┘ branch 

 
──(A)───(B)───(E)── master 

지금, 나는이 결과를 갖고 싶어 :

병합하는 동안이 원격 저장소에 무슨 일이 있었
 
──(A)─┬─(B)─┬─(D)──(E)── master 
     │  │ 
     └─(C)─┘ branch 

또는이 결과

 
──(A)─┬─(B)───(E)─┬──(F)── master 
     │   │ 
     └────(C)────┘ branch 

즉 좀 더 라인을 병합하지 않습니다. 많은 것을 (C) 다시 한번 병합하여 오랜 시간을 들이지 않고 그렇게 할 수 있습니까? 누군가가 다음이

──(A)───(B)───(E)── master 

과 같은 원격 코드를 밀어

+0

내가 이것을 이해하려고하자, 당신은 너무 오랜 시간이 걸리기 때문에'C'를 다시 합치는 것을 피하고 싶습니까? 'C '병합에 왜 그렇게 오래 걸리는지 아십니까? 그것은 이상하게 보입니다. –

+0

병합을 이미 완료했다면; 즉, 지점이 2 커밋이고 커밋이 1 커밋임을 의미합니다. 이제 git pull (또는 fetch 및 rebase origin/branchname)을 수행하면 커밋에 대한 커밋이 D - E로 C에 첨부됩니다. 그래서 문제는 어디에 있습니까? – forvaidya

답변

1

경우 그 공공 역사, 당신과 함께 프로젝트 작업을 다른 개발자가 아니라면 당신은 그것을 다시 안 그걸로 알았어. 그리고 새로 워진 역사로 작업을 동기화하는 데 어려움을 겪지 않을 것이다. 그들은 당신이 그들의 역사를 다시 작성과 확인을하지 않은 경우 E 대중 역사에서 무엇을하지 않은, B 대신 D의 자식이되기 때문에, 당신은이

──(A)─┬─(B)─┬─(D)──(E)── master 
     │  │ 
     └─(C)─┘ branch 

을해서는 안된다.

이 상황에서 대부분의 사람들은 하드 리셋을 사용하여 병합을 로컬에서 실행 취소 한 다음 원격에서 마스터의 새로운 팁에 대해 다시 병합 또는 리베이스하는 것입니다.

──(A)─┬─(B)───(E)─┬──(F)── master 
     │   │ 
     └────(C)────┘ branch 

또는이 같은 뭔가 더 선형을 얻을 수 E에 대한 C을 리베이스 수 :의 당신에게 단지 다시 병합을 가정 해 봅시다, 당신이 설명한대로 역사는 다음과 같이 표시됩니다

───(A)───(B)───(E)───(C')── master 

더 많은 정보가 없으면 병합을 피할 수있는 방법을 찾지 못하게하지 않을 것입니다. C 너무 오래 걸릴 것입니다. 왜 그런 문제가 있는지 모르겠습니다.

+0

첫 번째 부분은 맞습니다.이 경우를 고려하지 않겠습니다. 문제는 많은 파일에 많은 충돌이 있다는 것입니다. – majvan

+0

그런 다음 리베이스하는 것은 어떻습니까? 같은 수의 충돌을 해결해야하지만, 나중에 리베이스해야 할 때마다 (누군가가 원격 마스터에게 더 많은 커밋을 푸시하는 것처럼) 충돌이 이미 해결되었을 것이며, 새로운 충돌이있을 때만 해결하면됩니다. –

+0

리베이스를 사용하는 것이 맞지만 많은 변경 사항이있는 지점을 병합하려고하면 원래 지점 기록을 유지하는 것이 좋습니다. 의견을 주셔서 감사합니다. – majvan

0

원하는대로 할 수있는 쉬운 방법은 없습니다. 앞에서 설명한 것처럼 대부분의 사람들은 병합을 실행 취소하고 업스트림 브랜치의 새로운 상태에 따라 다시 실행합니다. 그러나 그것을 할 수 있습니다.

당신은 현재 master 최신 커밋로 병합을 가지고 지점과 당신이 현재의 상단에 병합했던 것처럼 보이게하기 위해 다음과 같은 작업을 수행 할 수 다른 사람들의 최근 개발이 origin/master이있는 경우 오히려 이전 버전보다 origin/master :

git checkout master 
git branch savepoint 
git merge -m temporary origin/master 
git reset --hard $(git show --pretty=format:%B 'HEAD^' | git commit-tree -p 'HEAD^2' -p 'HEAD^^2' -F - 'HEAD^{tree}') 

보이는 병합 추가 병합이 생성됩니다 커밋하지만 그 뜻은 다음과 같은 명령을 사용하여 멀리 갈 . 이 병합은 저장소 내용의 원하는 최종 상태 인 을 얻는 경우에만 수행됩니다.

마지막 명령에는 복잡한 명령이 있습니다. commit-tree 부분은 부모가 E와 C를 커밋하고 이전 병합 작업으로 만든 내용과 에서 커밋 메시지를 작성합니다 (show 명령 덕분에). -F - 옵션). 그런 다음 reset이 새 병합 커밋을 새 상태가됩니다. 이렇게하면 원하는 결과의 첫 번째 옵션이 제공되고 은 공유 된 기록을 다시 쓰지 않습니다.

git reset --hard을 사용하기 때문에 커밋되지 않은 변경 사항이 제거됩니다. savepoint 브랜치는 뭔가 잘못되었을 때를 대비하여 백업을 시작 지점으로 편리하게 만들도록 만들어졌습니다.