git rebase 실행 취소


3178

누구나 git rebase를 쉽게 취소하는 방법을 알고 있습니까?

마음에 드는 유일한 방법은 수동으로 진행하는 것입니다.

  • 커밋 부모를 두 가지 모두에 대해 git checkout
  • 그런 다음 거기에서 임시 지점을 만듭니다.
  • 손으로 모든 커밋을 체리 픽
  • 수동으로 만든 브랜치로 리베이스 한 브랜치를 교체하십시오.

현재 상황에서 이것은 두 가지에서 커밋을 쉽게 찾을 수 있기 때문에 작동합니다 (하나는 내 물건이고 다른 하나는 동료의 물건이었습니다).

그러나 내 접근 방식은 차선책이며 오류가 발생하기 쉬운 것으로 나타났습니다 (방금 자신의 지점 중 2 개로 리베이스했다고 가정 해 봅시다).

어떤 아이디어?

설명 : 나는 많은 커밋이 재생되는 rebase에 대해 이야기하고 있습니다. 하나만이 아닙니다.


6
또한 리베이스 중에 커밋을 제외하거나 스쿼시 할 수 있습니다. 이러한 변경 사항은 원래 노드에 대한 포인터가 없거나 참조 로그를 거르지 않으면 되돌릴 수 없으므로 체리 픽킹이 작동하지 않습니다.
ANeves

답변:


4337

가장 쉬운 방법은 reflog 에서 rebase가 시작되기 직전의 지점의 헤드 커밋을 찾는 것입니다 ...

git reflog

현재 분기를 분기로 재설정합니다 ( --hard옵션으로 재설정하기 전에 절대적으로 확인해야한다는 일반적인주의 사항 ).

이전 커밋이 HEAD@{5}참조 로그에 있다고 가정합니다 .

git reset --hard HEAD@{5}

Windows에서는 참조를 인용해야 할 수도 있습니다.

git reset --hard "HEAD@{5}"

git log HEAD@{5}( Windows :)를 수행하여 후보 이전 헤드의 히스토리를 확인할 수 있습니다 git log "HEAD@{5}".

브랜치 리플 로그별로 비활성화하지 않은 경우 git reflog branchname@{1}최종 헤드에 다시 연결하기 전에 리베이스가 브랜치 헤드를 분리 하기 만하면 됩니다. 최근에 확인하지 않았지만 이것을 다시 확인하겠습니다.

기본적으로 모든 reflog는 베어 리포지토리에 대해 활성화됩니다.

[core]
    logAllRefUpdates = true

114
Git reflog는 훌륭합니다. git log -g(Scott Chacon의 progit.org/book 의 팁)을 사용하면 더 나은 형식의 출력을 얻을 수 있습니다 .
karmi

60
@Zach : git rebase --abort( -i와 의미가 없습니다 --abort)는 충돌이 발생했거나 대화식이거나 둘 다 때문에 완료되지 않은 리베이스를 포기하는 것입니다. 성공적인 리베이스를 취소하는 것이 문제가 아닙니다. 어떤 상황에 있는지 rebase --abort또는 사용 reset --hard하느냐에 따라 두 가지를 모두 수행 할 필요는 없습니다.
CB Bailey

311
만일을 대비하여 먼저 백업하십시오 : git tag BACKUP. 문제가 발생하면 다시 돌아올 수 있습니다.git reset --hard BACKUP
kolypto

