如何让 'git log' 显示文件名类似于 'svn log -v'

1242

SVN的日志有一个“-v”模式,可以输出每个提交中更改的文件名,如下所示:

jes5199$ svn log -v
------------------------------------------------------------------------
r1 | jes5199 | 2007-01-03 14:39:41 -0800(星期三,2007年1月3日)| 1 line
Changed paths:
   A /AUTHORS
   A /COPYING
   A /ChangeLog
   A /EVOLUTION
   A /INSTALL
   A /MacOSX

是否有一种快速的方法在Git中获取每个提交中更改的文件列表?


27
为什么git log不支持像很多人期望/想要的那样的-v开关呢?(抱怨) - MarkHu
13个回答

1924

获取变更文件的完整路径:

git log --name-only

获取完整路径和更改文件的状态:

git log --name-status

显示缩写路径和改变文件的差异统计:

git log --stat

还有更多选项。 查看文档


29
我使用 git log --numstat 命令。有关更多选项,请查看 git help log - ma11hew28
54
“git log --name-only --oneline”也很不错-每个提交有一行彩色线条,每行一个文件。https://dev59.com/h2Yq5IYBdhLWcg3wxTaq#14227496 - cp.engr
4
在使用 Git 2.7.3 版本时,我需要使用 git log --name-status --find-renames 命令来显示重命名的文件,而不是只显示添加和删除操作。 - Suzanne Soy
2
请注意,--stat 缩写了长路径;宽度是可配置的,但换行的直方图更难读取。其他格式(如 --numstat)始终打印完整路径。 - Beni Cherniavsky-Paskin
3
@ma11hew28 谢谢。--numstat 选项在 git 2.22.00 版本的 man 页面的第 946 行。这比大多数人需要的选项要多得多。 - Martin Schröder
显示剩余2条评论

147

注意:git whatchanged已经被弃用,建议使用git log替代。

推荐新用户使用git-log[1]代替whatchanged命令。该命令和git-log[1]基本相同,但默认显示原始格式的差异输出并跳过合并。

该命令主要出于历史原因而保留;许多在git log问世之前通过阅读Linux内核邮件列表学习Git的人都熟练地输入它。


您可以使用命令git whatchanged --stat获取每个提交更改的文件列表(以及提交消息)。

参考文献


63

git show 也是一个非常好的命令。

它有点像 svn diff,但您可以传递一个 git 提交哈希值并查看差异。


59

如果你只想获取文件名而不需要提交信息的其余部分,可以使用以下命令:

git log --name-only --pretty=format: <branch name>

然后可以将其扩展以使用包含文件名的各种选项:

git log --name-status --pretty=format: <branch name>

git log --stat --pretty=format: <branch name>

使用这种方法需要注意的一点是输出中可能有一些空行需要忽略。如果您想要查看已更改但尚未推送到远程分支且没有保证最新内容已经被拉取的本地分支中的文件,那么使用此方法会很有用。例如:

git log --name-only --pretty=format: my_local_branch --not origin/master

显示本地分支上已更改但尚未合并到远程主分支的所有文件。


1
关于上面示例中的空格 - 它就像 git log --stat --pretty="format:" $branchName。例如,git log --stat --pretty="format:" $(git rev-parse --abbrev-ref HEAD)。顺便说一下,这是与我的目的相关的确切咒语:git log --name-only --pretty="format: " master..$(git rev-parse --abbrev-ref HEAD) - floer32

51

我每天都使用它来显示更改过的文件的历史记录:

git log --stat --pretty=short --graph

简单来说,通过以下方式在.gitconfig中添加一个别名:

git config --global alias.ls 'log --stat --pretty=short --graph'

2
我的命令非常接近于那个,是git log --pretty=oneline --graph --name-status。我觉得它更加简洁,只显示了改变的文件列表。 - Peter Suwara
感谢您,--stat标志部分会显示更改的文件和总统计数字,而您的--name-status部分同样好,只显示文件。 - FantomX1
我使用 git config --global alias.shortlog 'log --pretty=oneline --graph --name-status' 为 @PeterSuwara 的版本创建了一个别名。有人知道为什么使用别名的输出与直接使用 git log --pretty=oneline --graph --name-status 的输出不同吗? - nabrown
更新:算了,我刚意识到“shortlog”已经是一个git命令了! - nabrown
那个不包括日期。 - malhal
可以设置配置,使默认的“log”输出类似于“--stat --pretty=short --graph”吗? - undefined

30

这个简短的命令非常有用,可以列出每个提交所更改的所有文件。

git log --name-only --oneline

--name-only

只显示更改文件的名称。这些文件名通常以UTF-8编码。有关编码的更多信息,请参阅git-log手册页中的讨论1

--oneline

每个提交只显示一行信息。

This is a shorthand for "--pretty=oneline --abbrev-commit" used together.

输出 Output


16

我使用这个:

git log --name-status <branch>..<branch> | grep -E '^[A-Z]\b' | sort | uniq

输出文件列表及其状态(添加、修改、删除):

A   sites/api/branding/__init__.py
M   sites/api/branding/wtv/mod.py
...

11

答案摘要及示例输出

这是使用一个本地代码仓库,其中包含了五个简单的提交记录。

‣ git log --name-only
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

file5

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

file1

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

file2
file3

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

file4

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

file1
file2
file3


‣ git log --name-status
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

R100    file4   file5

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

