Отмена git rebase
кто-нибудь знает, как легко отменить git rebase?
единственный способ, который приходит на ум, это пойти на это вручную:
- git проверка фиксации родителя в обеих ветвях
- затем создайте временную ветвь оттуда
- cherry-pick все коммиты вручную
- замените ветку, в которой я перебазировал вручную созданную ветку
в моей нынешней ситуации это будет работать, потому что я могу легко точечные коммиты из обеих ветвей (один был моим материалом, другой-материалом моего коллеги).
однако мой подход поражает меня как неоптимальный и подверженный ошибкам (скажем, я только что перебазировался с 2 из моих собственных ветвей).
какие идеи?
уточнение: я говорю о перебазировании, во время которого была воспроизведена куча коммитов. И не только один.
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
и может вернуться к предыдущему состоянию вашего файла/папки независимо от того, какие ошибки вы сделали с версиями программного обеспечения. Всегда хорошо иметь еще один безотказный ход.