Git for Windows - 防止 .pack 文件 date/time 修改
Git for Windows - prevent .pack file date/time modification
我正在为 Windows 使用 Git(版本 2.15,但同样的问题出现在 2.14 中,我认为旧版本也是如此)并且我注意到一个相当烦人的行为:当我执行一些基本 git 操作*),.git/objects/pack/pack-*.pack 文件的修改日期更改。文件本身保持不变,但最后修改日期字段得到更新,这导致我的备份软件认为文件已更改,需要添加到我的差异备份中。因为我的 .pack 文件相当大,这显着增加了我每日备份的大小。有没有办法防止这种行为?也就是说,保持包文件完全不变,包括它的元数据,直到我执行 git gc 或 git repack?
遗憾的是,我无法确定是哪个操作导致了此行为。今天发生的时候,我只用了 git status,git log,git add,git mv 和 git commit,没有别的,date/time 已更改,但当我尝试在昨天的备份中复制行为时,日期更改没有发生。我想下次我会 运行 进程监控并观察对文件的访问,但与此同时,有没有人知道可能导致此问题的原因?谢谢
您可以:
而不是引用您的 Git 存储库本身供您的备份程序处理(日期问题)
- 执行
git bundle
of your repo 的任务(仅生成 一个 文件)
- 您的备份程序只会备份那个文件。
这样,您就可以完全绕过这些包文件的修改日期问题。
您可以只保存并保留整个存储库捆绑包的一个副本。
或者制作增量包。
如果您尝试禁用此功能,那么您很可能会看到细微的错误,其中仍在使用的对象将从您的存储库中消失。
您无法确定确切的操作,因为 每个 添加文件的操作都会执行。
这是非常有意的 - Git 刷新数据库中对象的时间戳(更新松散对象或包文件上的时间戳)以了解上次写入对象的时间。每当您创建新提交时,它都会更新所有包含被引用对象的文件的时间戳。
这很重要,因为它有助于删除数据的工具(如修剪)避免竞争条件:一个对象可能会被取消引用然后重新引用。 Prune 还会查看时间戳,因此通过触摸文件,它将不符合垃圾收集的条件。
最终证明 Edward Thomson 的回答解释了为什么没有 "real" 解决方案是可能的。但是,为了满足我的需求,我编写了一个简单的 Windows command-line 应用程序,它扫描目录树,找到可能的 Git 个存储库,找到它们的包文件并更改 date/time每个 .pack 文件到相应的 .idx 文件。到目前为止似乎运行 OK。无论如何,我还没有遇到任何垃圾收集问题。我还没有发布这个工具,因为我怀疑没有人关心,但如果有人感兴趣,我可以上传到某个地方。
显然,有人感兴趣。因此,该程序现已发布。不在 GitHub 上,但仍然是开源的,在 3 条款 BSD 许可下。在此处下载二进制文件:https://www.pepak.net/files/git/gitpacksync-0.01.zip
和这里的源代码:https://www.pepak.net/files/git/gitpacksync-0.01-source.zip
我正在为 Windows 使用 Git(版本 2.15,但同样的问题出现在 2.14 中,我认为旧版本也是如此)并且我注意到一个相当烦人的行为:当我执行一些基本 git 操作*),.git/objects/pack/pack-*.pack 文件的修改日期更改。文件本身保持不变,但最后修改日期字段得到更新,这导致我的备份软件认为文件已更改,需要添加到我的差异备份中。因为我的 .pack 文件相当大,这显着增加了我每日备份的大小。有没有办法防止这种行为?也就是说,保持包文件完全不变,包括它的元数据,直到我执行 git gc 或 git repack?
遗憾的是,我无法确定是哪个操作导致了此行为。今天发生的时候,我只用了 git status,git log,git add,git mv 和 git commit,没有别的,date/time 已更改,但当我尝试在昨天的备份中复制行为时,日期更改没有发生。我想下次我会 运行 进程监控并观察对文件的访问,但与此同时,有没有人知道可能导致此问题的原因?谢谢
您可以:
而不是引用您的 Git 存储库本身供您的备份程序处理(日期问题)- 执行
git bundle
of your repo 的任务(仅生成 一个 文件) - 您的备份程序只会备份那个文件。
这样,您就可以完全绕过这些包文件的修改日期问题。
您可以只保存并保留整个存储库捆绑包的一个副本。
或者制作增量包。
如果您尝试禁用此功能,那么您很可能会看到细微的错误,其中仍在使用的对象将从您的存储库中消失。
您无法确定确切的操作,因为 每个 添加文件的操作都会执行。
这是非常有意的 - Git 刷新数据库中对象的时间戳(更新松散对象或包文件上的时间戳)以了解上次写入对象的时间。每当您创建新提交时,它都会更新所有包含被引用对象的文件的时间戳。
这很重要,因为它有助于删除数据的工具(如修剪)避免竞争条件:一个对象可能会被取消引用然后重新引用。 Prune 还会查看时间戳,因此通过触摸文件,它将不符合垃圾收集的条件。
最终证明 Edward Thomson 的回答解释了为什么没有 "real" 解决方案是可能的。但是,为了满足我的需求,我编写了一个简单的 Windows command-line 应用程序,它扫描目录树,找到可能的 Git 个存储库,找到它们的包文件并更改 date/time每个 .pack 文件到相应的 .idx 文件。到目前为止似乎运行 OK。无论如何,我还没有遇到任何垃圾收集问题。我还没有发布这个工具,因为我怀疑没有人关心,但如果有人感兴趣,我可以上传到某个地方。
显然,有人感兴趣。因此,该程序现已发布。不在 GitHub 上,但仍然是开源的,在 3 条款 BSD 许可下。在此处下载二进制文件:https://www.pepak.net/files/git/gitpacksync-0.01.zip 和这里的源代码:https://www.pepak.net/files/git/gitpacksync-0.01-source.zip