如何在Git仓库中打印每个文件的最后一次提交信息

17

我有一个脚本,可以从我的远程服务器的git库复制一些文件。对于每个被复制的文件,如果它在版本控制中,我想要生成一行,例如:

Filename: <filename>, commit: <last-commit-hash>, date: <date of last commit>

我的想法是将这些行存储在文件中,并将其复制到远程服务器上。这样我就可以始终知道服务器上的哪个文件属于我的 git 存储库中的哪个提交。 有没有快速的方法来做到这一点?

3个回答

20

我对这个东西的用处持怀疑态度,因为你总是可以从本地仓库或GitWeb中获取信息,但是既然在这里了,那就给你:

git ls-files | while read file; do git log -n 1 --pretty="Filename: $file, commit: %h, date: %ad" -- $file; done

%h会给你一个简略的哈希值;如果你想要完整的哈希值,可以使用%H。你也可以通过--date=local|iso|rfc|short调整日期格式(详见git-log手册页面)。


我有一个HTML/JavaScript演示。我将其发布到我的网站上,让人们玩耍,同时我继续开发它。由于这是一个早期演示,我不想使用标签;因为我每两天发布一次,我会有大量的标签,这会让人感到困惑。我只在我感觉演示有点稳定时更新它。 但是,每当有人发现错误或问题时,我想确切地知道我的“已发布”文件的版本,这样我就可以将它们与我的HEAD进行比较,看看它是否是我已经修复的错误。 - janesconference
1
@janesconference:所以你真正关心的只是你发布的提交。那个哈希值完全足够展示每个文件的版本。使用git checkout <sha1>将整个工作树恢复到该状态,或者使用git show <sha1>:<path>查看一个文件的内容。 - Cascabel
1
@janesconference:或者比较起来,git diff <published-commit> HEAD <file>。真的没有必要知道它上次更改的时间。 - Cascabel
嗯,你说得对。我错误地认为如果我提交了file1,然后两天后再提交file2,然后将所有内容推送到远程存储库,那么最后一个提交的哈希值(其中我提交了file2)仅会涉及我在file2中所做的更改(而不是file1)。我错了,对吧? - janesconference
@janesconference:是的,Git不像CVS/SVN那样有版本号。一个提交包含了所有东西:一些元数据和对整个工作树快照的引用。 (有一些内部细节,但现在它们并不重要。) - Cascabel
显示剩余3条评论

8

我在#git频道和几个人聊过这个问题,其中一个人(谢谢Mikachu)找到了这个Perl脚本,它有正确的算法但是实现存在一些严重的缺陷。

所以我修复了这个脚本中的问题,大幅度整理了代码,并生成了结果 (从这里下载)。注意,它当前需要Term::ANSIColor才能运行。下面可以看到它运行的截图:

screenshot of git-ls-dir runs
(来源:adamspiers.org)

希望这对你有所帮助!


0

这种方法更快,而且可以按年龄排序:

find <dir> -exec git log -n 1 --pretty="%ai {}" "{}" \; | sort -r

这并没有回答问题,因为它没有生成任何Git提交信息。 - henrebotha
而且在任何时候都没有显示git log的结果。它打印的每一行看起来像2019-03-08 17:20:47 +0100 ./keymaps/henrebotha/keymap.c,其中不包含提交哈希、分支名称或与Git相关的其他任何内容。 - henrebotha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接