GIT восстановить последнюю отсоединенную HEAD

87

Пожалуйста, у меня в проекте большая проблема: вот сценарий. У меня есть проект xcode под GIT. Сегодня я понял, что последний коммит сломал некоторые тесты, поэтому я проверил предыдущий коммит. Я использовал SourceTree, и это предупреждение

Это сделает вашу рабочую копию отдельной HEAD, что означает, что вы больше не будете в ветке. Если вы захотите выполнить фиксацию после этого, вы, вероятно, захотите либо снова проверить ветку, либо создать новую ветку. Это нормально?

Я работал целый день и в итоге все сделал. Мне нужно было объединить мою работу над веткой разработки, поэтому я проверяю ветку разработки и ... моя работа мгновенно исчезла :(

Я знаю, что было неправильно отсоединять мою ГОЛОВУ, и Sourcetree предупредил меня ... но есть ли способ восстановить мою работу?

IgnazioC
источник
Связанная тема с той же проблемой здесь и техническими подробностями о том, как это происходит здесь .
RBT

Ответы:

259

Если вы напечатаете git reflog, он покажет вам историю того, на какие изменения HEADуказали. Ваша оторванная голова должна быть там. Как только вы его найдете, выполните git checkout -b my-new-branch abc123или git branch my-new-branch abc123(где abc123SHA-1 отделенной HEAD), чтобы создать новую ветку, которая указывает на вашу отделенную голову. Теперь вы можете объединить эту ветку на досуге.

Как правило, если вы проверяете ветку после работы с отдельной головкой, Git должен сообщить вам фиксацию из отсоединенной головы, в которой вы были, чтобы вы могли восстановить ее, если вам нужно. Я никогда не использовал SourceTree, поэтому не знаю, передает ли он это сообщение. Но если он действительно отобразил это сообщение, вы сможете использовать его для поиска фиксации и снова использовать git checkout -bили git branchдля создания ветки из этой фиксации.

Брайан Кэмпбелл
источник
5
Спасибо, Брайан. Ты спас мне день.
Muzammil
Брайан, ты спас мне жизнь! Благодаря!!
cldrr 08
Я новичок в git .. я получаю fatal: A branch named 'mybranch' already exists.Как добавить в существующую ветку?
Рамеш Муругесан
1
В качестве PSA для всех, кто благодарит Брайана: если вы делаете работу, которую не хотите терять, отправляйте ее на удаленный компьютер (например, на github) каждые несколько часов. Когда на ваш компьютер упадет метеор, вы будете этому рады. Если вы еще не готовы поделиться им с соавторами, просто поместите его в ветку, о которой пока никто не знает, а затем переустановите ее на мастер позже.
MatrixManAtYrService
1
Кроме того, если это единственная потерянная фиксация, которая просто исчезла, и вы нашли ее там, вы можете вернуть ее с помощью git cherry-pick e5b2f7b, где e5b2f7bнаходится SHA-1 фиксации.
Aidin
10

В Sourcetree это можно сделать с помощью графического интерфейса.

Сначала найдите «потерянную» фиксацию, посмотрев сообщение в истории команд (вид: Показать выходные данные команды). Вероятно, он будет в команде "Switching Branch" после потерянного коммита. Надеюсь, в этом сообщении вы увидите комментарий фиксации с идентификатором фиксации 1234567.

Используйте этот идентификатор фиксации для следующего шага.

Нажмите кнопку «Ветвь» на верхней панели инструментов, и вы должны получить диалоговое окно «Новая ветвь», в котором вы можете указать конкретную фиксацию. Поместите этот идентификатор фиксации туда, укажите новое имя ветки, нажмите «Создать ветку», и вы должны получить новую ветку с потерянной фиксацией!

введите описание изображения здесь

светловолосый
источник
действительно работает. Убедитесь, что вы видите правильный комментарий с идентификатором фиксации.
Хаммад Хан
@blalond Здравствуйте, прочитав ваш ответ, у меня возник небольшой вопрос: когда в SourceTree я дважды щелкаю предыдущий коммит (чтобы проверить его), я получаю то же сообщение, что это может вызвать отслоение головы, поэтому мне интересно что это значит, когда люди говорят, что вы можете просто вернуться к любой предыдущей версии с помощью git? Как мне тогда вернуться к конкретному коммиту? Спасибо
5

Если вы не хотите сохранять изменения отключенной HEAD и хотите перейти к последней фиксации ветки, используйте команду ниже напрямую.

git checkout - 

Примечание: я удалю все ваши изменения в отключенной HEAD.

Пустынная роза
источник
ОП действительно просило сохранить их работу. Это не отвечает на исходный вопрос. Просто добавив возможность сохранить это в ветке, этот ответ будет полезным.
мануэльвигарсия
1

У моего коллеги была такая ситуация. В его случае были коммиты в отдельной голове - они работают в R-Studio - и инструмент предупреждал их, что они могут создать ветку с той и той ссылкой на SHA ... но поскольку единственным вариантом было "Закрыть" --ду !! это было информационное окно - они закрыли диалог и потеряли информацию навсегда ...

Благодаря reflog команде мы увидели, что изменения не пропали. Но в нашем случае git branchэто не сработало, как ожидалось ... или входящий git pullкак-то испортил его. Нам пришлось выловить изменения из рефлога во вновь созданную ветку:

 git cherry-pick 0b823d42..3cce27fc

который поместил все нужные нам коммиты в ветку. Тогда мы могли бы developбез проблем объединить ветку .

На всякий случай, если это для кого-то информативно, мы идентифицировали коммиты на отдельной голове. в reflogфайле, посмотрев на те, которые находятся между помеченными «checkout» (которые определяют смещение ветки):

e09f183b HEAD@{3}: pull: Fast-forward
b5bf3e1d HEAD@{4}: checkout: moving from lost_changes to develop
b5bf3e1d HEAD@{5}: checkout: moving from 3cce27fca50177a288df0252f02edd5da5ee64fd to lost_changes
3cce27fc HEAD@{6}: commit: add statistics
417a99a4 HEAD@{7}: commit: add test
0b823d42 HEAD@{8}: commit: new utility class
d9ea8a63 HEAD@{9}: checkout: moving from develop to d9ea8a635d4c2349fcb05b3339a6d7fad5ae2a09
b5bf3e1d HEAD@{10}: pull: Fast-forward

Те, кого мы хотели, были HEAD@{8} в HEAD@{6}(оба включительно). Итак, мы получили их:

git cherry-pick 0b823d42..3cce27fc

Затем обычное решение слияния и финальная фиксация оставили нам ветку lost_changes, в которой размещалась отдельная работа, которую мы считали потерянной. На этот раз слияние этого с разработкой было ускоренным.

Мануэльвигарсия
источник
0

Я попробовал этот сценарий и обнаружил, что git сообщает мне SHA-1 последней фиксации:

vors@localhost:~/git-test$ git checkout master 
Warning: you are leaving 1 commit behind, not connected to
any of your branches:

  ec600e6 333

If you want to keep them by creating a new branch, this may be a good time
to do so with:

 git branch new_branch_name ec600e6eb2473dd4f3732539c5c1fa5829f631b7

Switched to branch 'master'

Вы видели это сообщение?

xvorsx
источник
нет. а может я не обращаю внимания. Я ищу резервную копию на timemachine; (
IgnazioC
1
@IgnazioC Вам не нужно смотреть резервную копию. Вы смотрели на мой ответ? git reflogдолжен показать вам, что вам нужно.
Брайан Кэмпбелл,
0

Отдельная голова - это нормально, если вы не хотите вносить никаких изменений.

Если вы хотите отменить фиксацию, вы можете использовать git revert в определенной ветке

Если вы хотите работать с отдельной головой и делать коммиты; создать новую ветку (а затем объединить ее);

Форваидья
источник
Да уж! мы знаем правила. Но когда коллеги работают над отстраненной головой, а затем отказываются от этих коммитов, они просят ответов, а не правил.
мануэльвигарсия
0
  1. Сначала бегите, git reflogчтобы посмотреть историю.
  2. Самая старая ревизия будет последней в списке.
  3. Переключитесь на желаемый коммит, используя git checkout -b temp e35d2b3здесь e35dd23 - хеш-значение вашего коммита.
  4. Вот и все. Теперь просто сделайте git add. и т.д....

Примите это как ответ, если он решит вашу проблему. В противном случае поделитесь своим комментарием.

Сохаиб
источник