git remove merge commit from history


99

내 Git 기록은 다음과 같습니다.

힘내 역사

보라색 커밋을 하나의 커밋으로 스쿼시하고 싶습니다. 내 커밋 로그에서 다시는보고 싶지 않습니다.

나는을 시도했지만 파란색 가지에 git rebase -i 1있지만 1(그림 참조) 보라색 가지에있는 모든 커밋을 볼 수 있습니다.

커밋 로그에서 퍼플 브랜치를 완전히 제거하려면 어떻게해야합니까?


다른 사람들이 가져온 리포지토리가 어디에나 밀려 있습니까?
Schleis

두 가지 모두 순전히 지역적입니다.
Benjamin Toueg 2013

답변:


101

git rebase -i <sha before the branches diverged>이 당신이 병합을 제거 할 수 커밋하고 당신이 원하는대로 로그는 하나 개의 라인을 것입니다. 더 이상 원하지 않는 커밋을 삭제할 수도 있습니다. 리베이스가 작동하지 않는 이유는 충분히 멀리 돌아 가지 않았기 때문입니다.

경고 :이 작업을 수행하면서 기록을 다시 작성하고 있습니다. 원격 리포지토리에 푸시 된 변경 사항으로이 작업을 수행하면 문제가 발생합니다. 로컬 커밋으로 만이 작업을 수행하는 것이 좋습니다.


4
가지가 갈라 전에 나는 샤을 선택하더라도, 나는 -_- 보라색 지점의 모든 커밋 참조
벤자민 Toueg을

1
예, 그런 다음 나타나는 편집기에서 삭제하면 git rebase제거됩니다.
Schleis 2013

4
커밋을 삭제하면 병합의 모든 수정 사항이 손실됩니다. 그러나 나는 소프트 리셋을했고 내가 원하는 것과 같은 것을 가질 수 있었다 (주문이 초기 기대와 일치하지 않음).
Benjamin Toueg 2013

2
이 답변은 세부적으로 불완전합니다. 어떤 분기에서 리베이스를 시작합니까?
grgry

3
커밋을 '제거'하고 싶지는 않습니다. 'remove'는 rebase의 옵션이 아니지만 delete는 있습니다. 커밋을 삭제하면 도입 된 변경 사항이 손실됩니다. 커밋을 스쿼시하고 싶습니다.
thecoshman

71

원래 상태의 저장소로 시작

원래 repo 기록

병합 커밋을 제거하고 분기를 메인 라인의 단일 커밋으로 스쿼시하려면

스쿼시 된 커밋, 병합 커밋 없음

다음 명령을 사용하십시오 (5 및 1을 해당 커밋의 SHA로 대체).

git checkout 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git rebase HEAD master

병합 커밋을 유지하지만 분기 커밋을 하나로 스쿼시하려면 :

스쿼시 된 커밋, 유지 된 병합 커밋

다음 명령을 사용하십시오 (5, 1 및 C를 해당 커밋의 SHA로 대체).

git checkout -b tempbranch 5
git reset --soft 1
git commit --amend -m '1 2 3 4 5'
git checkout C
git merge --no-ff tempbranch
git rebase HEAD master

병합 커밋을 제거하고 분기에서 개별 커밋으로 바꾸려면

분기가 메인 라인으로 이동하고 병합 커밋 없음

그냥하세요 (5를 해당 커밋의 SHA로 대체) :

git rebase 5 master

마지막으로 가지를 완전히 제거하려면

분기가 완전히 제거됨

다음 명령을 사용합니다 (C와 D를 해당 커밋의 SHA로 대체).

git rebase --onto C D~ master

git rebase 5 master경우, 이유는 없다 "ABC 1 2 3 4 5 ... D"순서는?
Roy

1
이 명령 은와 master공통되지 않는 커밋을 가져와 . 은 커밋 의 혈통의 일부가 아닌 , 그 위에 이동 첫 번째입니다 . 55C55
Allen Luce

2
"ABC 1 2 3 4 5 D ..."로 끝내려면 다음을 수행 할 수 있습니다.git rebase C 5; git rebase 5 master
Allen Luce

19

병합 커밋 만 제거하려면

만약 당신이하고 싶은 것이 합병 커밋을 제거하는 것 뿐이라면 (2) 그것이 결코 일어나지 않은 것처럼 보이게하는 것입니다. 명령은 다음과 같습니다.

git rebase --onto <sha of 1> <sha of 2> <blue branch>

이제 보라색 가지가 파란색 커밋 로그에 전혀 없으며 두 개의 개별 가지가 다시 있습니다. 그런 다음 보라색을 독립적으로 스쿼시하고 병합 커밋없이 원하는 다른 조작을 수행 할 수 있습니다.


1
모든 답변 중에서 가장 간단하고 가장 쉬운 방법이라고 생각합니다. 감사합니다.
Roshambo

16

원하는 사항에 따라이 문제를 해결하는 방법에는 두 가지가 있습니다.

해결 방법 1 : 보라색 커밋을 제거하고 기록을 보존합니다 (롤백하려는 경우).

git revert -m 1 <SHA of merge>

-m 1 선택할 상위 라인을 지정합니다.

보라색 커밋은 여전히 ​​역사에 있지만 되돌 렸으므로 해당 커밋의 코드는 볼 수 없습니다.


해결 방법 2 : 퍼플 커밋을 완전히 제거 (리포지토리가 공유되는 경우 중단 변경)

git rebase -i <SHA before branching out>

퍼플 커밋에 해당하는 삭제 (줄 제거).

병합 후 커밋이 이루어지지 않으면 덜 까다로울 것입니다. 추가 커밋은 revert/rebase.


이것은 옳지 않은 것 같습니다. 원래 포스터가 처음에 보라색 커밋으로 무엇을하고 싶었는지 말하기 어렵다는 사실을 제쳐두고, 병합을 되 돌리면 괜찮습니다. 그러면 해당 커밋에서 변경 사항의 역 패치를 수행하고 다음과 같이 추가합니다. 또 다른 커밋은 보라색 커밋을 취소합니다. 마치 1 - 1 = 0. 그러나 보라색 커밋을 리베이스하면 다시 리베이스하지 않는 한 되 ​​돌린 패치를 남겨 둡니다. 그렇지 않은 경우 -1이력에 적용 하는 것이 아니라 0, 원하지 않는 변경 사항을 남겨 두는 것과 같습니다 .

제공된 @Cupcake는 두 개의 별도 답변이었습니다. 나는 덜 혼란스럽게 대답을 수정했습니다 : P
prem

AFAIK 이것은 OP가 요구하는 것이 아닙니다. 그는 변경 사항을 유지하고 싶지만 로그에서 소음을 제거합니다. 이를 위해 그는 커밋을 스쿼시해야하며 삭제하면 변경 사항이 제거됩니다.
thecoshman

사실, 원래 질문이 수정 된 것 같습니다. 이 답변은 OP 문제가 아닙니다.
prem
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.