在.git/refs
中,The Git Book中描述了三个目录:
heads
remotes
tags
此外,git replace
creates目录replace
。所以至少这四个名字是已知的,对Git有特殊意义。
但是,例如自己的存储库中的Gerrit creates目录for
和changes
。 (这只是一个例子,我不会问任何关于Gerrit的事情。)例如,我可以获取'更改'refs。 Git会知道它们不是分支而不是远程 - 它们是否像标签一样处理?
Git一般如何理解.git/refs
中的“非标准”内容?这样的用例可以是什么?除了上面列出的参考文献之外,还有其他“标准”目录吗?
答案 0 :(得分:3)
我对此的看法与Schwern's answer略有不同:没有目录具有特殊含义。相反,某些前缀字符串具有含义。
Git关心的是引用,它们是以refs/
开头的符合git check-ref-format
强加的限制的名称。 Git有时会选择将这些名称存储为普通文件路径名,有时候不会将它们全部存储在一个简单的文本数据库文件中。.git/packed-refs
将它们全部存储起来。将来,除了平面文件和/或目录树之外,Git可以使用真实数据库。如果您坚持使用已发布的界面(如下所述),您可以将自己与以后的任何格式更改隔离开来。
Git中定义的前缀字符串是(我试图使这个列表完整,但我忘了Schwern添加的至少一个,所以我添加了它:-)):
refs/bisect/
:有关正在进行的二分法的信息refs/heads/
:分支机构名称refs/notes/
:注意名称refs/original/
:git filter-branch
使用它来存储所有原始(预过滤操作)参考refs/remotes/
:远程跟踪名称refs/replace/
:替换对象refs/stash
:(单数)藏匿refs/tags/
:标记名称所有其他名称都可用,至少在某些第三方扩展程序被集成到Git中之前。
要编写参考,请使用the shell command git update-ref
。这可以创建,更新或删除对任何有效散列ID的引用。要编写符号引用,请使用git symbolic-ref
。两个命令都会更新引用的 reflog (如果存在),或者在适当时创建或删除它。
要浏览所有引用,请使用git for-each-ref
。要在逻辑树结构中遍历特定引用,您可以继续使用git for-each-ref
(它需要前缀和glob模式),或者使用一些更面向用户的命令(如git branch
和{{1例如,对git tag
使用--branches
,--tags
和/或--remotes
个参数。
如果要使用较低级别的操作,请注意,当前git rev-list --no-walk
中存在的文件会覆盖存储在平面文件.git/refs
文件中的任何值。我怀疑如果/当Git获得一个真正的参考数据库时,真数据库条目将覆盖所有其他数据库,并且可能存在数据库条目类型代码"此名称曾经存在,但现在不存在" 。 (如果数据库有效,它可能还会保存reflog条目,这将是一个允许"取消删除"旧引用的好方法。)
答案 1 :(得分:2)
Git如何理解.git / refs中的“非标准”内容?
没有。它忽略了它们。
.git
是目录树。与任何其他目录树一样,文件和目录名称对git
具有意义。 .git/refs/
的每个顶级目录都具有git
的特定含义。
.git/refs/heads/
包含分支头(即master
).git/refs/tags/
包含标签(即v1.2.3
).git/refs/remotes/
包含远程分支头(即origin/master
) Git命令将遍历这些目录中的文件,以发现可用的分支,标记和远程控制。并且它知道它何时需要,例如,它在.git/refs/tags/
中看到的标签。
例如,git branch
有效地列出了.git/refs/heads/
及其子目录中的所有文件。 git tag -l
执行.git/refs/tags/
。 git branch -r
执行.git/refs/remotes/
。请注意,有"packed refs"这样的优化使得这不再那么简单了。
git
中的任何其他内容都不会使用。就像你的主目录中的文件和目录被许多程序放在那里一样,它们每个人都只关心自己的程序。
这样的用例可以是什么?
你已经用Gerrit回答了你的问题。当第三方Git实用程序需要存储有关本地存储库的额外信息时,可以将它放在.git
中。与在代码树顶部放置.gerrit
目录不同,.git
中的额外文件和目录被大多数其他实用程序忽略。如果您移动或复制repo目录,.git
中的额外Gerrit信息将随之而来。
例如,当Gerrit想要存储其他类型的引用时,它可以将它们放在.git/refs/changes/
或.git/refs/for/
中,而不会干扰正常的git
功能。
除了我上面列出的那些之外,还有其他“标准”目录吗?
我怀疑是否有明确的清单,您可能需要扫描git
的源代码。有关已知目录的列表,请参阅@torek's answer。