Отмена отмены git

Кто-нибудь знает, как легко отменить git rebase?

Единственный способ, который приходит на ум, - это пойти вручную:

  • git проверить родительский элемент фиксации на обеих ветвях
  • затем создайте ветвь темпа
  • Черри-выберите все фиксации вручную
  • замените ветвь, в которой я переустановил ветвь, созданная вручную

В моей нынешней ситуации это сработает, потому что я могу легко обнаружить фиксации из обеих ветвей (один был моим материалом, другой - моим коллегой).

Однако мой подход поражает меня как неоптимальную и подверженную ошибкам (скажем, я только что переделал две мои собственные ветки).

Любые идеи?

Уточнение: я говорю о переустановке, в ходе которой была переиграна куча коммитов. Не только один.

Ответ 1

Самый простой способ - найти головную фиксацию ветки, как это было непосредственно перед началом перезагрузки в reflog..

git reflog

и reset текущую ветвь к ней (с обычными предостережениями о том, чтобы быть абсолютно уверенными перед реселлированием с опцией --hard).

Предположим, что старый коммит был [email protected]{5} в журнале ref:

git reset --hard [email protected]{5}

В Windows вам может потребоваться указать ссылку:

git reset --hard "[email protected]{5}"

Вы можете проверить историю старого кандидата, выполнив git log [email protected]{5} (Windows: git log "[email protected]{5}").

Если вы не отключили данные для каждого ветки, вы должны просто сделать git reflog [email protected]{1}, так как rebase отделяет ветвь ветки до ее присоединения к финальной голове. Я бы дважды проверял это, хотя, поскольку я не проверял это недавно.

По умолчанию все рефлоги активируются для не-голых репозиториев:

[core]
    logAllRefUpdates = true

Ответ 2

Фактически, rebase сохраняет начальную точку до ORIG_HEAD, поэтому это обычно так же просто, как:

git reset --hard ORIG_HEAD

Тем не менее, reset, rebase и merge все сохраняют ваш исходный указатель HEAD в ORIG_HEAD, поэтому, если вы выполнили какие-либо из этих команд с момента переустановки, которую вы пытаетесь отменить, вам придется использовать reflog.

Ответ 3

Ответ Charles работает, но вы можете сделать это:

git rebase --abort

для очистки после reset.

В противном случае вы можете получить сообщение "Interactive rebase already started".

Ответ 4

git reflog покажет вам все изменения до и после перезагрузки, и позволит вам найти подходящее для сброса. Но я удивлен, что никто еще не упомянул этот другой супер простой способ:

Также, как уже упоминалось здесь, rebase оставляет старое состояние как ORIG_HEAD, поэтому вы можете отменить последнюю перезагрузку, выполнив:

git reset --hard ORIG_HEAD

Ответ 5

Сброс ветки к обмотанному объекту фиксации его старого наконечника - это, конечно, лучшее решение, потому что оно восстанавливает предыдущее состояние, не затрачивая никаких усилий. Но если вы потеряли эти коммиты (f.ex., потому что вы мусор - собрал ваш репозиторий тем временем, или это новый клон), вы всегда можете снова переустановить ветвь. Ключом к этому является переключатель --onto.

Допустим, у вас была ветвь темы, образно названная topic, что вы отделили master, когда кончиком master был 0deadbeef commit. В какой-то момент на ветке topic вы сделали git rebase master. Теперь вы хотите отменить это. Вот как:

git rebase --onto 0deadbeef master topic

Это займет все фиксации на topic, которые arent на master, и воспроизведите их поверх 0deadbeef.

С --onto вы можете перестроить свою историю практически в любой форме.

Получайте удовольствие.: -)

Ответ 6

Я фактически помещаю тэг резервной копии в ветку, прежде чем выполнять какую-либо нетривиальную операцию (большинство перестановок тривиально, но я бы сделал это, если он выглядит где-то сложным).

Затем восстановление так же просто, как git reset --hard BACKUP.

Ответ 7

