Git克隆更改文件修改时间

内容来源于 Stack Overflow,遵循 CC BY-SA 4.0 许可协议进行翻译与使用。IT领域专用引擎提供翻译支持

腾讯云小微IT领域专用引擎提供翻译支持

原文
Stack Overflow用户 修改于2021-10-23
  • 该问题已被编辑
  • 提问者: Stack Overflow用户
  • 提问时间: 2014-02-13 01:39

当我使用" git clone ... “命令克隆一个Git仓库时,我本地仓库中的所有克隆文件都具有与发出 git clone 命令时相同的修改时间和日期和时间。

有没有一种方法可以用每个文件的实际修改时间克隆远程Git存储库

浏览 340 关注 0 得票数 50
  • 得票数为Stack Overflow原文数据
原文
修改于2017-05-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2014-02-13 02:04
得票数 33

Git,因为它是分布式 does not record timestamp for the files (这意味着你计算机上的时间可以与我的不同:没有时间和日期的“中心”概念)

不记录元数据的官方论据解释为 in this answer

但是您可以找到尝试恢复有意义的日期、 like this one (或 simpler version of the same idea )的脚本。

修改于2021-10-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2019-04-10 18:10
得票数 22

您可以检索Git存储库中所有文件的最后修改日期(上次提交时间)。参见。

然后使用 touch 命令更改修改日期:

git ls-tree -r --name-only HEAD | while read filename; do
  unixtime=$(git log -1 --format="%at" -- "${filename}")
  touchtime=$(date -d @$unixtime +'%Y%m%d%H%M.%S')
  touch -t ${touchtime} "${filename}"
done

另请参阅我的gist here

修改于2021-10-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2019-08-05 11:54
得票数 7

这个Linux单行程序将修复所有文件(不是文件夹-只是文件)的问题-它也将修复包含空格的文件的问题:

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'"'"'`;'
修改于2021-10-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2020-04-02 12:38
得票数 1

我发现 user11882487's answer 的一个更短的变体更容易理解:

git ls-files | xargs -I{} git log -1 --date=format:%Y%m%d%H%M.%S --format='touch -t %ad "{}"' "{}" | $SHELL
回答于2020-10-15
得票数 9

重置mtime的另一个选项是 git-restore-mtime

sudo apt install git-restore-mtime # Debian/Ubuntu example
git clone <myurl>
cd <mydir>
git restore-mtime
操作
回答于2021-01-21
得票数 1

正在向一行程序列表中添加...

for f in $(git ls-files) ; do touch -d $(git log -1 --format='%aI' "$f") "$f" ; done
评论 0
0
修改于2021-10-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2021-03-17 00:42
得票数 0

这适用于前面多个答案中的解决方案:

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

Stack Overflow用户
修改于2021-10-23
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2021-03-17 02:00
得票数 1

对每个文件运行一次 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'

它可以在十秒内完成linux的历史记录(通过一个shell传输所有触摸命令需要一分钟)。

这是一个毁掉一分为二的好方法,我属于~甚至不要开始尝试重载文件系统时间戳的阵营,坚持这样做的人显然必须以艰难的方式学习~,但我可以看到,也许有一些工作流程,这真的不会伤害你。

管他呢。但是,可以肯定的是,不要盲目地这样做。

操作
修改于2021-11-02
  • 该回答已被编辑
  • 回答者: Stack Overflow用户
  • 回答时间: 2021-11-02 14:47
得票数 0

由于 os.utime 接受 git log 命令输出的Unix时间戳,因此在Python语言中执行此操作比其他一些选项更简单。本例使用GitPython,但它也可以与 subprocess.run 一起调用 git log

import git
from os import utime
from pathlib import Path
repo_path = "my_repo"
repo = git.Repo(repo_path)
for n in repo.tree().list_traverse():
    filepath = Path(repo.working_dir) / n.path
    unixtime = repo.git.log(
        "-1", "--format='%at'", "--", n.path