git克隆更改文件修改时间

git克隆更改文件修改时间,git,clone,Git,Clone,当我使用“git clone…”命令克隆git存储库时,本地存储库中的所有克隆文件的修改时间与发出git clone命令的日期和时间相同 是否有一种方法可以克隆远程git存储库,并为每个文件指定实际修改时间 Git,因为它是分布式VCS(意味着你的计算机上的时间可能与我的不同:没有时间和日期的“中心”概念) 解释了不记录该元数据的官方论点 但是您可以找到尝试恢复有意义的日期(或a)的脚本。您可以检索git存储库中所有文件的最后修改日期。(lat提交时间) 然后使用触摸命令更改修改日期 git-

当我使用“
git clone…
”命令克隆git存储库时,本地存储库中的所有克隆文件的修改时间与发出
git clone
命令的日期和时间相同

是否有一种方法可以克隆远程git存储库,并为每个文件指定实际修改时间

Git,因为它是分布式VCS(意味着你的计算机上的时间可能与我的不同:没有时间和日期的“中心”概念)

解释了不记录该元数据的官方论点


但是您可以找到尝试恢复有意义的日期(或a)的脚本。

您可以检索git存储库中所有文件的最后修改日期。(lat提交时间)

然后使用
触摸
命令更改修改日期

git-ls-tree-r——读取文件名时仅命名头;做
unixtime=$(git log-1--format=“%at”--“${filename}”)
touchtime=$(日期-d@$unixtime+“%Y%m%d%H%m.%S”)
touch-t${touchtime}“${filename}”
完成
这也是我的要点

2019年10月更新 感谢您的评论。

我已经更新了答案和要点,以支持带有空格的文件名

这个linux one liner将修复所有文件(不是文件夹-只是文件)-它还将修复其中包含空格的文件:-

git ls-files -z | xargs -0 -n1 -I{} -- git log -1 --format="%ai {}" {} | perl -ne 'chomp;next if(/'"'"'/);($d,$f)=(/(^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d(?: \+\d\d\d\d|)) (.*)/);print "d=$d f=$f\n"; `touch -d "$d" '"'"'$f'"'"'`;' 
我觉得更容易理解的一个简短的答案:

git ls-files | xargs -I{} git log -1 --date=format:%Y%m%d%H%M.%S --format='touch -t %ad "{}"' "{}" | $SHELL

重置mtime的另一个选项是

sudo-apt安装git-restore-mtime#Debian/Ubuntu示例
git克隆
光盘
git恢复时间

添加到一行程序列表中

用于f,单位为$(git ls文件);dotouch-d$(gitlog-1--格式=“%aI'”$f”)“$f”;完成

适用于上述多种解决方案:


使用
%at
格式,然后使用
touch-d\@$epochdelta
,以避免日期-时间转换问题。

每个文件运行
log-1
一次会让我感到厌烦,所以我写了这篇文章,一次完成所有任务:

( # don't alter any modified-file stamps:
  git diff --name-status --no-find-copies --no-renames | awk '$1="D"' FS=$'\t' OFS=$'\t'
  git log --pretty=%cI --first-parent --name-status -m --no-find-copies --no-renames
) | awk ' NF==1 { date=$1 }
          NF<2 || seen[$2]++ { next }
          $1!="D" { print "touch -d",date,$2 }' FS=$'\t'
(#不要更改任何已修改的文件戳记:
git diff--名称状态--没有找到副本--没有重命名| awk'$1=“D”'FS=$'\t'OFS=$'\t'
git日志--pretty=%cI--第一个父级--名称状态-m--找不到副本--没有重命名
)| awk'NF==1{date=$1}


NF这是操作系统问题,而不是Git问题。您可以从
Git log-n1--file
获取上次修改的时间;这就是git的目的。我不太明白“git就是为了这个”的说法。为什么是国防部。时间不会像在CVS中那样保存?@Amadan:您只会获得上次提交时间,而不是上次修改文件的时间。@Turn这不是问题。。。程序可以更改所创建文件的修改时间,因此这是程序的选择,但它可以节省远程端的本地时间。当基于修改时间编译文件时,我如何解决构建问题?好的,谢谢回复和建议的解决方案。我看到了讨论,但由于git是版本控制系统,所以不保存mod时间的论点在我看来并不强烈。我使用CVS已经很多年了,它有这个特性,而且不会伤害它。实际上,简单的ls-ltr命令显示了从CVS存储库签出的修改文件的顺序。构建依赖于文件的修改时间这一事实实际上是不将其存储为元数据的一部分的原因。如果mtime更新为提交时间,那么您必须在签出较旧的提交后启动一个干净的构建,因为文件将被视为比相应的派生文件旧,并且不会导致重新构建它们。(显然,假设构建系统依赖于mtime。)它可以节省UTC时间,不是吗?@VonC,你永远无法保证你的时间是正确的。但这不是放弃使用时间的理由。太棒了!工作起来很有魅力。对我们来说,这是至关重要的,这样我们就可以加快基于
Makefile
的构建。这就是答案。除了一个更改,如果文件名带有空格,您应该在$filename周围添加引号。@P.T.我看到现在已经添加了引号。这是怎么回答的。。您可以说“您可以检索git存储库中所有文件的最后修改日期(lat提交时间)”@barlop git history并不总是实际编辑的历史,它可以通过修改和重新设置-i来修改。这是作者选择呈现的一段逻辑历史,在其中,提交是对一组文件的逻辑原子的同时更改。如果您想记录“file1在file2之前更改”,那么它们之间必须存在一个点-这些必须是单独的提交。非常非常好。酷!!!!在我看来,不幸的是,有些文件可能还没有用这个解决方案转换。例:1。包含字符
'
(39 0027'撇号)的文件,2。存储库根目录中的文件,3。包含
(也可以是
)的文件。也许你也可以抽出时间来看看这些具体的案例?这是从git repo检索的,所以只能给出提交日期。不是实际的文件上次修改日期/时间。
( # don't alter any modified-file stamps:
  git diff --name-status --no-find-copies --no-renames | awk '$1="D"' FS=$'\t' OFS=$'\t'
  git log --pretty=%cI --first-parent --name-status -m --no-find-copies --no-renames
) | awk ' NF==1 { date=$1 }
          NF<2 || seen[$2]++ { next }
          $1!="D" { print "touch -d",date,$2 }' FS=$'\t'