6
많은 커밋을 한 경우 찾고있는 HEAD @ {#}이 (가)와 commit:반대로 시작 됩니다 rebase:. 분명히 들리지만 조금 혼란 스러웠습니다.
Warpling

4
실수로 리베이스 한 후 파티에 참여 : D. git reset --hard ORIG_HEAD실수로 리베이스 한 직후에도 속임수가 되지 않습니까?
quaylar

1485

실제로 rebase는 시작점을 저장 ORIG_HEAD하므로 일반적으로 다음과 같이 간단합니다.

git reset --hard ORIG_HEAD

그러나 reset, rebasemerge모든 원래의 저장 HEAD에 포인터 ORIG_HEAD그래서, 당신은 당신이 reflog를 사용해야합니다 다음 취소하려는 REBASE 때문에 이러한 명령 중 하나를 수행 한 경우.


34
ORIG_HEAD더 이상 유용하지 않은 경우 분기 포인터의 n 번째 이전 위치 인 branchName@{n}구문 을 사용할 수도 있습니다 n. 예를 들어 featureA지점에 지점을 리베이스 master하지만 리베이스의 결과가 마음에 들지 않으면 git reset --hard featureA@{1}지점을 리베이스하기 전의 위치로 다시 재설정하기 만하면 됩니다. 공식 Git 문서 에서 branch @ {n} 구문에 대한 자세한 내용을 확인할 수 있습니다 .

15
이것이 가장 쉬운 방법입니다. git rebase --abort그래도 후속 조치를 취하십시오.
Seph

1
@DaBlick은 충돌없이 완전히 성공적으로 리베이스 된 후 나에게 잘 작동했습니다 git 2.17.0.
dvlsg

4
그리고 보완 해 드리겠습니다. git reset --hard ORIG_HEAD반복해서 사용하여 계속해서 롤백 할 수 있습니다. 예를 들어 A--rebase to --- B --- rebase to --- C라면 이제 C입니다. 두 번 사용하여 A로 돌아갈 수 있습니다git reset --hard ORIG_HEAD
CalvinChe

5
@Seph 왜 당신이 다음을 추천하는지 설명해 주실 수 있습니까 git rebase --abort?
UpTheCreek

386

Charles의 답변은 효과가 있지만 이렇게 할 수 있습니다.

git rebase --abort

청소 후 reset.

그렇지 않으면 " Interactive rebase already started" 메시지가 표시 될 수 있습니다 .


4
이 메시지가 프롬프트에서 "| REBASE"부분을 제거했습니다. +1
Wouter Thielen 5

62
그것은 질문이 아니 었습니다. 이 질문은 완성 된 리베이스를 취소하는 방법을 묻습니다.
Arunav Sanyal

2
Charles의 답변에 대한 답변이어야합니다. 질문에 대한 답변이 아니기 때문입니다.
Murmel

흠, 나는 그렇게 할 필요가 없었습니다.
Viktor Seč

1
나를 위해 일한 유일한 사람!
Alexandre Picard

90

이전 팁의 댕글 링 커밋 객체로 분기를 재설정하는 것은 노력을 기울이지 않고 이전 상태를 복원하기 때문에 물론 최상의 솔루션입니다. 그러나 커밋을 잃어 버린 경우 (f.ex. 저장소를 가비지 수집했거나 새로운 복제본이기 때문에) 언제든지 브랜치를 다시 리베이스 할 수 있습니다. 이것의 열쇠는 --onto스위치입니다.

하자 당신이 상상이라는 주제 분기를 가지고 말할 topic오프 분기 것을 master끝 때 master(가)이었다 0deadbeef커밋합니다. 지점에있는 동안 어느 시점 topic에서 했어요 git rebase master. 이제이 작업을 취소하고 싶습니다. 방법은 다음과 같습니다.

git rebase --onto 0deadbeef master topic

이것은 켜져 topic있지 않은 모든 커밋을 수행 하고 master위에서 재생합니다 0deadbeef.

을 사용하면 --onto역사를 거의 모든 형태 로 재 배열 할 수 있습니다 .

즐기세요 :-)


3
유연성으로 인해 이것이 최선의 선택이라고 생각합니다. b1을 마스터에서 분기 한 다음 b1을 새 분기 b2로 리베이스 한 다음 다시 마스터를 기반으로 b1을 되돌리려 고했습니다. 나는 단지 자식을 좋아한다-고마워!
ripper234

2
이것이 가장 좋은 옵션입니다! 현재 지점에 대한 모든 변경 사항을 유지하고 원하지 않는 항목을 모두 제거했습니다!
Alicia Tang

나는의 조합으로 그런 말 것 --onto하고 -i는 거의 어떤 모양든지로 역사를 다시 정렬 할 수 있습니다. gitk (또는 mac의 경우 gitx)를 사용하여 만드는 모양을보십시오. :-).
rjmunro

69

나는 사소한 작업을 수행하기 전에 실제로 지점에 백업 태그를 넣었습니다 (대부분의 리베이스는 사소한 것이지만 복잡한 곳이면 그렇게 할 것입니다).

그런 다음 복원이 쉽습니다 git reset --hard BACKUP.


2
나도 이걸한다 BACK diff..HEAD를 git diff로 변경하여 원하는 것을 변경했는지 확인하는 것도 유용합니다.
Paul Bone

5
예전에도 그렇게했지만 Reflog에 익숙해 져서 더 이상 필요하다고 느끼지 않습니다. 거절은 기본적으로 HEAD를 변경할 때마다 귀하를 대신하여 수행됩니다.
Pete Hodgson

4
글쎄, 나는 reflog에서 올바른 아이템을 찾는 것이 때로는 전혀 재미 있지 않기 때문에 의미있는 이름을 선호합니다.
Alex Gontmakher

