在分离的HEAD状态下创建的git commit会怎样?


137

这是发生了什么:

我有一个分支A。在分支AI上进行了一堆更改。我对代码不满意,因此我签出了分支A中的上一个提交。然后,我做了很多更改,并将它们提交到分支A中。现在,我在任何地方都找不到此提交。我丢失了此代码吗?


当您说“我签出了分支A中的先前提交”时,您的意思是“我将分支A重置为先前的提交”吗?也就是说,您实际上git reset不是git checkout吗?
CB Bailey 2012年

不,我用过结帐。reflog有效。
Mausimo

如果您使用checkout,那么您将一直处于分离状态,HEAD而分支A将停留在上一次提交中。您究竟运行了哪些命令?
CB Bailey

1
我在OSX Lion上使用SourceTree GIT GUI。我在分支A上,并检查了分支A上一次提交的结帐。然后,我做了一堆代码更改并提交了(分支A)。我相信我有一个独立的头。
Mausimo

好的,当您说对分支A进行了更多更改时,我感到很困惑。
CB Bailey

Answers:


185

旧的提交仍在reflog中。

git reflog

这将显示提交列表,“丢失的”提交应该在其中。您可以将其放入新分支。例如,如果SHA-1是ba5a739,则可以在旧提交中使用以下命令创建一个名为“ new-branch”的新分支:

git branch new-branch ba5a739

请注意,修剪数据库后,“丢失的”提交将被删除。


3
我做了同样的事情,并因心脏病发作而认为自己丢失了。谢谢(你的)信息!
大通

14
使用git cherry-pick [SHA]移动提交到现有的分支,以防不小心而脱落国家元首承诺
扬AAGAARD迈耶

3
另外,您可以切换到现有分支,并执行与reflog中列出的“丢失”提交相对应的“ git merge HEAD @ {n}” n。
eaykin

您是否知道是否prune会删除提交消息中引用的分离提交?还是使它们可达
卡马菲瑟

@Kamafeather:我不认为这使他们可以到达。
Dietrich Epp

63

如前所述,您的提交仍可在reflog中使用。除了其他答案之外,这是一种将分离的HEAD提交直接接管到当前分支中的方法,而无需创建和合并新分支:

  1. 使用以下命令在分离的HEAD状态下查找提交的SHA-1哈希

    git reflog
    
  2. 然后执行,将所有提交哈希值从最早到最新的顺序排序:

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

    例如,如果我只有一个,则以“前7个字符”的短哈希格式给出:

    git cherry-pick a21d053
    

这将对当前分支创建新的提交,即您在命令中提到的每个HEAD分离哈希提交一个提交。它还将接管原始提交消息。


11

您可能会发现使用以下命令丢失(悬挂)的提交:

git fsck --lost-found

请注意,如果您当前的头悬空提交,则不会将其列为丢失。

您可以在git-fsck(1)手册页上找到更多信息。

然后,您可以在丢失的提交上创建分支:

git branch new-branch ba5a739

我首先为子模块使用了命令“ git reflog”,然后使用了“ git branch new-branch ba5a739”,它可以正常工作。
ondermerol '16

7

Git认为工作目录的状态是“ 分离的HEAD”。这是另一个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

可以了,好了!!


2

在Sourcetree中,我发现git reflog无效,因此我想出了如何使用GUI进行此操作。

首先,尝试通过在命令历史记录中查找消息来查找“丢失的”提交(视图:显示命令输出)。希望在丢失的提交之后将在命令“ Switching Branch”中,并且您将看到带有1234567提交ID的提交注释。

将该提交ID转到下一步。

点击顶部工具栏中的“分支”按钮,您将获得一个“新分支”对话框,您可以在其中指定某个提交。在其中放置该Commit ID,指定一个新的分支名称,点击Create Branch,您将获得一个新的分支,其中包含丢失的提交!

这给我带来了一些丢失的工作!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.