Как я могу легко отменить git rebase?
Мои текущие идеи - только ручные подходы:
git checkout
на коммит родитель для обеих ветвей- Создайте временную ветку оттуда
git cherry-pick
все совершает вручную- заменить ветку, в которой я перебазировал ветку, созданную вручную
В моей нынешней ситуации это сработает, потому что я легко могу определить коммиты из обеих веток (одна была моей, другая - моей коллегой).
Однако мой подход кажется мне неоптимальным и подверженным ошибкам (скажем, я только что перебазировал 2 моих собственных ветки).
Пояснение : я говорю о ребазе, во время которого была воспроизведена группа коммитов. Не только один.
git
rebase
git-rebase
undo
webmat
источник
источник
Ответы:
Самый простой способ - найти главный коммит ветки, как это было непосредственно перед тем, как в reflog начался ребаз ...
и сбросить текущую ветку к нему (с обычными предостережениями о полной уверенности перед перезагрузкой с
--hard
опцией).Предположим, что старый коммит был
HEAD@{5}
в журнале ссылок:В Windows вам может понадобиться процитировать ссылку:
Вы можете проверить историю старого руководителя кандидата, просто выполнив
git log HEAD@{5}
( Windows:)git log "HEAD@{5}"
.Если вы не отключили повторные журналы для каждой ветви, вы можете просто сделать, так
git reflog branchname@{1}
как ребаз отсоединяет головку ветви, прежде чем присоединять ее к конечной головке. Я бы дважды проверил это, хотя я не проверял это недавно.По умолчанию все reflogs активируются для не пустых репозиториев:
источник
git log -g
(совет от Скотта Чакона progit.org/book ).git rebase --abort
(-i
не имеет смысла--abort
) для отказа от ребазинга, который не был завершен - либо потому, что были конфликты, либо потому, что он был интерактивным, либо и то, и другое; речь идет не об отмене успешного ребазинга, о котором идет речь. Вы должны либо использовать,rebase --abort
либо вreset --hard
зависимости от того, в какой ситуации вы оказались. Вам не нужно делать то и другое.git tag BACKUP
. Вы можете вернуться к нему, если что-то пойдет не так:git reset --hard BACKUP
commit:
перед, а неrebase:
. Звучит очевидно, но это немного смутило меня.git reset --hard ORIG_HEAD
сделать то же самое сразу после случайной перезагрузки?На самом деле, rebase сохраняет вашу отправную точку,
ORIG_HEAD
поэтому обычно это так просто:Однако
reset
,rebase
иmerge
все , кроме исходногоHEAD
указателя вORIG_HEAD
так, если вы сделали какие - либо из этих команд с Rebase вы пытаетесь отменить , то вы должны будете использовать reflog.источник
ORIG_HEAD
он больше не используется, вы также можете использоватьbranchName@{n}
синтаксис, гдеn
находится n-ая предшествующая позиция указателя ветви. Так, например, если вы перебазируетеfeatureA
ветвь на своюmaster
ветку, но вам не нравится результат перебазировки, тогда вы можете просто сделатьgit reset --hard featureA@{1}
сброс ветви обратно туда, где она была до перебазирования. Вы можете прочитать больше о синтаксисе ветки @ {n} в официальных документах Git для ревизий .git rebase --abort
хотя.git 2.17.0
.git reset --hard ORIG_HEAD
можно использовать несколько раз для отката снова и снова. Скажем, если A --- перебазировать в --- B --- перебазировать в --- C, теперь я нахожусь в C, я могу вернуться к A, используя два разаgit reset --hard ORIG_HEAD
git rebase --abort
?Ответ Чарльза работает, но вы можете сделать это:
убирать после
reset
.В противном случае вы можете получить сообщение «
Interactive rebase already started
».источник
Сброс ветвления к висячему объекту фиксации его старого наконечника, конечно же, является лучшим решением, потому что он восстанавливает предыдущее состояние без каких-либо усилий. Но если вы потеряли эти коммиты (например, из-за того, что тем временем вы собрали мусор в своем хранилище или это новый клон), вы всегда можете перебазировать ветку снова. Ключом к этому является
--onto
переключатель.Допустим, у вас была изобретательная ветка темы
topic
, которую вы разветвляли,master
когда кончикmaster
был0deadbeef
коммитом. В какой-то момент, находясь наtopic
ветке, вы это сделалиgit rebase master
. Теперь вы хотите отменить это. Вот как:Это возьмет все коммиты
topic
, которые не включены,master
и воспроизведет их поверх0deadbeef
.С помощью
--onto
вы можете изменить свою историю практически в любую форму .Радоваться, веселиться. :-)
источник
--onto
и-i
вы можете изменить свою историю практически в любой форме. Используйте Gitk (или Gitx на Mac), чтобы увидеть формы, которые вы делаете :-).На самом деле я помещаю резервный тег в ветку перед тем, как выполнить какую-либо нетривиальную операцию (большинство ребаз это тривиально, но я бы сделал это, если это выглядит где-то сложно).
Тогда восстановление так же просто, как
git reset --hard BACKUP
.источник
branchName@{n}
синтаксис, вотn
n-ая предшествующая позиция указателя ветки. Так, например, если вы перебазируетеfeatureA
ветку на своюmaster
ветку, но вам не нравится результат перебазировки, тогда вы можете просто сделатьgit reset --hard featureA@{1}
сброс ветки обратно туда, где она была до перебазирования. Вы можете прочитать больше оbranch@{n}
синтаксисе в официальных документах Git для ревизий .HEAD
ветки временно хранится вORIG_HEAD
. Но техника использования резервной метки ветки тоже работает, это просто больше шагов.Если вы перенесли ветку в удаленный репозиторий (обычно это источник), а затем выполнили успешную перезагрузку (без слияния) (
git rebase --abort
выдает «Нет выполнения в процессе»), вы можете легко сбросить ветку с помощью команды:Пример:
источник
С помощью
reflog
не работает для меня.То, что сработало для меня, было похоже на описанное здесь . Откройте файл в .git / logs / refs, названном в честь перебазированной ветви, и найдите строку, содержащую «rebase finsihed», что-то вроде:
Оформить второй коммит, указанный в строке.
После того как я подтвердил, что это содержит мои потерянные изменения, я разветвился и вздохнул с облегчением.
источник
Для нескольких коммитов помните, что любой коммит ссылается на всю историю, ведущую к этому коммиту. Поэтому в ответе Чарльза прочитайте «старый коммит» как «самый новый из старых коммитов». Если вы вернетесь к этому коммиту, то снова появится вся история, ведущая к этому коммиту. Это должно делать то, что вы хотите.
источник
Следуя решению @Allan и @Zearin, я хотел бы просто сделать комментарий, но мне не хватает репутации, поэтому я использовал следующую команду:
Вместо того чтобы делать
git rebase -i --abort
(обратите внимание на -i ) я должен был просто сделатьgit rebase --abort
( без -i ).Использование обоих
-i
и--abort
одновременно заставляет Git показывать мне список использования / опций.Итак, мой предыдущий и текущий статус ветки с этим решением:
источник
Если вы успешно перебазировали против удаленной ветки и не можете,
git rebase --abort
вы все равно можете сделать некоторые трюки, чтобы сохранить свою работу и не иметь принудительных толчков. Предположим, что ваша текущая ветка, которая была перебазирована по ошибке, называетсяyour-branch
и отслеживаетorigin/your-branch
git branch -m your-branch-rebased
# переименовать текущую веткуgit checkout origin/your-branch
# оформить заказ до последнего состояния, известного как источник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 новых коммитов, которые что-то ломают. Я обнаружил, что часто проще всего удалить плохие коммиты.
Интерактивная перебазировка за последние 31 коммитов (не повредит, если вы выберете слишком много).
Просто возьмите коммиты, от которых вы хотите избавиться, и пометьте их «d» вместо «pick». Теперь коммиты эффективно удаляются, отменяя ребазинг (если вы удаляете только коммиты, которые вы только что получили при ребазинге).
источник
Для новичков / тех, кто слишком боится сделать полный сброс, вы можете извлечь коммит из reflog, а затем сохранить его как новую ветку.
Найти коммит незадолго до того, как вы начали ребазинг. Возможно, вам придется прокрутить дальше вниз, чтобы найти его (нажмите Enter или PageDown). Запишите номер HEAD и замените 57:
Просмотрите ветку / commitits, если она выглядит хорошо, создайте новую ветку, используя эту HEAD:
источник
Если вы находитесь на ветке, вы можете использовать:
Существует не только справочный журнал для HEAD (полученный с помощью
git reflog
), но и для каждой ветки (также полученные с помощью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 reset #commit_hash
до последнего коммита, где, я думаю, ребаз не имел никакого эффекта.
тогда
git pull
Теперь ваша ветка должна совпадать точно так же, как master, и в ней не должно быть повторных коммитов.
Теперь можно просто выбрать коммиты на этой ветке.
источник
Я перепробовал все предложения с перезагрузкой и рефлогом, но безуспешно. Восстановление локальной истории IntelliJ решило проблему потерянных файлов
источник
git reset --hard origin / {branchName}
является правильным решением для сброса всех ваших локальных изменений, сделанных с помощью rebase.
источник
origin/branch
вы можете потерять изменения между HEAD и этой точкой. Вы не хотите этого вообще говоря.Если вы что-то испортили в git rebase, например
git rebase --abort
, когда у вас есть незафиксированные файлы, они будут потеряны иgit reflog
не помогут. Это случилось со мной, и вам нужно будет думать нестандартно здесь. Если вам повезло, как и мне, и вы используете IntelliJ Webstorm, то вы можетеright-click->local history
и можете вернуться к предыдущему состоянию ваших файлов / папок, независимо от того, какие ошибки вы допустили при работе с версионным программным обеспечением. Всегда хорошо иметь другой отказоустойчивый запуск.источник
git rebase --abort
прерывает активную перебазировку, отмена не отменяет . Кроме того, использование двух VCS одновременно является плохой идеей. Это хорошая функция в программном обеспечении Jetbrains, но вы не должны использовать оба. Лучше просто изучать Git, особенно когда отвечаете на вопросы о переполнении стека, касающиеся Git.