12
실제로 백업 브랜치를 만들 필요조차 없습니다. 간단히 branchName@{n}구문을 사용할 수 있습니다 . 여기는 n브랜치 포인터의 n 번째 이전 위치입니다. 예를 들어 featureA지점에 지점을 리베이스 master하지만 리베이스의 결과가 마음에 들지 않으면 git reset --hard featureA@{1}지점을 리베이스하기 전의 위치로 다시 재설정하기 만하면 됩니다. 공식 Git 문서branch@{n} 에서 구문에 대한 자세한 내용은 개정판을 참조하십시오 .

2
실제로 Pat Notz의 답변HEAD 에 따르면 분기 의 원본 은에 임시 저장됩니다 ORIG_HEAD. 위의 구문을 사용할 필요조차 없습니다 . 그러나 백업 브랜치 레이블을 사용하는 기술도 작동합니다. 더 많은 단계 일뿐입니다.

68

경우 당신은 원격 저장소에 지사를 밀어했다 ((보통의 기원) 다음은 (병합 없음) succesfull REBASE를 한 적이 git rebase --abort쉽게 할 수 있습니다 "아니이 진행 리베이스"제공) 리셋 지점 명령을 사용하여

git reset --hard origin / {branchName}

예:

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is ahead of 'origin/{branchName}' by 135 commits.
  (use "git push" to publish your local commits)

nothing to commit, working directory clean

$ ~/work/projects/{ProjectName} $ git reset --hard origin/{branchName}
HEAD is now at 6df5719 "Commit message".

$ ~/work/projects/{ProjectName} $ git status
On branch {branchName}
Your branch is up-to-date with 'origin/{branchName}.

nothing to commit, working directory clean

그게 정답입니다. 리베이스 이전의 리베이스 및 커밋은 동일한 커밋 ID를 가졌으며 HEAD {1} (으)로 돌아 가면 리베이스가 되돌려지지 않습니다!
Bill Kotsias

23

사용 reflog하지 못했습니다.

나를 위해 일한 것은 여기에 설명 된 것과 유사합니다 . 리베이스 된 브랜치의 이름을 딴 .git / logs / refs에서 파일을 열고 "rebase finsihed"를 포함하는 라인을 찾으십시오.

5fce6b51 88552c8f Kris Leech <me@example.com> 1329744625 +0000  rebase finished: refs/heads/integrate onto 9e460878

행에 나열된 두 번째 커밋을 확인하십시오.

git checkout 88552c8f

이것이 내가 잃어버린 변화를 포함하고 있음을 확인하면 나는 분기하고 안도의 한숨을 내 쉬었다.

git log
git checkout -b lost_changes


3
우와-그 연결에서 "한 가지 경고가 있습니다. 지점의 역사를 잃어 버렸지 만이 경우에는 중요하지 않습니다. 변경 사항을 검색 한 것이 기뻤습니다." ?
ruffin

16

여러 커밋의 경우 커밋은 해당 커밋으로 이어지는 모든 기록을 참조합니다. 찰스의 대답에서 "오래된 커밋"을 "가장 오래된 커밋"으로 읽습니다. 해당 커밋으로 재설정하면 해당 커밋으로 이어지는 모든 기록이 다시 나타납니다. 이것은 당신이 원하는 것을해야합니다.


11

@Allan과 @Zearin의 해결책에 따라 간단히 의견을 말할 수는 있지만 평판이 충분하지 않기 때문에 다음 명령을 사용했습니다.

대신 일을 git rebase -i --abort (음 -i를 ) 단순히해야했다 git rebase --abort( 없이 -i ).

모두를 사용 -i하고 --abort힘내을 동시에 발생하는 것은 나에게 사용 / 옵션 목록을 표시합니다.

따라서이 솔루션의 이전 및 현재 지점 상태는 다음과 같습니다.

matbhz@myPc /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

matbhz@myPc /my/project/environment (branch-123)
$

11

원격 지사를 성공적으로 리베이스 할 수 없어도 git rebase --abort여전히 작업을 저장하고 강제로 푸시하지 않는 몇 가지 트릭을 수행 할 수 있습니다. 실수로 리베이스 된 현재 지점이 호출 your-branch되어 추적되고 있다고 가정하십시오.origin/your-branch

  • git branch -m your-branch-rebased # 현재 지점 이름 바꾸기
  • git checkout origin/your-branch # 출처로 알려진 최신 상태로 체크 아웃
  • git checkout -b your-branch
  • 확인 git log your-branch-rebased, 비교 git log your-branch및 누락 된 커밋 정의your-branch
  • git cherry-pick COMMIT_HASH 커밋 할 때마다 your-branch-rebased
  • 변경 사항을 푸시하십시오. 두 개의 현지 지점이 연결되어 있으므로 remote/your-branch푸시해야합니다.your-branch

