我经常在不同分支之间切换。我有一个脚本,将checkout的内容推送到“运行”环境中,在那里我可以看到代码的运行并进行测试(它是一个Web应用程序)。这个推送脚本的核心是使用rsync,它使用时间戳来检测应该传输哪些文件。因为“git-checkout”似乎将文件的时间戳设置为当前时间,所以rsync报告所有文件都被推送了,只是因为时间戳会更新。
如何让“git-checkout”在切换分支时保留时间戳,以便rsync仅报告内容更改?
我不想使用rsync的校验和选项,因为它非常慢。
我经常在不同分支之间切换。我有一个脚本,将checkout的内容推送到“运行”环境中,在那里我可以看到代码的运行并进行测试(它是一个Web应用程序)。这个推送脚本的核心是使用rsync,它使用时间戳来检测应该传输哪些文件。因为“git-checkout”似乎将文件的时间戳设置为当前时间,所以rsync报告所有文件都被推送了,只是因为时间戳会更新。
如何让“git-checkout”在切换分支时保留时间戳,以便rsync仅报告内容更改?
我不想使用rsync的校验和选项,因为它非常慢。
关于git checkout和时间戳的情况,Git 2.2.2+(2015年1月)应该会更好。
当执行git checkout
时,已经是最新的文件的时间戳不应再移动。
请参见Jeff King (peff
)的commit c5326bd:
git checkout $tree
”时,我们会将路径从$tree
拉取到索引中,然后将结果条目检出到工作树中。然而,我们的第一步方法相当笨重,它会覆盖整个现有的索引条目,即使内容相同也是如此。这意味着我们失去了状态信息,导致checkout_entry
稍后重新写入具有相同内容的整个文件。因此,让我们看看是否已经在索引中拥有相同的条目,如果是,则将其保留在原地,这样可以让checkout_entry
做正确的事情。我们的测试涵盖了两种有趣的情况:1.确保没有更改的文件不会被重写;2.确保我们更新了索引中未更改但具有工作树更改的文件(与$tree
相比)。我们保留旧的索引条目,checkout_entry能够意识到我们的状态信息已过期。git checkout
会更新时间戳的原因是,几乎所有源代码的构建系统都依赖于时间戳来确定目标是否需要重新构建。如果git checkout
在文件更新时不更新时间戳,则这些构建系统将无法正确进行增量构建。实际上,git checkout
只应更新已更改的文件的时间戳。
rsync
在更新时间戳时应该是高效的,并且如果仅元数据已更改,则不传输任何数据。您可以通过 "speedup" 来验证这一点。您还可以使用 -i
标志请求最近版本的 rsync
列出更改项。您可以通过省略 -a
或 -t
来告诉 rsync
不要使用时间戳(仅使用校验和),但是不推荐这样做,根据 rsync(1)
手册。
-a
或-t
标志,但是rsync
似乎仍然认为文件已更改。我不能使用--size-only
,因为即使字母发生了变化,我也需要更新文件,所以如果rsync只比较校验和,或者git保留原始修改时间,那就太完美了。有什么想法吗? - XedinUnknown看起来Git这样做的唯一原因是在DVCS环境中,您可能会使用旧的时间戳文件来更新新的时间戳文件并引起构建问题。我认为这不好,因为我们很少使用旧的时间戳文件来更新新的时间戳文件。
我认为可以以聪明的方式处理这个问题:当用文件B更新文件A时,
file_timestamp = (timestamp(B) > timestamp(A)) ? timestamp(B) : timestamp(CURRENT);
或者,这可以设计为可配置选项。