Отмена git rebase
кто-нибудь знает, как легко отменить git rebase?
единственный способ, который приходит на ум, - это сделать это вручную:
- git checkout фиксация родителя для обеих ветвей
- затем создайте ветку temp оттуда
- cherry-pick все коммиты вручную
- замените ветку, в которой я перебазировался вручную созданной веткой
в моей текущей ситуации это сработает, потому что я могу легко spot commits из обеих ветвей (один был моим материалом, другой-материалом моего коллеги).
однако мой подход поражает меня как неоптимальный и подверженный ошибкам (скажем, я только что перезагрузился с 2 из моих собственных ветвей).
какие идеи?
уточнение: я говорю о ребазе, во время которого была воспроизведена куча коммитов. Не только один.
15 ответов
самый простой способ найти голову совершить ветви, как это было непосредственно перед начал перебазироваться в reflog...
git reflog
и сбросить текущую ветку на нее (с обычными предостережениями о том, чтобы быть абсолютно уверенным перед сбросом с ).
предположим, что старый commit был HEAD@{5} в журнале Реф:
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} как перебазировать отсоединяется руководитель отделения перед установкой к окончательной голове. Я бы дважды проверил это, хотя, поскольку я не проверял это в последнее время.
по умолчанию все 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.бывший. поскольку вы тем временем собрали свой репозиторий, или это свежий клон), вы всегда можете снова перебазировать ветку. Ключ к этому ---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 дает "нет rebase в процессе") вы можете легко сброс филиала используя
команда:
сброс git --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
Я удивлен, что никто не упомянул еще здесь. Rebase покидает старое состояние как 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 (без на -Я).
используя как -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# проверка на последнее состояние, которое известно origin 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
Interactive rebase для последних 31 коммитов (это не больно, если вы выбираете слишком много).
просто возьмите коммиты, от которых вы хотите избавиться, и отметьте их "d" вместо "pick". Теперь коммиты удаляются эффективно отмена перебазировать (если удалить только коммиты вы просто когда перебазирования).
Если вы что-то испортите в git rebase, например git rebase --abort, в то время как у вас есть незафиксированные файлы, они будут потеряны и git reflog не поможет. Это случилось со мной, и вам нужно будет подумать вне коробки здесь. Если Вам повезет, как мне, и использовать IntelliJ Webstorm, то вы можете right-click->local history и может вернуться к предыдущему состоянию вашего файла / папок независимо от того, какие ошибки вы сделали с версиями программного обеспечения. Всегда хорошо иметь другой failsafe бег.