git 提交后,尽管存档内容未更改,但 zip 文件的 Sha256 哈希值有所不同?
Sha256 hash of a zip file is different after git commit despite archive contents not changing?
我正在使用 git 存档从存储库中的某个项目文件夹 src
导出源代码,以便计算其组合的 sha256 哈希值,如下所示:
git archive HEAD --worktree-attributes -o project-archive.zip src/
sha256sum project-archive.zip | awk '{ print }' > project-archive.zip.hash
我的 git 属性文件位于项目的根目录下,看起来有点像这样:
integration_tests/ export-ignore
src/unit_tests export-ignore
src/.* export-ignore
.git* export-ignore
.config.yml export-ignore
*.md export-ignore
这很适合计算我的源的哈希值,但我发现对未包含在存档中的项目文件的修改,例如 .config.yml
和 integration_tests/foo.py
仍然会修改存档的哈希值。
存档本身没有任何错误文件。
每个 .py
文件的 sha256 哈希未更改。
我只有在提交
不相关的(未存档的)更改,所以我认为这是 git 行为或对
git 我的属性配置。
大概源文件上有一些我不知道的 git 元数据会影响存档哈希?
来自the git archive
documentation:
git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead. Additionally the commit ID is stored in a global extended pax header if the tar format is used; it can be extracted using git get-tar-commit-id. In ZIP files it is stored as a file comment.
(所有粗体都是我的)。由于您通过 HEAD
提供提交 ID,因此该提交 ID 作为文件注释存储在 zip 存档中。如果你压缩两个不同的提交,在压缩之后,除了这个文件注释哈希 ID 之外是相同的,那么压缩文件的整体校验和将不同。 (去掉散列 ID 和 zip 文件的整体校验和应该匹配,除了下面的时间戳问题。)
一个解决方案很明显:提供提交的树 ID 而不是 HEAD
,例如,使用 HEAD^{tree}
。不幸的是,这会立即 运行 你进入第一个非粗体句子:当前时间用作存档中每个文件的修改时间。 所以你必须将计算机时钟调回。您可以按字面意思继续使用 HEAD
,但是您将获得新的 HEAD
提交时间,而不是之前的 HEAD
提交时间,这又会导致同样的问题。
如果有某种方法可以使用现有存档在新存档上重新设置时间戳,或者如果您可以比较没有时间戳的文件(如果所有文件都被删除,则切换回旧存档)相同)或计算存档的哈希值减去时间戳,即可完成工作。
git archive
没有任何参数可以实现您想要的。修改 Git 源本身可以让你指定一个特定的时间戳;参见 this region of the source code。
我正在使用 git 存档从存储库中的某个项目文件夹 src
导出源代码,以便计算其组合的 sha256 哈希值,如下所示:
git archive HEAD --worktree-attributes -o project-archive.zip src/
sha256sum project-archive.zip | awk '{ print }' > project-archive.zip.hash
我的 git 属性文件位于项目的根目录下,看起来有点像这样:
integration_tests/ export-ignore
src/unit_tests export-ignore
src/.* export-ignore
.git* export-ignore
.config.yml export-ignore
*.md export-ignore
这很适合计算我的源的哈希值,但我发现对未包含在存档中的项目文件的修改,例如 .config.yml
和 integration_tests/foo.py
仍然会修改存档的哈希值。
存档本身没有任何错误文件。
每个
.py
文件的 sha256 哈希未更改。我只有在提交 不相关的(未存档的)更改,所以我认为这是 git 行为或对 git 我的属性配置。
大概源文件上有一些我不知道的 git 元数据会影响存档哈希?
来自the git archive
documentation:
git archive behaves differently when given a tree ID versus when given a commit ID or tag ID. In the first case the current time is used as the modification time of each file in the archive. In the latter case the commit time as recorded in the referenced commit object is used instead. Additionally the commit ID is stored in a global extended pax header if the tar format is used; it can be extracted using git get-tar-commit-id. In ZIP files it is stored as a file comment.
(所有粗体都是我的)。由于您通过 HEAD
提供提交 ID,因此该提交 ID 作为文件注释存储在 zip 存档中。如果你压缩两个不同的提交,在压缩之后,除了这个文件注释哈希 ID 之外是相同的,那么压缩文件的整体校验和将不同。 (去掉散列 ID 和 zip 文件的整体校验和应该匹配,除了下面的时间戳问题。)
一个解决方案很明显:提供提交的树 ID 而不是 HEAD
,例如,使用 HEAD^{tree}
。不幸的是,这会立即 运行 你进入第一个非粗体句子:当前时间用作存档中每个文件的修改时间。 所以你必须将计算机时钟调回。您可以按字面意思继续使用 HEAD
,但是您将获得新的 HEAD
提交时间,而不是之前的 HEAD
提交时间,这又会导致同样的问题。
如果有某种方法可以使用现有存档在新存档上重新设置时间戳,或者如果您可以比较没有时间戳的文件(如果所有文件都被删除,则切换回旧存档)相同)或计算存档的哈希值减去时间戳,即可完成工作。
git archive
没有任何参数可以实现您想要的。修改 Git 源本身可以让你指定一个特定的时间戳;参见 this region of the source code。