etc./StackOverFlow

git rebase 실행 취소

청렴결백한 만능 재주꾼 2021. 10. 1. 03:21
반응형

질문자 :webmat


git rebase를 쉽게 취소하는 방법을 아는 사람이 있습니까?

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

  • git checkout 두 브랜치에 부모 커밋
  • 그런 다음 거기에서 임시 분기를 만듭니다.
  • 모든 커밋을 손으로 체리 선택
  • 내가 리베이스한 브랜치를 수동으로 생성한 브랜치로 바꿉니다.

내 현재 상황에서는 두 가지 모두에서 커밋을 쉽게 찾을 수 있기 때문에 이것이 작동할 것입니다(하나는 내 항목이고 다른 하나는 내 동료의 항목임).

그러나 내 접근 방식은 차선책이고 오류가 발생하기 쉬운 것 같습니다(2개의 자체 분기로 다시 기반을 두었다고 가정해 보겠습니다).

어떤 아이디어?

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



가장 쉬운 방법은 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}" )를 수행하여 후보 이전 헤드의 기록을 확인할 수 있습니다.

분기별 reflogs를 비활성화하지 않은 경우 rebase가 최종 헤드에 다시 연결하기 전에 분기 헤드를 분리 git reflog branchname@{1} 최근에 확인하지 않았기 때문에 다시 확인하겠습니다.

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

 [core] logAllRefUpdates = true

CB Bailey

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

 git reset --hard ORIG_HEAD

그러나 reset , rebasemerge 모두 원래 HEAD 포인터를 ORIG_HEAD 저장하므로 rebase 이후에 이러한 명령을 수행한 경우 실행 취소하려는 경우 reflog를 사용해야 합니다.


Pat Notz

Charles의 대답 은 효과가 있지만 다음과 같이 할 수 있습니다.

 git rebase --abort

reset 후 정리합니다.

Interactive rebase already started "라는 메시지가 표시될 수 있습니다.


Allan

이전 팁의 매달린 커밋 개체로 분기를 재설정하는 것이 물론 최선의 솔루션입니다. 노력을 들이지 않고 이전 상태를 복원하기 때문입니다. 그러나 그 커밋을 잃어버린 경우(예: 그 동안 저장소를 가비지 수집했기 때문에 또는 이것이 새로운 복제본인 경우) 언제든지 분기를 다시 베이스화할 수 있습니다. 이것의 핵심은 --onto 스위치입니다.

topic 이라는 주제 분기가 있다고 가정해 보겠습니다. 이 분기 master 의 끝이 0deadbeef 커밋일 master 분기했습니다. topic 브랜치에 있는 동안 git rebase master . 이제 이 작업을 취소하려고 합니다. 방법은 다음과 같습니다.

 git rebase --onto 0deadbeef master topic

master 없는 topic 에 대한 모든 커밋을 가져 0deadbeef 위에서 재생합니다.

--onto 를 사용 하면 히스토리 를 거의 모든 형태 로 재정렬할 수 있습니다 .

즐거운 시간 보내세요. :-)


Aristotle Pagaltzis

분기를 원격 저장소 (일반적으로 원본)로 푸시한 다음 병합 없이 성공적으로 리베이스를 수행한 경우( 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

Maksym

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

그런 다음 복원은 git reset --hard BACKUP 만큼 쉽습니다.


Alex Gontmakher

git reset --hard origin/{branchName}

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


Damodar P

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

Kris

여러 커밋의 경우 모든 커밋은 해당 커밋까지 이어지는 모든 기록을 참조한다는 점을 기억하십시오. 따라서 Charles의 답변에서 "이전 커밋"을 "최신 커밋"으로 읽으십시오. 해당 커밋으로 재설정하면 해당 커밋까지 이어지는 모든 기록이 다시 나타납니다. 이것은 당신이 원하는 것을해야합니다.


Greg Hewgill

@Allan 및 @Zearin의 솔루션에 따라 간단히 댓글을 달 수 있으면 좋겠지만 평판이 충분하지 않으므로 다음 명령을 사용했습니다.

대신 일을 git rebase -i --abort 합니다 (-i 참고) 단순히해야 할 일을했을 git rebase --abort 합니다 (-i없이).

-i--abort 를 동시에 사용하면 Git에서 사용/옵션 목록을 표시합니다.

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

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

Matheus Felipe

원격 브랜치에 대해 성공적으로 리베이스하고 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와 비교하고 git log your-branch 에서 누락된 커밋을 정의 your-branch
  • your-branch-rebased 모든 커밋에 대해 git cherry-pick COMMIT_HASH
  • 변경 사항을 푸시하십시오. 두 지역의 지점과 연관되어 있음을 유의하십시오 remote/your-branch 및 만 밀어해야 your-branch

Sergey P. aka azure

하드 리셋을 하고 싶지 않다면 ...

reflog에서 커밋을 체크아웃한 다음 새 분기로 저장할 수 있습니다.

 git reflog

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

 git checkout HEAD@{57}

분기/커밋을 검토하고 올바른 경우 이 HEAD를 사용하여 새 분기를 만듭니다.

 git checkout -b new_branch_name

Andrew

마스터를 기능 브랜치로 리베이스하고 무언가를 깨뜨리는 30개의 새로운 커밋을 얻었다고 가정해 보겠습니다. 나는 종종 나쁜 커밋을 제거하는 것이 가장 쉽다는 것을 발견했습니다.

 git rebase -i HEAD~31

마지막 31개 커밋에 대한 대화형 리베이스(너무 많이 선택해도 문제가 되지 않음).

제거하려는 커밋을 "선택" 대신 "d"로 표시하기만 하면 됩니다. 이제 커밋이 효과적으로 삭제되어 리베이스를 취소합니다(리베이스할 때 방금 얻은 커밋만 제거하는 경우).


Hardev

지점에 있는 경우 다음을 사용할 수 있습니다.

 git reset --hard @{1}

HEAD에 대한 참조 로그( git reflog 얻음)뿐만 아니라 각 분기에 대한 git reflog <branch> 얻음). master 에 있다면 git reflog master 는 해당 분기에 대한 모든 변경 사항을 나열합니다. master@{1} , master@{2} 등으로 변경 사항을 참조할 수 있습니다.

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