В случае вы переместили вашу ветку в удаленный репозиторий (обычно это происхождение), а затем вы выполнили успешную переадресацию (без слияния) (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

Ответ 8

Если вы не закончили rebase и посередине, выполните следующие действия:

git rebase --abort

Ответ 9

Использование 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

Ответ 10

Для нескольких коммитов помните, что любая фиксация ссылается на всю историю, ведущую к этой фиксации. Поэтому в ответе Чарльза читайте "старый фиксат" как "самый новый из старых коммитов". Если вы reset, чтобы зафиксировать это, тогда вся история, ведущая к этой фиксации, снова появится. Это должно делать то, что вы хотите.

Ответ 11

Следуя решению @Allan и @Zearin, я хотел бы просто сделать комментарий, хотя, но у меня недостаточно репутации, поэтому я использовал следующую команду:

Вместо git rebase -i --abort (обратите внимание на -i) мне просто нужно было сделать git rebase --abort (без -i).

Используя как -i, так и --abort, в то же время вызывает Git, чтобы показать мне список использования/параметров.

Таким образом, мой предыдущий и текущий статус ветки с этим решением:

[email protected] /my/project/environment (branch-123|REBASE-i)
$ git rebase --abort

[email protected] /my/project/environment (branch-123)
$

Ответ 12

Если вы успешно переустановили удаленный филиал и не можете 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

Ответ 13

Просто:

git rebase --abort

?

Ответ 14

Скажем, я переустанавливаю мастера на свою ветку функций, и я получаю 30 новых коммитов, которые что-то ломают. Я обнаружил, что часто проще всего просто удалить плохие коммиты.

git rebase -i HEAD~31

Интерактивная перестановка для последних 31 фиксации (это не больно, если вы слишком много выбираете).

Просто возьмите коммиты, от которых вы хотите избавиться, и пометьте их "d" вместо "pick". Теперь коммиты удаляются, эффективно уничтожая rebase (если вы удаляете только те коммиты, которые вы только что получили при перезагрузке).

Ответ 15

Для новичков/тех, кто слишком боится сделать полный сброс, вы можете извлечь коммит из reflog, а затем сохранить его как новую ветку.

git reflog

Найти коммит незадолго до того, как вы начали ребазинг. Возможно, вам придется прокрутить дальше вниз, чтобы найти его (нажмите Enter или PageDown). Запишите номер HEAD и замените 57:

git checkout [email protected]{57}

Просмотрите ветку /commitits, если она выглядит хорошо, создайте новую ветку, используя эту HEAD:

git checkout -b new_branch_name

Ответ 16

Если вы находитесь на ветке, вы можете использовать:

git reset --hard @{1}

Существует не только справочный журнал для HEAD (полученный с помощью git reflog), но также есть и reflogs для каждой ветки (полученный с помощью git reflog <branch>). Таким образом, если вы используете master то git reflog master выведет список всех изменений в этой ветке. Вы можете сослаться на эти изменения по [email protected]{1}, [email protected]{2} и т.д.

git rebase обычно меняет HEAD несколько раз, но текущая ветка будет обновляться только один раз.

@{1} - это просто ярлык для текущей ветки, поэтому он равен [email protected]{1} если вы используете master.

git reset --hard ORIG_HEAD не будет работать, если вы использовали git reset во время интерактивного rebase.

Ответ 17

Что я обычно делаю, так это git reset #commit_hash

до последнего коммита, где, я думаю, ребаз не имел никакого эффекта.

тогда git pull

Теперь ваша ветка должна совпадать точно так же, как master, и в ней не должно быть повторных коммитов.

Теперь можно просто выбрать коммиты на этой ветке.

Ответ 18

git reset --hard origin/{branchName}

является правильным решением для сброса всех ваших локальных изменений, сделанных с помощью rebase.

Ответ 19

Если вы повредите что-то в рамках git rebase --abort git, например git rebase --abort, в то время как у вас есть незафиксированные файлы, они будут потеряны, а git reflog не поможет. Это случилось со мной, и вам нужно будет подумать нестандартно. Если вам повезло, как я, и используйте IntelliJ Webstorm, вы можете щелкнуть right-click->local history кнопкой мыши по right-click->local history и вернуться к предыдущему состоянию вашего файла/папок независимо от того, какие ошибки вы совершили с помощью программного обеспечения для управления версиями. Всегда хорошо иметь еще один отказоустойчивый ход.

Ответ 20

Чтобы отменить, вы можете ввести следующую команду:

git -c core.quotepath=false rebase --abort