Кто-нибудь знает, как легко отменить git rebase?
Единственный способ, который приходит на ум, - это пойти вручную:
В моей нынешней ситуации это сработает, потому что я могу легко обнаружить фиксации из обеих ветвей (один был моим материалом, другой - моим коллегой).
Однако мой подход поражает меня как неоптимальную и подверженную ошибкам (скажем, я только что переделал две мои собственные ветки).
Любые идеи?
Уточнение: я говорю о переустановке, в ходе которой была переиграна куча коммитов. Не только один.
Самый простой способ - найти головную фиксацию ветки, как это было непосредственно перед началом перезагрузки в reflog..
git reflog
и reset текущую ветвь к ней (с обычными предостережениями о том, чтобы быть абсолютно уверенными перед реселлированием с опцией --hard
).
Предположим, что старый коммит был HEAD@{5}
в журнале ref:
git reset --hard HEAD@{5}
В Windows вам может потребоваться указать ссылку:
git reset --hard "HEAD@{5}"
Вы можете проверить историю старого кандидата, выполнив git log HEAD@{5}
(Windows: git log "HEAD@{5}"
).
Если вы не отключили данные для каждого ветки, вы должны просто сделать git reflog branchname@{1}
, так как rebase отделяет ветвь ветки до ее присоединения к финальной голове. Я бы дважды проверял это, хотя, поскольку я не проверял это недавно.
По умолчанию все рефлоги активируются для не-голых репозиториев:
[core]
logAllRefUpdates = true
git log -g
(подсказка Скотта Чакона из progit.org/book ).
git rebase -i --abort
. Одного вышесказанного недостаточно.
Фактически, rebase сохраняет начальную точку до ORIG_HEAD
, поэтому это обычно так же просто, как:
git reset --hard ORIG_HEAD
Тем не менее, reset
, rebase
и merge
все сохраняют ваш исходный указатель HEAD
в ORIG_HEAD
, поэтому, если вы выполнили какие-либо из этих команд с момента переустановки, которую вы пытаетесь отменить, вам придется использовать reflog.
git reset
как вы предлагаете, теперь git log
показывает некоторые все еще перебазированные коммит-сообщения и полностью пропускает другие.
Ответ Charles работает, но вы можете сделать это:
git rebase --abort
для очистки после reset
.
В противном случае вы можете получить сообщение "Interactive rebase already started
".
git rebase --abort
в (возможно, в зависимости от вашей версии git).
Сброс ветки к обмотанному объекту фиксации его старого наконечника - это, конечно, лучшее решение, потому что оно восстанавливает предыдущее состояние, не затрачивая никаких усилий. Но если вы потеряли эти коммиты (f.ex., потому что вы мусор - собрал ваш репозиторий тем временем, или это новый клон), вы всегда можете снова переустановить ветвь. Ключом к этому является переключатель --onto
.
Допустим, у вас была ветвь темы, образно названная topic
, что вы отделили master
, когда кончиком master
был 0deadbeef
commit. В какой-то момент на ветке topic
вы сделали git rebase master
. Теперь вы хотите отменить это. Вот как:
git rebase --onto 0deadbeef master topic
Это займет все фиксации на topic
, которые arent на master
, и воспроизведите их поверх 0deadbeef
.
С --onto
вы можете перестроить свою историю практически в любой форме.
Получайте удовольствие.: -)
Я фактически помещаю тэг резервной копии в ветку, прежде чем выполнять какую-либо нетривиальную операцию (большинство перестановок тривиально, но я бы сделал это, если он выглядит где-то сложным).
Затем восстановление так же просто, как git reset --hard BACKUP
.
Я удивлен, что никто еще не упомянул об этом здесь. Rebase оставляет прежнее состояние как ORIG_HEAD
, поэтому вы можете вернуть последнюю rebase, запустив:
git reset --hard ORIG_HEAD
В случае вы переместили вашу ветку в удаленный репозиторий (обычно это происхождение), а затем вы выполнили успешную переадресацию (без слияния) (git rebase --abort
дает "Нет переадресации" ) вы можете легко reset отрасль, используя
Команда:
git reset - неправильное начало/{название ветки}
Пример:
$ ~/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
Если вы не закончили rebase и посередине, выполните следующие действия:
git rebase --abort
Использование reflog
не помогло мне.
Что сработало для меня, было похоже на описанный здесь. Откройте файл .git/logs/refs, названный в честь ветки, которая была переустановлена, и найдите строку, содержащую "rebase finsihed", что-то вроде:
5fce6b51 88552c8f Kris Leech <[email protected]> 1329744625 +0000 rebase finished: refs/heads/integrate onto 9e460878
Оформить вторую фиксацию, указанную в строке.
git checkout 88552c8f
Как только это подтвердилось, мои потерянные изменения я разветкил и вздохнул с облегчением.
git log
git checkout -b lost_changes
Для нескольких коммитов помните, что любая фиксация ссылается на всю историю, ведущую к этой фиксации. Поэтому в ответе Чарльза читайте "старый фиксат" как "самый новый из старых коммитов". Если вы reset, чтобы зафиксировать это, тогда вся история, ведущая к этой фиксации, снова появится. Это должно делать то, что вы хотите.
Следуя решению @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)
$
Если вы успешно переустановили удаленный филиал и не можете 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
Просто:
git rebase --abort
?
Скажем, я переустанавливаю мастера на свою ветку функций, и я получаю 30 новых коммитов, которые что-то ломают. Я обнаружил, что часто проще всего просто удалить плохие коммиты.
git rebase -i HEAD~31
Интерактивная перестановка для последних 31 фиксации (это не больно, если вы слишком много выбираете).
Просто возьмите коммиты, от которых вы хотите избавиться, и пометьте их "d" вместо "pick". Теперь коммиты удаляются, эффективно уничтожая rebase (если вы удаляете только те коммиты, которые вы только что получили при перезагрузке).
Если вы находитесь на ветке, вы можете использовать:
git reset --hard @{1}
Существует не только справочный журнал для HEAD (полученный с помощью git reflog
), но также есть и reflogs для каждой ветки (полученный с помощью git reflog <branch>
). Таким образом, если вы используете master
то git reflog master
выведет список всех изменений в этой ветке. Вы можете сослаться на эти изменения по master@{1}
, master@{2}
и т.д.
git rebase
обычно меняет HEAD несколько раз, но текущая ветка будет обновляться только один раз.
@{1}
- это просто ярлык для текущей ветки, поэтому он равен master@{1}
если вы используете master
.
git reset --hard ORIG_HEAD
не будет работать, если вы использовали git reset
во время интерактивного rebase
.
Если вы повредите что-то в рамках git rebase --abort
git, например git rebase --abort
, в то время как у вас есть незафиксированные файлы, они будут потеряны, а git reflog
не поможет. Это случилось со мной, и вам нужно будет подумать нестандартно. Если вам повезло, как я, и используйте IntelliJ Webstorm, вы можете щелкнуть right-click->local history
кнопкой мыши по right-click->local history
и вернуться к предыдущему состоянию вашего файла/папок независимо от того, какие ошибки вы совершили с помощью программного обеспечения для управления версиями. Всегда хорошо иметь еще один отказоустойчивый ход.
git rebase --abort
прекращает активную перебазироваться, не отменить перебазирования. Кроме того, использование двух VCS одновременно является плохой идеей. Это хорошая функция в программном обеспечении Jetbrains, но вы не должны использовать оба. Лучше просто изучать Git, особенно когда отвечаете на вопросы о переполнении стека, касающиеся Git.
Чтобы отменить, вы можете ввести следующую команду:
git -c core.quotepath=false rebase --abort