@{1} 간단하다 현재 지점에 대한 바로 가기 가 동일 그래서, master@{1} 당신에있는 경우 master .

git reset --hard ORIG_HEAD 는 대화형 rebase git reset 을 사용한 경우 작동하지 않습니다.


devconsole

자동화가 가능해야 한다는 사실에도 불구하고(적어도 대부분) 이러한 답변 중 어느 것도 완전 자동이 아니라는 것이 끝도 없이 짜증이 납니다. 이 문제를 해결하기 위해 별칭 집합을 만들었습니다.

 # Useful commands ################# # Undo the last rebase undo-rebase = "! f() { : git reset ; PREV_COMMIT=`git x-rev-before-rebase` && git reset --merge \"$PREV_COMMIT\" \"$@\";}; f" # See what changed since the last rebase rdiff = "!f() { : git diff ; git diff `git x-rev-before-rebase` "$@";}; f" # Helpers ######## # Get the revision before the last rebase started x-rev-before-rebase = !git reflog --skip=1 -1 \"`git x-start-of-rebase`\" --format=\"%gD\" # Get the revision that started the rebase x-start-of-rebase = reflog --grep-reflog '^rebase (start)' -1 --format="%gD"

임의의 수의 rebase를 아주 쉽게 되돌릴 수 있도록 이것을 조정할 수 있어야 합니다(args를 저글링하는 것이 가장 까다로운 부분입니다). 이는 많은 rebase를 연속적으로 빠르게 수행하고 도중에 무언가를 엉망으로 만들 때 유용할 수 있습니다.

주의 사항

커밋 메시지가 "rebase(start)"로 시작하는 경우 혼동될 것입니다(이 작업을 수행하지 마십시오). 정규식에 대해 다음과 같이 일치시켜 상황을 개선하기 위해 정규식을 보다 탄력적으로 만들 수 있습니다.

 --grep-reflog "^rebase (start): checkout "

경고: 테스트되지 않음(정규식은 조정이 필요할 수 있음)

내가 이것을하지 않은 이유는 리베이스가 항상 체크 아웃으로 시작된다는 100 %가 아니기 때문입니다. 누구든지 이것을 확인할 수 있습니까?

[함수의 시작 부분에 있는 null( : ) 명령어가 궁금하다면 별칭에 대한 bash 완성을 설정하는 방법입니다]


DylanYoung

하드 리셋을 수행할 필요가 없는 또 다른 방법은 원하는 시작점으로 새 분기를 만드는 것입니다.

다른 솔루션과 마찬가지로 reflog를 사용하여 올바른 시작점을 찾습니다.

 git reflog

(자세한 내용은 여기에서 git log -g 를 사용할 수도 있습니다.)

그런 다음 커밋 SHA(예: e86a52b851e )에 대한 참조를 확인합니다.

마지막으로 git 분기 명령을 사용합니다.

 git branch recover-branch e86a52b851e

참조: https://git-scm.com/book/en/v2/Git-Internals-Maintenance-and-Data-Recovery#_data_recovery


GuyStalks

내가 일반적으로하는 일은 git reset #commit_hash

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

그런 다음 git pull

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

이제 이 브랜치에서 커밋을 선택하면 됩니다.


mrigendra

재설정 및 reflog로 모든 제안을 시도했지만 성공하지 못했습니다. IntelliJ의 로컬 기록 복원으로 파일 손실 문제 해결


user3638751

커밋되지 않은 파일이 있는 동안 git rebase --abort 내에서 무언가를 엉망으로 git reflog 가 도움이 되지 않습니다. 이것은 나에게 일어난 일이며 여기에서 상자 밖에서 생각해야합니다. 나처럼 운이 좋고 IntelliJ Webstorm을 사용하는 경우 버전 관리 소프트웨어에서 어떤 실수를 했는지에 관계없이 right-click->local history 항상 다른 안전 장치를 실행하는 것이 좋습니다.


Steve K

출처 : 여기를 클릭하세요


출처 : http:www.stackoverflow.com/questions/134882/undoing-a-git-rebase

반응형