我知道git不会看到空的dir,但有人可以提供有关其实现方式的一些文档的参考。 它不仅仅是关于空文件夹。如果我将文件添加到新文件夹,但我没有将其添加到暂存区域,git实际上会看到该文件夹,但不是文件。
答案 0 :(得分:2)
我知道Git不会看到空头......
这不太对。 Git会看到就好了,它不会保存。
但有人可以提供有关如何实施的文档的参考。
好的软件通常会试图隐藏实现细节,这表明Git不是很好,但是在这种情况下,实现细节确实非常隐蔽。 Git的内部文档是here,其中一个骨架api-in-core-index.txt上次更新了9年前(!),还有一个更新的index-format.txt。在任何情况下,跟踪都是关于Git的索引,它有几个名称:“索引”,“临时区域”和“缓存”。
这不仅仅是关于空文件夹。如果我将文件添加到新文件夹,但我没有将其添加到暂存区域,Git实际上会看到该文件夹,但不是文件。
这也不太正确。尝试运行git status -uall
(或等效地,git status --untracked-files=all
)。 1 这里发生的是git status
命令通常总结未跟踪文件通过一个简单的规则:如果存在名为dir
的目录,并且在dir
中找到了一些未跟踪的文件,但未找到跟踪的文件dir
,Git只打印dir/
而不是枚举 dir
中的每个文件。
如果您使用-uno
(或--untracked-files=no
),Git甚至不会查找未跟踪文件,从而节省时间。在一个大型存储库(成千上万的目录,数十万甚至数百万个文件)中,这可以使git status
在一秒钟内完成,而git status
花费很多秒。
查找所有未跟踪文件需要将实际工作树与存储在索引中的工作树的缓存版本进行比较。使用正常(汇总)模式,Git有时可以使用其缓存来避免枚举dir
内的文件,甚至查看 dir
内的文件,这也节省了时间。
当然,没有找到未跟踪的文件,Git永远不会提醒你git add
这样的文件。所以默认(汇总)模式在操作速度方面都是一种妥协(“如果dir
本身或通过子目录包含任何文件 2 ,但我们已经知道没有跟踪 dir
中的文件,不要为文件“和”可用性进行更细粒度的扫描(“不需要在dir
内使用19,365个文件名对垃圾邮件进行垃圾邮件当我们可以说dir/
“)时。
1 如果您指定无选项,则默认为-unormal
,但如果您指定-u
,则表示-uall
。但是,您也可以设置the status.showUntrackedFiles
configuration variable来修改默认值。
2 对此进行测试(“dir
或其子目录包含任何普通文件”)部分取决于对readdir
's {{d_type
字段的支持3}}数据,这是POSIX不需要但很常见的(它在所有现代Unix变种中都可以找到)。最新版本的Git还具有索引格式的“未跟踪缓存”扩展,如dirent
中所述,允许Git在stat
数据未更改时跳过读取未跟踪目录,使用{{ 1}} that same technical documentation的字段。
答案 1 :(得分:1)
正在发生的事情分为两个层次:幕后发生了什么(管道)以及你实际看到的(瓷器)。
要了解有关管道层的所有信息,我建议您查看Pro Git的this section。简而言之,目录存储为tree
对象,其内容类似于
100644 blob a906cb2a4a904a152e80877d4088654daad0c859 README
100644 blob 8f94139338f9404f26296befa88755fc2598c289 Rakefile
040000 tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0 lib
第一列用于权限,第二列用于是blob
(文件)还是tree
(另一个目录),第三列用于SHA-1对象,最后一列是文件名。
尽管管道方面没有任何内容阻止您在提交中放置一个空的tree
对象,it can cause problems later。如果要实现类似的效果,可以将文件放在目录中。如果要强制目录保持为空,可以使用this solution;如果您不关心以后人们是否放置文件,则可以是README
或空.gitignore
。