如何找到最近修改过一个文件的git提交记录?

265

我想要找到最近修改过源文件的提交记录。

我可以使用git blame命令查看每行提交的日期,但很难确定哪个提交记录是最后一个修改该文件的。

如何在我的Git代码库中找到最后一个修改给定文件的提交记录?

6个回答

341

git log可以查看特定文件(和目录)的历史记录,因此您可以像这样调用它:

git log my/file.c

如果您只想列出最近的一次提交,例如在脚本中使用它,可以使用-n 1选项:

git log -n 1 --pretty=format:%H -- my/file.c

--pretty=format:%h 告诉 git log 只显示提交哈希值。-- 分隔符将文件名与提交名称分开,以防止其模糊不清。


18
如果您想了解文件的最后修改时间,无论分支如何,可以通过添加“--all”选项来考虑所有分支。 - K. C.
如果有人在这里拥有足够的声誉来进行一次单字符编辑操作,那么现在该答案中的URL已经有了https版本。 - AJM
我需要在文件路径前添加“--”,例如:git log -- my/file.c - FeifanZ
请注意,此代码仅适用于静态环境,也就是说,如果重新克隆您的存储库,则提交哈希值将会更改。 - dzona
@dzona 你说“如果重新克隆你的仓库,提交哈希将会改变”。听起来不对,每个新的克隆中提交哈希是相同的。 - undefined

79
如果您只想找到最新的提交,则不需要使用git-log,而是需要使用git-rev-list,它会列出更改该文件的提交对象,按时间顺序从最近的开始。简单来说:
git rev-list -1 对于您的情况中的git-rev-list,您只需提供:
- 要包括的提交数,或者-1仅获取最近的提交 - 要从头开始查找的分支(或提交ID),如果您已经在HEAD上,则为HEAD,如果要获取所有已知提交,则为--all - 您的文件的相对路径
这将返回当前分支中最近更改该文件的提交ID,例如:215095e2e338525be0baeeebdf66bfbb304e7270。
对于更复杂的示例,您可以使用标签名称,甚至远程引用,并包括带通配符的相对路径,例如:

git rev-list origin/user/bob/testbranch -1 src/bfiles/*.txt

这个命令会告诉你在该分支历史记录中通配符匹配的最近更改是什么。rev-list 命令的选项极其丰富,它是最重要的基础命令之一,因此您可以根据几乎任何想象得到的标准进行包含或排除。

当然,请参考 git-rev-list(1) 手册页

1
你真的没有解释为什么使用 git-log 是劣质的。 - Piotr Dobrogost
12
我不会说它是低劣的,只是默认提供了不必要的信息。git-rev-list仅返回提交ID,如果您打算将响应馈送到脚本或其他自动化过程中,则这正是您想要的。git-log返回所选提交的信息,首先使用git-rev-list来收集提交ID,然后收集每个提交的信息。如果您只是要过滤掉提交信息并使用ID,则可以直接使用git-rev-list。由于日志基于rev-list,因此它使用大多数相同的筛选参数。 - Michael Erickson
10
git-log 是瓷器化命令,git-rev-list 是管道化命令。 - blitzen9872
请注意,如果您合并了来自不同分支的提交,则此方法将无法为您提供合并提交(正如我所预期的那样,因为它是将此更改引入我的分支的提交),而是合并的原始提交。这只是需要记住的一些事情。我还没有找到获取合并提交的命令,但我相信肯定有这样的命令。 - SvenS

30

如果您只想获取修改特定文件集的最新提交的哈希值(并希望避免使用 awk),则可以使用:

git log -n 1 --pretty=format:%h -- <path>

这可以帮助获取提交哈希值,以便随后在git describe中使用。

例如(如果对任何人有用的话)...

我通过考虑更改任何源文件的最新提交来创建当前版本ID(假设您使用标记,如mycode-1.2.1来标识版本):

COMMIT=$(git log -n 1 --pretty=format:%h -- *.c *.h)
if VN=$(git describe --always --abbrev=5 --match "mycode-*" $COMMIT 2>/dev/null) &&
case "$VN" in
mycode-*)
    git update-index -q --refresh
    test -z "$(git diff-index --name-only HEAD *.c *.h)" ||
    VN="$VN-mod" ;;
*) VN="mycode-unknown-g$VN" ;;
esac
then
    continue
else
VN="mycode-unknown"
fi

这将生成如下id:

  • mycode-1.2.1 - 当源文件的当前状态对应于已标记的版本时
  • mycode-1.2.1-g3k7s2 - 当源文件的当前状态对应于已标记版本之后的提交时
  • mycode-1.2.1-g3k7s2-mod - 当源文件的当前状态自上次已标记版本之后有所修改时
  • mycode-unknown - 当尚未创建版本标签时

6
$VN 看起来像是某种噩梦般的不死版本控制系统 SVN。 - ThorSummoner

10

我不确定这是否符合您的要求,但是如果您运行 git log <thefile> 命令,可以获取更改过该文件的提交记录。您可以选择最新的那个提交,它应该就是您要找的。


4
如果你使用 git log -n1 -- <thefile> (或者将输出管道传递给 head -1 如果你想浪费资源)你就不必手动选择顶部的行(参见 Jo Liss 的答案)。 - Tobias Kienzler
4
好主意。我认为你可以直接跳过“-n”,并直接使用“-1”。 - Noufal Ibrahim

3

如果你想查看某次提交的SHA id,可以使用git log FILENAME,然后使用git show SHA_ID_HERE查看该次提交的信息。你甚至不需要输入完整的ID,前6个字符就足够了。


4
虽然这比 OP 要求的要多一点,但是你可以将其组合成一个单行命令:git show $(git log -1 --pretty="%H" -- FILENAME) - Tobias Kienzler

3

如果只需将引用放在一行中,请尝试以下操作:

git log -n1 --oneline <path> | awk '{print $1;}'

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