M       file1

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

M       file2
D       file3

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

A       file4

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

A       file1
A       file2
A       file3


‣ git log --stat
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

 file4 => file5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:36:32 2019 -0700

    foo file1

    really important to foo before the bar

 file1 | 3 +++
 1 file changed, 3 insertions(+)

commit 1b6413400b5a6a96d062a7c13109e6325e081c85
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:34:37 2019 -0700

    foobar file2, rm file3

 file2 | 1 +
 file3 | 0
 2 files changed, 1 insertion(+)

commit e0dd02ce23977c782987a206236da5ab784543cc
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:33:05 2019 -0700

    Add file4

 file4 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)

commit b58e85692f711d402bae4ca606d3d2262bb76cf1
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:32:41 2019 -0700

    Added files

 file1 | 0
 file2 | 0
 file3 | 0
 3 files changed, 0 insertions(+), 0 deletions(-)


‣ git log --name-only --oneline
ed080bc (HEAD -> master) mv file4 to file5
file5
5c4e8cf foo file1
file1
1b64134 foobar file2, rm file3
file2
file3
e0dd02c Add file4
file4
b58e856 Added files
file1
file2
file3


‣ git log --pretty=oneline --graph --name-status
* ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master) mv file4 to file5
| R100  file4   file5
* 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328 foo file1
| M     file1
* 1b6413400b5a6a96d062a7c13109e6325e081c85 foobar file2, rm file3
| M     file2
| D     file3
* e0dd02ce23977c782987a206236da5ab784543cc Add file4
| A     file4
* b58e85692f711d402bae4ca606d3d2262bb76cf1 Added files
  A     file1
  A     file2
  A     file3


‣ git diff-tree HEAD
ed080bc88b7bf0c5125e093a26549f3755f7ae74
:100644 000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0000000000000000000000000000000000000000 D  file4
:000000 100644 0000000000000000000000000000000000000000 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 A  file5


‣ git log --stat --pretty=short --graph
* commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
| Author: My Name <user@email.com>
| 
|     mv file4 to file5
| 
|  file4 => file5 | 0
|  1 file changed, 0 insertions(+), 0 deletions(-)
| 
* commit 5c4e8cfbe3554fe3d7d99b5ae4ba381fa1cdb328
| Author: My Name <user@email.com>
| 
|     foo file1
| 
|  file1 | 3 +++
|  1 file changed, 3 insertions(+)
| 
* commit 1b6413400b5a6a96d062a7c13109e6325e081c85
| Author: My Name <user@email.com>
| 
|     foobar file2, rm file3
| 
|  file2 | 1 +
|  file3 | 0
|  2 files changed, 1 insertion(+)
| 
* commit e0dd02ce23977c782987a206236da5ab784543cc
| Author: My Name <user@email.com>
| 
|     Add file4
| 
|  file4 | 0
|  1 file changed, 0 insertions(+), 0 deletions(-)
| 
* commit b58e85692f711d402bae4ca606d3d2262bb76cf1
  Author: My Name <user@email.com>

      Added files

   file1 | 0
   file2 | 0
   file3 | 0
   3 files changed, 0 insertions(+), 0 deletions(-)


‣ git log --name-only --pretty=format:
file5

file1

file2
file3

file4

file1
file2
file3


‣ git log --name-status --pretty=format:
R100    file4   file5

M       file1

M       file2
D       file3

A       file4

A       file1
A       file2
A       file3


‣ git diff --stat 'HEAD^!'
 file4 => file5 | 0
 1 file changed, 0 insertions(+), 0 deletions(-)


‣ git show
commit ed080bc88b7bf0c5125e093a26549f3755f7ae74 (HEAD -> master)
Author: My Name <user@email.com>
Date:   Mon Oct 21 15:46:04 2019 -0700

    mv file4 to file5

diff --git a/file4 b/file5
similarity index 100%
rename from file4
rename to file5

感谢 @CB-Bailey @Peter-Suwara @Gaurav @Omer-Dagan @xsor @Hazok @nrz @ptc 的贡献。


9

git diff --stat HEAD^! 显示上次提交 (HEAD) 中更改的文件和添加/删除的行数。

我认为没有单个命令可以一次性获取多个提交的文件名、添加和删除的行数等简洁输出,因此我创建了自己的 Bash 脚本:

#!/bin/bash
for ((i=0; i<=$1; i++))
do
    sha1=`git log -1 --skip=$i --pretty=format:%H`
    echo "HEAD~$i $sha1"
    git diff --stat HEAD~$(($i+1)) HEAD~$i
done

例如,可以称之为./changed_files 99,以便从HEADHEAD~99以简洁的形式获取更改。它可以被管道传输,例如到less


你难道不能使用 git diff --stat HEAD..master 来显示 HEAD 和 master 之间的差异吗?或者在你2012年回答时这个命令还不存在吗? - Ferrybig
1
@Ferrybig 的问题是关于如何“获取每个提交中已更改的文件列表”,而不是关于 HEADmaster 之间的差异。 这两件事是不同的。 - nrz

8
我发现以下显示方式是列出每次提交更改的文件的理想格式:
git log --pretty=oneline --graph --name-status

1
谢谢,这正是我在寻找的。我还建议使用漂亮的格式,如“git log --pretty="format:%n %cn %s %cr" --graph --name-status” https://hansrobo.github.io/cheatsheets/git-log-format - velocity

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