2014-12-10 2 views
3

그래서 부분 병합 (git merge --no-commit 경유)을 수행하여 featureA 분기에서만 일부 변경 사항을 가져 왔습니다. 그런 다음 featureB 브랜치에서 병합되었습니다. 이제는 featureA에서 나머지 변경이 필요합니다. Git은 featureA를 다시 병합하면 아무 것도 할 수 없다고 말합니다. Git이 이미 병합되었다고 생각하기 때문입니다.부분 병합을 수행 한 후 분기를 다시 병합하는 방법

아래는 내가 자식이 할 수있는 간단한 명령이 있는가

 featureB ,-------. 
      /  \(merge) 
master----+---+-----+-----+------------+--- 
      \  /(partial merge) /(TODO: merge in rest of featureA) 
    featureA `-----'..................' 
        (no changes here) 

할 노력하고있어 설명하기위한 시도이다?

+1

두 병합을 버리고 다시 실행하는 방법에 대해 어떻게 생각하십니까? –

답변

2

아래 텍스트의 경우 : masterA의 잘못된 병합 이후 축적 된 차이를 반영합니다. 잘못된 병합의 자식으로 커밋 된 올바른 병합 결과를 원하므로 올바른 결과를 다시 마스터로 병합하고 두 팁을 병합 할 때 잘못된 병합과 올바른 병합 간의 차이점을 확인하고 병합합니다.

다음과 같은 방법으로 이야기의 내용을 어느 정도 반영합니다.


당신이 지금 가지고있는 병합베이스, featureA tip은 원하지 않습니다. 그 이후로 변경 사항이 병합되어 이후로 변경 사항은 master에 있습니다. 원래 병합에서 전체 작업을 수행했다면 얻은 병합 기록과 결과가 필요합니다. 참조 할 수 있도록 커밋 그래프의 압축 된 버전 : 당신이 지금

# redo the original merge to get the right parents and the right content 
git checkout $APM^  # checkout the original merge parent 
git merge $APM^2   # do the correct merge with its other parent 
git checkout -b AM  # give this work a name 

:

#   /-B.....-\   featureB 
# ---A0---B0---APM---BM---? master [APM, featureA partial merge, is bad] 
#  \-A...../??????????/ featureA [can keep history, merge rest of A?] 

1 단계는 당신이 첫 번째 장소에서 원하는 병합 결과를 얻을 수 있습니다

#   /-B......\ 
# ---A0---B0---APM---BM---? 
#  \  \-/-AM 
#  \-A.../-/ 

AM의 부모가 $APM과 같지만 올바른 결과입니다. $APM이 무엇을했는지는 AM에도 있습니다. AM은 올바른 결과를 얻으려면 $APM으로 변경해야 할 사항을 구체화합니다. $APM 커밋에있는 모든 내용이 AM에 병합되었습니다 (리터럴 효과 있음).

git merge -s ours $APM # $APM is correctly incorported in AM. Tell git. 

그리고 그 올바른 역사를 만든다 : AM$APM 변경 한 세트를 반영, 그리고 master 다른를 반영한다.

git checkout master 
git merge AM 

git branch -d AM을 나는이 권리를 가지고있는 경우에, 당신은 완료 : 시간 병합합니다.

git clone -s . ../wip # safety play: sandbox the changes 
# do the above, and when you're satisfied you've got `master` correct, 
cd ../$mainrepo 
git checkout master # okay, incorporate the results 
git pull    # . 
rm -rf ../wip   # (everything in wip is now also here) 

테스트 : 경우에 따라, 스크래치의 repo에 이상을 알림 또는주의로 그래도 뭔가 잘못을 가지고 그냥 경우


:

# drop this as file `script` in an empty directory and 
# say `sh script` to recreate the described situation: 

set -x 
git init --template= 
for f in {1..5}; do seq -ffile$f%4.0fx 10 >f$f; done 
git add . 
git commit -m'Initial commit' 
git checkout -b featureA 
sed -si s/4x/4-featureA/ f2 f3 
git commit -am4featureA-f2f3 
git checkout master 
sed -si s/1x/1-master/ f1 f2 f3 
git commit -am1master-f1f2f3 
git checkout -b featureB 
sed -si s/8x/8-featureB/ f3 f4 
git commit -am8featureB-f3f4 
git checkout master 
git merge --no-commit featureA 
git checkout HEAD f3 
git commit -m'Merge branch featureA - less the f3 changes' 
git tag APM 
git merge --no-edit featureB 

# and test the given solution: 

git checkout -b AM APM^ 
git merge --no-edit featureA 
git merge --no-edit -s ours APM 
git checkout master 
git merge --no-edit AM 

# say `rm -rf f* .git` to cleanup 
+0

위대한, 시도하자. – gjcamann

+0

브랜치 생성 명령을 수정했습니다. 늦은 편집을해서 죄송합니다. – jthill

+0

시도해 줘서 고맙지 만, 이것이 작동하지 않았다 ... 힘내는 우리의 필사자가 여전히 똑똑해서 속인다. 유일한 선택은 제 시간에 돌아가서 모든 것을 다시 합치는 것입니다. – gjcamann

1

당신이 설명한 것처럼 IMO 부분 병합은 지금 당장이나 다른 일들을 경험하는 이유 때문에 악조건입니다.

예 : 저장소에서 작업하는 개발자는 masterfeatureA의 모든 변경 사항이 포함될 것으로 예상합니다. 이것은 많은 혼란을 야기 할 수 있습니다.


참고 : 난 당신이 저장소의 루트에 마스터 분기에 현재이라고 가정합니다.

당신은 effectivly이 쉽게 가지 옵션이 있습니다 : 당신은 masterfeatureA의 나머지 변경 내용을 병합하는 git checkout --merge featureA -- .를 사용

  1. - 당신이 병합

  2. 당신은 할 커밋이되지 않습니다이 경우를 빈 커밋 (git commit --allow-empty)이 featureA에 있고 다시 병합

두 가지 해결책이 부분 병합의 결과 인 차선책입니다.

더 깨끗한 접근법은 오래된 합병을 되 돌리는 것입니다. featureA을 여러 개의 커밋으로 나누고 필요한 커밋 만 병합하십시오. 그런 다음 나중에 나머지를 병합 할 수 있습니다.
이것은 분명히 가장 많은 노력을 기울이는 접근법이기도합니다.

개인적으로 나는 옵션 1 또는 2 중 하나를 제안하고 향후 이러한 병합을 피하십시오.


내가 this answer에 기술 된 방법을 사용하여 커밋 수동으로 병합을 만들려고했습니다편집 할 수 있습니다. 그러나 그것은 자식이 이미 featureA이 병합되었고 두 번째 부모를 버리고 있다는 사실을 인식하고있는 것처럼 보이기 때문에 결과는 단순하고 병합하지 않습니다.

관련 문제