Отмена 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 бег.