2013-01-08 3 views
8

병합 작업을 수행한지 얼마 전에 병합이 수행 된 저장소에서 --strategy=ours 플래그 (--strategy-option = ours 플래그를 사용)가 사용되었으므로 HEAD에 변경 사항이 적용되지 않았습니다. 그러나 변경 사항을 적용해야합니다. Git은 이미 브랜치가 Merge 된 것으로 인식하고 브랜치의 히스토리에 커밋을한다.strategy = ours를 사용하는 병합을 취소하는 방법은 무엇입니까?

병합 이런 종류의 git revert -m ...

은 무엇 복귀 및/또는 재 적용 파일을 변경할 수있는 병합을 적절한 방법이 될 것입니다 사용하여 되돌릴 수 없습니다?

master A - B - E - F - G ---> L - M - N 
      \ /
topic   C - D 

병합 커밋 (F)은이 시나리오에서 범인이 될 것입니다.

+0

파일을 병합하는 분기의 끝 부분에 새로운 커밋을 생성하면 기록을 다시 쓰지 않으려한다고 말하는 것이 안전한가요? –

+0

사실, 역사를 다시 쓰는 것이 괜찮은 선택이 될 것입니다. 이 상황에서 변경 사항이 실제로 적용되는 한 중요하지 않습니다. 참고 사항 : 우리는 'master'브랜치로 병합을 수정하려고하는데, master 브랜치는 수십 번 분기되었으므로 다른 브랜치 병합에 병합 할 수 있어야합니다. –

답변

6

이 문제에 대한 해결책을 발견했습니다. 리누스가 잘못된 합병을 되 돌리는 것에 관해 썼던 서한은 모두 How to revert a faulty merge입니다. 이 경우 git merge --strategy=ours topic은 의도하지 않았습니다. 병합 오류가 있어도 되돌릴 수없고 오랫동안 푸시 된 경우 되돌리기 커밋을 되돌릴 수 없으면 병합 되돌리기가 수행되는 것과 동일한 효과가 있습니다.

해결 방법은 항목 분기를 체크 아웃하고 첫 번째 커밋에서 rebase --no-ff을 실행 한 다음 해당 분기를 다시 마스터로 병합합니다.

fixed–topic C'–––D'––––––––––––––––––––- 
      /       \ 
master A–––B–––E–––F–––G –––> L–––M–––N–––F2 
      \ /
topic   C–––D 

정말 깊이있는 이것을 이해 분기를 다시 만들 수 --no-ff REBASE 옵션을 사용하여 문자 How to Revert a Faulty Merge의 마지막 부분을 읽으려면 :

git checkout topic 
git rebase -i --no-ff <C> 
git checkout master 
git merge topic 

은 항복의 효과가 있었다.

0

병합 전략은 "자연스럽게 병합 되더라도 상관없이 여기에있는 것을 유지하십시오."라는 병합 전략은 되돌릴 수 없습니다. 새 분기에서 병합의 첫 번째 부모를 체크 아웃 한 다음 병합을 다시 수행합니다. Rebase - 원래의 병합 부분 위에있는 커밋의 나머지 부분을 본다.

UPDATE : 당신이 과거에 대해 걱정하지 않는 경우

귀하의 경우에는

, 당신은 E에 G-N을 리베이스하고 그냥이 새 마스터에 D를 병합 할 수 있습니다. rebase는 F가 - 머지 합병이기 때문에 사소할 것입니다.

+0

안녕하세요, 제 질문을 약간 더 명확하게 편집했습니다. -이 병합이 수행 된 이후에 master 브랜치에 대해 69 개의 ​​커밋이 만들어졌습니다. 나는 팀 구성원의 저장소에 잠재적으로 치명적인 오류를 일으킬 수있는 내역을 다시 작성하고 rebase의 병합을 내 repos에 병합 할 수 있다는 점에 흥미가 있습니다. 아마도 적절한 대안이 없다면 패치 경로를가는 것이 가장 안전한 방법 일 수 있습니까? –

+0

리베이스와 패치는 결국 똑같습니다. 리베이스는 훨씬 더 자동화되어 있습니다. 재시작해야 할 경우에 대비하여 다시 충돌을 설정하고 동일한 충돌 해결을 다시하고 싶지 않을 때를 대비하여 기억하십시오. –

3

@Highway of Life 좋은 대답이 있습니다. 그 중 하나는 리스터 된 커밋이 새로운 커밋처럼 보이기 때문에 많은 경우 바람직하지 않을 수 있습니다. 동일한 커밋을 두 번 병합하려고했지만 git-merge이이를 방지합니다. 그러나, 나는 항상 당신이 원하는 것을 할 자식을 얻을 수있는 시간과 시간을 찾습니다.

  1. 따르 생명의 지시의 고속도로하지만 마스터에 바로 병합하지 않습니다

    지금 나무가 설정되어
    re-merged    ––––––––––––––––––––------R 
            /      /
    fixed–topic  C'–––D'      /
           /       /
    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /
    topic   C–––D 
    
  2. 정확하게 당신이 원하는 방법 :

    git checkout -b fixed-topic <D> 
    git rebase -i --no-ff <B> 
    git checkout -b re-merged master 
    git merge fixed-topic 
    

    이 결과 - 파일이 원하는 내용을 정확하게 보여줍니다. 한 가지 문제는 병합 커밋의 부모가 실제로 원래 커밋이 아닌 원래 커밋의 리베이스 된 복사본이라는 것입니다.그것은 git-reparent와 함께이 문제를 해결하기 쉽습니다 :

    master  A–––B–––E–––F–––G –––> L–––M–––N–––F2 
           \ /      \ 
    topic   C–––D       \ 
             \       \ 
    re-merged    ---------------------------R 
    

    주목해야 할 중요한 것은 R의 내용이 마지막 단계 만 부모 이후 변경되지 않은 것을 :

    git reparent -p master -p <D> 
    

    이 함께 끝 . 새로운 병합에

  3. 빨리 감기 마스터 커밋 :

    git checkout master 
    git merge re-merged 
    
  4. 마지막으로 당신이

    git branch -d fixed-topic re-master 
    

완료로 정리 할 수 ​​있습니다! 역사는 다음과 같습니다 :

master A–––B–––E–––F–––G –––> L–––M–––N–––F2---R 
      \ /      /
topic   C–––D---------------------------- 
+0

'reparent' 옵션이 제 3 자 함수라는 것을 몰랐습니다. Seams는 아주 좋은 해결책 이었지만 더 간단한 해결책을 찾고있었습니다. –