我正在尝试找到一个命令来获取本地 git 存储库中文件的最后修改日期。
我已经创建了存储库并完成了一次提交。我只需要编辑一个文件并提交它,但我想知道存储库中文件的最后修改数据是什么(不是提交日期)。
我只有命令行,并且
git log ./path/to/filename.php
只给我提交日期
正确的做法是使用 git log,如下所示。
git log -1 --pretty="format:%ci" /path/to/repo/anyfile.any
-1 将其限制为文件最后一次更改的时间
%ci 只是您可以从其他日期格式中选择的一种,网址为 https://git-scm.com/docs/pretty-formats
获取最后修改的时间戳
git log -1 --pretty="format:%ct" /path/to/repo/anyfile.any)
MitchellK 的答案完全符合我的需求,将我的本地文件的最后写入时间设置为 git 中的时间。这是一个用于自动化该过程的 C# LinqPad 脚本:
var root = new DirectoryInfo(@"C:\gitlab\mydirectory\");
Directory.SetCurrentDirectory(root.FullName); // Give git some context
var files = root.GetFiles("*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
var results = Util.Cmd("git",
$"log -1 --pretty=\"format:%ci\" \"{file.FullName}\"",
true);
var lastUpdatedString = results.FirstOrDefault();
if (lastUpdatedString == null)
{
Console.WriteLine($"{file.FullName} did not have a last updated date!!");
continue;
}
var dt = DateTimeOffset.Parse(lastUpdatedString);
if (file.LastWriteTimeUtc != dt.UtcDateTime)
{
Console.WriteLine($"{file.FullName}, {file.LastWriteTimeUtc} => {dt.UtcDateTime}");
file.LastWriteTimeUtc = dt.UtcDateTime;
}
else
{
Console.WriteLine($"{file.FullName} already updated.");
}
}
问题的关键是,您是否想要查看文件的上次修改时间戳,或者是否想要更改文件的时间戳为您认为应该的内容(例如,上次修改时间)?从问题来看,OP似乎希望看到文件的时间戳,而不一定要操纵它。
TL;DR: 只需运行此命令,
git ls
将显示 pwd 中所有文件的最后修改时间。 注意: $'
是 命令的一部分, 因此请复制整行
$'!cd -- ${GIT_PREFIX:-.};\nfor i in *; \ndo \n ls -ld $i | awk \'BEGIN { ORS="";} {print $1, $2, $3, $4; printf("%7s ",$5)}\'; \n gd=$(git log -1 --date=local --format="%ad" -- "$i"); \n [ -z "$gd" ] && gd=$(ls -ld "$i" | awk \'{print $6, $7, $8}\'); \n if [ $(date -d "$gd" +%s) -le $(date -d "6 months ago" +%s) ] ; \n then dfmt=\'%b %_d %Y\'; \n else dfmt=\'%b %_d %H:%M\'; \n fi; \n echo -n "$(date -d "$gd" +"$dfmt") "; \n ls -d --color=always "$i"; \ndone'
对我来说,我只想看到最后修改的日期,而不是去搞乱文件系统上的实际时间戳。
因此,我费心编写了一个 bash 脚本,它为我提供了
ls
样式的输出,该输出显示 git 存储库的最后修改日期(即作者的时间戳),而不是磁盘上的时间戳。这是一个相当粗糙的剪辑,但它按照我想要的方式工作。
cd -- ${GIT_PREFIX:-.};
for i in *;
do
ls -ld $i | awk 'BEGIN { ORS="";} {print $1, $2, $3, $4; printf("%7s ",$5)}';
gd=$(git log -1 --date=local --format="%ad" -- "$i");
[ -z "$gd" ] && gd=$(ls -ld "$i" | awk '{print $6, $7, $8}');
if [ $(date -d "$gd" +%s) -le $(date -d "6 months ago" +%s) ] ;
then dfmt='%b %_d %Y';
else dfmt='%b %_d %H:%M';
fi;
echo -n "$(date -d "$gd" +"$dfmt") ";
ls -d --color=always "$i";
done
将此文件另存为,例如 ~/scripts/git-ls。假设这是您使用的路径,然后使用
导入到您的 git 配置中echo "git config --global alias.ls $(printf '%q' "`echo -n \!; cat ~/scripts/git-ls`")" | bash -
它构建
git config
命令,然后将其交给 bash 子 shell 来执行。
优点:
ls
输出完全一样git help ls
仍然将定义显示为可读脚本缺点:
git ls
还是只是运行 ls
grep
ls
Git 不记录最后修改日期,只记录所有提交的提交/作者日期(可以包含多个文件)。
您需要运行一个脚本才能使用特定文件的最后修改日期修改提交(如果所述提交包含多个文件,则不是很有用)。
请参阅“Git:推送后更改时间戳”中的示例。
另一种选择是将这些时间戳记录在单独的文件中,并以这种方式修改您的提交:请参阅“git 的 use-commit-times 的等效项是什么?”。
其中包括:
- 核心脚本提供 3 个选项:mtimestore
(保存全部 - 用于在现有存储库中进行初始化(适用于熟悉 git 的文件)),-a
(保存分阶段更改)和-s
恢复它们。-r
- 预提交挂钩
- 结账后挂钩
顺便说一句,这是我在 5 年前解释过的帖子为什么 Git 不记录时间戳。
这是 Randall 的答案 的一个版本,适用于我在 macOS 12.4 上使用 zsh:
for i in *;
do
ls -ld $i | awk 'BEGIN { ORS="";} {print $1, $2, $3, $4; printf("%7s ",$5)}';
gd=$(git log -1 --date=local --format="%ad" -- "$i");
if [ -z "$gd" ] ;
then printf " --------------------------- $i\n";
else
dfmt="%a %b %d %T %Y";
printf "$(date -j -f "$dfmt" "$gd" "%+%Y") ";
ls -d --color=always "$i";
fi;
done
大部分差异在于
date
命令,在 Mac 上似乎有所不同。如果文件在 git 中没有与之关联的日期,我还选择打印出破折号(我觉得这比使用本地文件系统的日期更容易混淆)。
正如 Randall 提到的,您可以通过将其保存到像
~/scripts/git-ls
这样的文件然后运行来轻松添加 git 别名:
echo "git config --global alias.ls $(printf '%q' "`echo -n \!; cat ~/scripts/git-ls`")" | bash -