![重复压缩新创建但相同的文件,但 zip 的 shasum 不断变化](https://linux22.com/image/46934/%E9%87%8D%E5%A4%8D%E5%8E%8B%E7%BC%A9%E6%96%B0%E5%88%9B%E5%BB%BA%E4%BD%86%E7%9B%B8%E5%90%8C%E7%9A%84%E6%96%87%E4%BB%B6%EF%BC%8C%E4%BD%86%20zip%20%E7%9A%84%20shasum%20%E4%B8%8D%E6%96%AD%E5%8F%98%E5%8C%96.png)
这是后续我反复压缩同一个文件夹中的文件,但 shasum 不断变化本质上..
当我压缩存储库的一部分并获取其 sha 总和时,我试图添加一个包含当前提交的 git sha 的文件。
其代码是git rev-parse HEAD > .gitsha
.然而,将其添加到我的 zip 中意味着shasum
我的 zip 每秒左右都会发生变化。 zip 命令用于-X
忽略文件时间戳。
我只尝试了.gitsha
下面的文件
$ git rev-parse HEAD > .gitsha ; shasum .gitsha
8fa263bc885822ccba03006ea10015ef32da485c .gitsha
随着时间的推移,这一点是一致的。
但是压缩后,shasum
不再一致
$ git rev-parse HEAD > .gitsha ; zip -X --quiet -r test.zip .gitsha ; shasum test.zip
26cc38c624f91a1c555d503fdfdecb1ce670274f test.zip
$ git rev-parse HEAD > .gitsha ; zip -X --quiet -r test.zip .gitsha ; shasum test.zip
b03f7cb654e3aa0d25d18ead5fe1f225bc2aac9f test.zip
这是两次相隔几秒钟的试验。我认为该-X
标志可能不包括创建时间?有什么办法让它发挥作用吗?
更新:删除 zip 没有帮助。
$ rm test.zip; git rev-parse HEAD > .gitsha ; zip -X --quiet -r test.zip .gitsha ; shasum test.zip
76c722ccf2df75fb624f9640ad948f4508dd6152 test.zip
$ rm test.zip; git rev-parse HEAD > .gitsha ; zip -X --quiet -r test.zip .gitsha ; shasum test.zip
6bd26d2bc821d9f12806fc81a8ba8c8babcc664a test.zip
答案1
strings
检查zip 文件上的命令的输出:
$ strings test.zip blah.zip
.gitshab9e1355d36643fefe94da0bee81533cd8cbb04d9
.gitshaPK
QH;F
.gitshab9e1355d36643fefe94da0bee81533cd8cbb04d9
QH;F
.gitshaPK
三个字符串的内容保持不变,但顺序发生了变化。因此,zip 文件的某些组件可能不完全依赖于顺序。当我可以确定如何使输出恒定时,我会进行更新。
答案2
zip 命令附加到输出 zip 文件。尝试在运行之间删除它。
更新:我自己测试了 -X ,它似乎仍然在文件中插入文件时间戳(如所示unzip -l
)
如果你看一下维基百科上的协议您可以看到日期和时间字段始终存在,然后在标头的末尾它们有空间用于特定于操作系统的字段。我想说 -X 遗漏了那些特定于操作系统的额外字段。
因此,我认为生成一致的 zip 文件的唯一方法是具有一致的时间戳。您可以尝试将文件添加到特定日期,然后再将其添加到 zip 文件。
答案3
我最终.gitsha
在根文件夹中生成了一个存储库,并且只有在它过期时才重写它。这给了我我想要的..代价是将一行代码爆炸为 20 行..
new_sha=$(git rev-parse HEAD)
if [ -f ../.gitsha ]
then
old_sha=$(cat ../.gitsha)
if [ $old_sha = $new_sha ]
then
generate=false
echo "gitsha file up to date"
else
generate=true
echo "gitsha file out of date"
fi
else
echo "git sha file missing"
generate=true
fi
if [ $generate = true ]
then
echo $new_sha > ../.gitsha
fi
代替git rev-parse HEAD > .gitsha