4

마스터를 기능 지점으로 리베이스하고 30 개의 새로운 커밋을 가져 와서 무언가를 중단한다고 가정 해 봅시다. 나는 종종 나쁜 커밋을 제거하는 것이 가장 쉬운 것을 발견했습니다.

git rebase -i HEAD~31

지난 31 개의 커밋에 대한 대화식 리베이스 (너무 많이 선택해도 아프지 않음).

제거하려는 커밋을 "pick"대신 "d"로 표시하면됩니다. 이제 커밋이 효과적으로 rebase를 취소하여 삭제됩니다 (리베이스 할 때 얻은 커밋 만 제거하면).


3

초보자 / 하드 재설정을 너무 두려워하는 사람은 reflog에서 커밋을 확인한 다음 새 분기로 저장할 수 있습니다.

git reflog

리베이스를 시작하기 직전에 커밋을 찾으십시오. 찾을 때까지 아래로 스크롤해야 할 수도 있습니다 (Enter 또는 PageDown 누르기). HEAD 번호를 기록하고 57을 교체하십시오.

git checkout HEAD@{57}

이 HEAD를 사용하여 새 분기를 작성하는 것이 좋으면 분기 / 커밋을 검토하십시오.

git checkout -b new_branch_name

2

지점에 있다면 다음을 사용할 수 있습니다.

git reset --hard @{1}

HEAD에 대한 참조 로그 ( git reflog)가 제공 될뿐만 아니라 각 분기 ()에 대한 참조 로그 도 있습니다 git reflog <branch>. 그래서, 당신이 경우 master다음 git reflog master해당 분기의 모든 변경 사항을 나열합니다. 당신은에 의한 변경을 참조 할 수 있습니다 master@{1}, master@{2}

git rebase 일반적으로 HEAD가 여러 번 변경되지만 현재 분기는 한 번만 업데이트됩니다.

@{1}단순히 현재 분기바로 가기 이므로 master@{1}on 상태 인 경우와 같습니다 master.

git reset --hard ORIG_HEADgit reset대화식 중에 사용하면 작동하지 않습니다 rebase.


1

내가 보통하는 것은 git reset #commit_hash

rebase가 효과가 없다고 생각하는 마지막 커밋에.

그때 git pull

이제 브랜치는 마스터와 정확히 일치해야하며 리베이스 된 커밋은 그 안에 없어야합니다.

이제이 지점에서 커밋을 체리 픽으로 선택할 수 있습니다.


1

나는 아무런 제안없이 재설정 및 reflog로 모든 제안을 시도했다. IntelliJ의 로컬 히스토리를 복원하면 파일 손실 문제가 해결되었습니다.


감사! 전에는 지역 기록을 사용한 적이 없지만 실수로 리베이스 된 코드를 복구 할 수있는 가장 쉬운 옵션으로 판명되었습니다. 매우 멋지지만 다소 숨겨진 기능.
매그너스 W

0

git reset --hard origin / {branchName}

rebase에 의해 수행 된 모든 로컬 변경 사항을 재설정하는 올바른 솔루션입니다.


1
하드 리셋 origin/branch하면 HEAD와 해당 지점 사이의 변경 사항이 손실 될 수 있습니다. 당신은 일반적으로 말하고 싶지 않습니다.
bluesmonk

이것이 바로 제 경우에 원하는 것입니다. 그래서 공감.
Mandar Vaze

-4

git rebase --abort커밋되지 않은 파일이있는 동안 git rebase 내에서 무언가를 엉망으로 만들면 파일이 손실되고 git reflog도움이되지 않습니다. 이것은 나에게 일어 났고 당신은 상자 밖에서 생각해야합니다. 나처럼 운이 좋으며 IntelliJ Webstorm을 사용하면 right-click->local history버전 관리 소프트웨어로 어떤 실수를했는지와 상관없이 파일 / 폴더의 이전 상태로 되돌릴 수 있습니다. 다른 안전 장치를 항상 실행하는 것이 좋습니다.


5
git rebase --abort활성 리베이스를 중단하고 리베이스를 취소 하지 않습니다 . 또한 두 개의 VCS를 동시에 사용하는 것은 좋지 않습니다. Jetbrains 소프트웨어의 멋진 기능이지만 둘 다 사용해서는 안됩니다. 특히 Git에 관한 Stack Overflow에 대한 질문에 대답 할 때 Git을 배우는 것이 좋습니다.
dudewad
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.