我经常在分支之间来回切换。我有一个脚本,它将结帐的内容推送到“运行”环境,在那里我可以看到代码运行并测试它(它是一个Web应用程序)。此推送脚本的核心使用rsync,它使用时间戳来检测应该传输哪些文件。由于git-checkout似乎将文件的时间戳设置为当前时间,因此rsync报告所有文件都被推送,只是因为时间戳将被更新。
如何在分支之间切换时让git-checkout保留时间戳,以便rsync仅报告内容更改?
我不想使用rsync的校验和参数,因为它非常慢。
答案 0 :(得分:8)
使用Git 2.2.2 +(2015年1月),情况(关于git checkout和timestamps)应该更好。
对于在执行git checkout
时已经是最新的文件,时间戳不应再移动。
commit c5326bd见Jeff King (peff
):
当我们"
git checkout $tree
"时,我们:
- 将路径从
$tree
拉入索引,然后- 将结果条目检查到工作树。
我们的第一步方法相当严厉;即使内容相同,它也会破坏整个现有的索引条目 这意味着我们丢失了我们的统计信息,导致
checkout_entry
以后 用相同的内容重写整个文件。相反,让我们看看我们是否已经在索引中有相同的条目,在这种情况下我们将其保留在原位。这让checkout_entry做正确的事 我们的测试包括两个有趣的案例:
- 我们确保不会重写没有更改的文件。
- 我们确保更新索引中未更改的文件(与
$tree
相比),但更改了工作树。
我们保留旧索引条目,checkout_entry能够意识到我们的统计信息已过期。
答案 1 :(得分:5)
git checkout
更新时间戳的原因是几乎所有源代码构建系统都依赖于时间戳来确定是否需要重新构建目标。如果git checkout
在更新文件时未更新文件的时间戳,则这些构建系统将无法正确执行增量构建。实际上,git checkout
应该只更新已更改的文件的时间戳。
rsync
应该有效地更新时间戳,并且如果只有元数据发生了变化,则不会传输任何数据。您可以使用“加速”来验证这一点。您还可以要求rsync
的最新版本使用-i
标记逐项列出更改。您可以通过省略rsync
或-a
告诉-t
不要使用时间戳(并且仅使用校验和),但rsync(1)
手册页不推荐这样做。
答案 2 :(得分:1)
似乎git这样做的唯一原因是在DVCS环境中,您可以使用旧的时间戳文件来更新新的时间戳文件并导致构建问题。我认为这不好,因为我们很少使用旧的时间戳文件来更新新的时间戳文件。
我认为这可以通过智能方式处理:当用文件B更新文件A时,
file_timestamp =(timestamp(B)> timestamp(A))?时间戳(B):时间戳(CURRENT);
或者,这可以设计为可配置选项。