Git ghost commit逃避日志

时间:2012-07-25 21:09:43

标签: git

今天我正在研究我的一个项目,我意识到git有些奇怪。 Git会允许你将你的工作交给幽灵分支。我使用术语 ghost分支 ,因为更改存在于树中某处但是避开了git log --graph --decorate --oneline --all。任何人都可以向我解释为什么会这样吗?

重现此行为的步骤

输入分离头状态(您可以通过执行git checkout <hash>来实现)。

# Not currently on any branch.
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   uml 1.pdf

对您的代码库进行一些更改。并使用git status检查工作目录的状态。这应列出更改,但声明您不在任何分支上。

# Not currently on any branch.
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   .gitignore
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   uml 1.pdf

使用git commit -am '<message>'

提交更改
[detached HEAD ded7725] updated .gitignore
 1 files changed, 8 insertions(+), 1 deletions(-)

如果然后签出一个已知的分支,例如“master”,那么在分离的头状态中提交的所有更改都将消失。这是预期的。

Runnig git log --graph --decorate --oneline --all将显示所有提交,除了分离头上提交的提交(在我的情况下为ded7725)。

但是,git checkout <hash-for-ghost-branch>返回提交给ghost分支的更改。问题是:人们不能永远记住这个哈希。

预期的行为是这个幽灵分支将在一个有点悬挂的叶子上记录图形。但它不存在。关于为什么会发生这种情况的任何解释都表示赞赏或许我错过了一面显示隐藏分支的旗帜......

3 个答案:

答案 0 :(得分:2)

幽灵&#34;分支,就像你所说的那样,不是分支。它在DAG上提交,但没有任何指向。

虽然我没有查看代码,但我会想象git log会绘制图形并通过从分支指针开始并向后工作来列出提交。由于你处于一个独立的HEAD状态的提交没有任何指向它们的东西,因此没有办法将git log记录到&#34;参见&#34;它们。

要解决此问题,只需使用git branch branch_name <commit>创建分支即可。然后git log将指向在分离的HEAD状态下完成的最后一次提交,并且&#34; find&#34;那些在显示日志/绘制图形时提交。

答案 1 :(得分:2)

这个“ghost”分支没有出现在你的git log中的根本原因 - all是这个日志只代表所有分支,而不是所有现有的提交。 您必须考虑到,当您重新提交提交时,您不会删除旧提交,只需将它们复制到另一个父级,因此它们也可以在没有任何分支的情况下提交,例如您的ghost分支。

提交就像其他对象引用的对象一样,git保存的唯一对象是分支引用的对象。它实际上就像一个垃圾收集内存,你的提交是你在内存中创建的对象而不引用它。如果你运行git gc git将删除所有未被任何分支引用的提交,包括你的“ghost分支”。

您的解决方案是通过创建wasworld解释的分支或标记您的提交git tag tagname sha1来保留对此提交的引用。

编辑:git gc不会删除最近的提交,根据其手册页:

The optional configuration variable gc.reflogExpire can be set to indicate how long 
historical entries within each branch's reflog should remain available in this 
repository. The setting is expressed as a length of time, for example 90 days or 3
months. It defaults to 90 days.

因此默认情况下,您的幽灵分支可以安全地从git gc开始(可以在没有您要求的情况下启动)90天。

答案 2 :(得分:1)

在git中,分支只是提交的指针。所以,当你说“问题是:一个人永远不能记住这个哈希”时,为什么不在它上面创建一个分支呢?

git branch branch_name <commit>

另外要记住的是,如果你没有创建指向此提交的任何分支,那么一旦过期时间过去,它将被gc'ed。默认值为90天。