Что происходит с коммитами git, созданными в отключенном состоянии HEAD?

137

Это то, что случилось:

У меня есть ветка A. На ветке AI совершено кучу изменений. Я не был доволен кодом, поэтому я проверил предыдущий коммит в ветке А. Затем я внес еще несколько изменений и зафиксировал их в ветке А. Теперь я нигде не могу найти этот коммит. Я потерял этот код?

Mausimo
источник
Когда вы говорите: «Я извлек предыдущий коммит в ветви A», вы имеете в виду «Я сбрасываю ветку A на предыдущий коммит»? то есть ты на самом деле, git resetа не git checkout?
CB Bailey
Нет, я использовал оформить заказ. рефлог сработал.
Mausimo
Если бы вы использовали checkout, то вы были бы отсоединены, HEADа ветвь A осталась бы на предыдущем коммите. Какие именно команды вы выполняли?
CB Bailey
1
Я использовал SourceTree GIT GUI на OSX Lion. Я находился в ветви A и выполнил проверку предыдущего коммита в ветви A. Затем я сделал несколько изменений кода и зафиксировал (ветку A). Я считаю, что у меня была отдельная ГОЛОВА.
Mausimo
Хорошо, я думаю , что я был смущен , когда вы сказали , что вы совершили кучу больше изменений на ветви А .
CB Bailey

Ответы:

186

Старый коммит все еще находится в reflog.

git reflog

Это покажет список коммитов, и «потерянный» коммит должен быть там. Вы можете превратить его в новую ветку. Например, если SHA-1 - ba5a739, то вы можете создать новую ветку с именем "new-branch" при старой фиксации с помощью:

git branch new-branch ba5a739

Обратите внимание, что «потерянные» коммиты будут удалены при удалении базы данных.

Дитрих Эпп
источник
3
Я сделал то же самое, и насчет сердечного приступа, думая, что он был потерян. Спасибо за информацию!
Погоня
15
Используется git cherry-pick [SHA]для перемещения коммита в существующую ветку, если вы случайно зафиксировали его, находясь в отдельном состоянии
Ян Аагард Мейер
3
В качестве альтернативы вы можете переключиться на существующую ветку и выполнить команду «git merge HEAD @ {n}» n, соответствующую «потерянному» коммиту, указанному в reflog.
eaykin
Знаете ли вы prune, удалит ли также также отдельные коммиты, на которые ссылаются в сообщениях коммитов? Или это делает их достижимыми ?
Kamafeather
@ Kamafeather: я не думаю, что это делает их достижимыми.
Дитрих Эпп
64

Ваши коммиты все еще доступны в reflog, как уже отмечалось. В дополнение к другим ответам, вот способ перенести отключенные коммиты HEAD непосредственно в вашу текущую ветку , не создавая и не объединяя новую ветку:

  1. Посмотрите хэши SHA-1 коммитов, которые вы сделали в отдельном состоянии HEAD

    git reflog
    
  2. Затем выполните все упорядоченные хэши, начиная с самых старых и заканчивая самыми последними:

    git cherry-pick <hash1> <hash2> <hash3> ...
    

    Например, если у меня был только один, заданный в формате коротких хэшей «первые 7 символов»:

    git cherry-pick a21d053
    

Это создаст новые коммиты в вашей текущей ветке, по одному коммиту на хэш detached-HEAD-commit, который вы упомянули в команде. Он также принимает исходные сообщения коммита.

tanius
источник
11

Вы можете найти потерянные (висячие) коммиты с помощью следующей команды:

git fsck --lost-found

Обратите внимание, что если ваша текущая голова висящая коммит, она не будет указана как потерянная.

Вы можете найти больше информации на странице руководства git-fsck (1)

Затем вы можете создать ветку для этого потерянного коммита:

git branch new-branch ba5a739
sergtk
источник
Сначала я использовал команду «git reflog», а затем «git branch new-branch ba5a739» для подмодуля, это сработало.
ondermerol
7

Git, говоря о состоянии вашего рабочего каталога, - это « отдельная ГОЛОВА ». Вот еще одно место, которое git reflogспасает.

$ git reflog
0b40dd6 HEAD@{0}: commit: my commit on detached HEAD
...

Если я пытаюсь оформить заказ на другую ветку, git-1.7.5.1 дает полезное предложение.

$ git checkout master
Предупреждение: вы оставляете 1 коммит позади, не подключенный к
любая из ваших веток:

  0b40dd6 мой коммит на отдельной голове

Если вы хотите сохранить их, создав новую ветку, это может быть хорошим временем
сделать это с:

 git branch new_branch_name 0b40dd65c06bb215327863c2ca10fdb4f904215b

Перешел на ветку "мастер"
Грег Бэкон
источник
Спасибо за информацию и ссылку. Ссылка помогла мне понять, что происходит.
Mausimo
6

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

Грег Хьюгилл
источник
4

Выполните следующие шаги, чтобы связать свою отстраненную голову обратно в git repo

  1. git checkout "your branch with path but without remote name"

например, если удаленное имя является источником, а имя ветви bugfix/somebranchиспользуетсяgit checkout bugfix/somebranch

  1. git reflog получите список SHA для фиксации из списка коммитов отдельной ветки.

  2. git cherry-pick "commit hash1" "commit hash2" "commit hash3"

  3. git push

ВСЕ ГОТОВО!!

user1520615
источник
2

В Sourcetree я обнаружил, что git reflog не работает, поэтому я выяснил, как это сделать с помощью графического интерфейса.

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

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

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

Это вернуло мне потерянную работу!

blalond
источник