Отмена git rebase


кто-нибудь знает, как легко отменить git rebase?

единственный способ, который приходит на ум, это пойти на это вручную:

  • git проверка фиксации родителя в обеих ветвях
  • затем создайте временную ветвь оттуда
  • cherry-pick все коммиты вручную
  • замените ветку, в которой я перебазировал вручную созданную ветку

в моей нынешней ситуации это будет работать, потому что я могу легко точечные коммиты из обеих ветвей (один был моим материалом, другой-материалом моего коллеги).

однако мой подход поражает меня как неоптимальный и подверженный ошибкам (скажем, я только что перебазировался с 2 из моих собственных ветвей).

какие идеи?

уточнение: я говорю о перебазировании, во время которого была воспроизведена куча коммитов. И не только один.

15 2488

15 ответов:

самый простой способ-найти главный коммит ветви, как это было непосредственно перед началом перебазирования в reflog...

git reflog

и сбросить текущую ветку к нему (с обычными предостережениями о том, чтобы быть абсолютно уверенным перед сбросом с ).

предположим, что старый коммит был HEAD@{5} в журнале ref:

git reset --hard HEAD@{5}

в Windows, вы можете процитировать ссылка:

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

вы можете проверить историю кандидата старого руководителя, просто сделав git log HEAD@{5} (Windows:git log "HEAD@{5}").

если вы не отключили для каждой ветви reflogs вы должны быть в состоянии просто сделать git reflog branchname@{1} как rebase отсоединяет головку ветви перед повторным присоединением к окончательной головке. Я бы дважды проверил это, хотя, поскольку я не проверял это недавно.

по умолчанию все reflogs активируются для не-голых репозитории:

[core]
    logAllRefUpdates = true

на самом деле, rebase сохраняет вашу отправную точку в ORIG_HEAD так это обычно так:

git reset --hard ORIG_HEAD
на reset,rebase и merge все сохранить оригинал HEAD указатель на ORIG_HEAD Так что, если вы сделали любой из этих команд с перебазировать вы пытаетесь отменить то вам придется использовать reflog.

Чарльз работает, но вы можете сделать это:

git rebase --abort

чтобы очистить после reset.

в противном случае вы можете получить сообщение:"Interactive rebase already started".

сброс ветви к оборванному объекту фиксации ее старого наконечника, конечно, является лучшим решением, потому что он восстанавливает предыдущее состояние без каких-либо усилий. Но если вы случайно потеряли эти коммиты (F. ex. поскольку вы тем временем собирали мусор в своем репозитории, или это свежий клон), вы всегда можете снова перебазировать ветку. Ключом к этому является --onto переключатель.

допустим, у вас была тематическая ветка с творческим названием topic, что вы разветвились master когда верхушка master был 0deadbeef commit. В какой-то момент, находясь на topic ветку, сделал git rebase master. Теперь вы хотите, чтобы отменить это. Вот как:

git rebase --onto 0deadbeef master topic

это займет все коммиты на topic, не на master и воспроизвести их на вершине 0deadbeef.

С --onto, вы можете изменить свою историю в значительной степени каких бы то ни было форме.

получать удовольствие. : -)

Я на самом деле поставил тег резервного копирования на ветку, прежде чем делать какие-либо нетривиальные операции (большинство перебазировок тривиальны, но я бы сделал это, если бы это выглядело сложным).

тогда восстановление так же просто, как git reset --hard BACKUP.

в случае вы подтолкнули свою ветку к удаленному репозиторию (обычно это origin) , а затем вы сделали успешную перебазировку (без слияния) (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

в случае, если вы не закончили перебазирование и в середине его, следующие работы:

git rebase --abort

Я удивлен, что никто не упомянул еще здесь. Перебазировать листья старого государства, как ORIG_HEAD, Так что вы можете отменить последнее перемещение с помощью команды:

git reset --hard ORIG_HEAD

используя 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

для нескольких коммитов помните, что любой коммит ссылается на всю историю, ведущую к этому коммиту. Поэтому в ответе Чарльза прочитайте "старый коммит "как"самый Новый из старых коммитов". Если вы сбросите эту фиксацию, то вся история, ведущая к этой фиксации, появится снова. Это должно делать то, что вы хотите.

следуя решению @Allan и @Zearin, я хотел бы просто сделать комментарий, но мне не хватает репутации, поэтому я использовал следующую команду:

вместо git rebase -i --abort (обратите внимание на ) Я должен был просто сделать git rebase --abort (без the ).

используя как -i и --abort в то же время вызывает Git, чтобы показать мне список использования/параметры.

Итак, мой предыдущий и текущий статус филиала с это решение:

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

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

если вы успешно перебазировались на удаленную ветку и не можете git rebase --abort вы все еще можете сделать некоторые уловки, чтобы сохранить свою работу и не заставили толкает. Предположим, что ваша текущая ветвь, которая была перебазирована по ошибке, называется your-branch и отслеживая origin/your-branch

  • git branch -m your-branch-rebased # переименовать текущую ветку
  • git checkout origin/your-branch # checkout, чтобы последнее состояние, которое, как известно, происхождения
  • 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

допустим, я перебазирую master в свою ветку функций, и я получаю 30 новых коммитов, которые что-то нарушают. Я обнаружил, что часто проще всего просто удалить плохие коммиты.

git rebase -i HEAD~31

интерактивная перебаза для последних 31 коммитов (это не повредит, если вы выберете слишком много).

просто возьмите коммиты, от которых вы хотите избавиться, и отметьте их "d" вместо "pick". Теперь коммиты удаляются эффективно, отменяя перебазирование (если вы удаляете только коммиты, которые вы просто получил при перебазировании).

Если вы что-то испортите в git rebase, например git rebase --abort, пока у вас есть несохраненные файлы, они будут потеряны и git reflog не поможет. Это случилось со мной, и вам нужно будет думать вне коробки здесь. Если Вам повезет, как мне и использовать IntelliJ Webstorm, то вы можете right-click->local history и может вернуться к предыдущему состоянию вашего файла/папки независимо от того, какие ошибки вы сделали с версиями программного обеспечения. Всегда хорошо иметь еще один безотказный ход.

для отмены можно ввести следующую команду:

git -c core.quotepath=false rebase --abort