如何计算目录的git哈希对象?
有人举过在目录上使用git哈希对象的例子吗?它在一个文件上很容易工作,但不像我期望的那样在一个目录中工作**如何计算目录的git哈希对象?,git,Git,有人举过在目录上使用git哈希对象的例子吗?它在一个文件上很容易工作,但不像我期望的那样在一个目录中工作** *: git hash-object c:\somefile.txt **: git hash-object -t tree c:\somedirectory 当我尝试将哈希对象用于目录时,它会抱怨“致命:无法打开'C:\someDirectory':权限被拒绝”git hash object-t tree希望file参数是描述树中条目的文件,而不是文件系统中的目录。我从评论中了解到
*: git hash-object c:\somefile.txt
**: git hash-object -t tree c:\somedirectory
当我尝试将哈希对象用于目录时,它会抱怨“致命:无法打开'C:\someDirectory':权限被拒绝”
git hash object-t tree
希望file参数是描述树中条目的文件,而不是文件系统中的目录。我从评论中了解到,此命令需要一个以二进制格式描述树的文件,并且使用git mktree
创建树对象会更容易
git-mktree
理解您从(例如)git-ls-tree-HEAD
获得的格式输入。这里有一个很好的例子,可以使用中的git hash object
和git mktree
从头开始构建一棵树。正如Mark Longair所说,mktree是一条可行之路
我也遇到了同样的问题,为了解决它,我付出了很多努力。这就是我所做的:
git ls-files -s directory_path
这将为您提供目录及其哈希的内容列表
然后,您可以在文本编辑器中将此列表转换为ls树格式,然后
echo -e "{ls-tree format list}" | git mkdir
我也有同样的问题,并砍掉了一个。它的局限性在于它没有将
.gitignore
文件考虑在内,但到目前为止它已经达到了它的目的(hash目录、make commit对象等)。经过长时间的搜索,我发现了以下命令:
git写树
资料来源:
我用它来恢复丢失的目录:
git写入树路径/到/缺少/文件夹
我丢失的树对象被创建了。在此,您可以继续使用:
git散列对象-w path/to/missing/folder/file.txt
如中所述:
我想改进答案,提供他的脚本的修改版本,不同之处在于它不会将文件和目录存储在存储库中,这是计算散列的副作用:
不幸的是,我不知道有什么方法可以强制git mktree
不在存储库中创建树对象,因此代码必须生成树的二进制表示形式,并将其传递给git hash object-t tree
这个脚本也是基于
总体思路是使用git hash object--data.txt
获取文件的哈希值,并使用git hash object--stdin-t tree
获取目录,其中:
- TreeDescription是“模式名称\0hash”的串联
对于文件是模式
,对于目录是的“100644”
(请注意,对于目录,前导零不存在)的“40000”
和模式
由一个空格分隔名称
和name
由单个字节分隔hash
\0
是对象散列的20字节长的二进制表示形式散列
- 条目按
排序,这似乎不是创建树对象所必需的,但有助于通过比较它们的散列来确定两个目录是否相等-不幸的是,我不知道这里应该使用哪种排序算法(特别是:在非ascii字符的情况下该怎么办)名称
“tree SIZE\0”
标题
显然,您必须从最深的文件开始自下而上地计算,因为在计算父级的哈希之前,您需要对所有子级进行哈希运算。根据您希望这样做的原因,以下git命令可能会有用:
git ls-files -s somedirectory | git hash-object --stdin
这将给出一个考虑了文件名和内容的散列
它是这样工作的。git ls files-s..
将文件列表及其哈希值作为文本输出到stdout
,然后git hash对象
为它从stdin
接收的数据生成哈希值
我的用例如下-我想知道一个分支中目录中的(git托管)文件是否与另一个分支中的文件完全匹配(*)。具体用途是比较“目录散列”,决定是否需要重新生成缓存的派生文件
默认情况下,git ls files
也会列出子目录中的文件。如果你不想那样,试试看。还有各种其他功能,包括指定要包含的文件列表的功能
(*)排除散列冲突我不确定是否要获取git存储库外部目录的散列,但对于存储库内部的目录,请尝试仅打印散列:
git rev-parse HEAD:some/directory
不需要使用其他需要额外处理的命令
这也会起作用,但会提供您可能不需要的其他信息(如文件模式和其他数据):
我认为
git-ls-tree-HEAD-somedirectory
就足够了,git已经散列了dir。无需ls files
整个目录并使用git hash object
重新对其进行灰化。如果您需要限制散列计算中包含的文件,例如特定的文件扩展名,我想我上面的较长解决方案可能会很方便,或者排除子目录。回答得很好。git书不再包含mktree
示例,GitHub上的源代码也不足以在旧版本中找到它。
git ls-tree HEAD some/directory