【问题标题】:How to have 'git log' show filenames like 'svn log -v'如何让“git log”显示像“svn log -v”这样的文件名
【发布时间】:2010-11-16 20:03:56
【问题描述】:

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

jes5199$ svn log -v
-------------------------------------------------- ----------------------
r1 | jes5199 | 2007-01-03 14:39:41 -0800(2007 年 1 月 3 日,星期三)| 1 行
改变的路径:
   /作者
   A /复制
   A /变更日志
   /进化
   /安装
   一个/MacOSX

有没有一种快速的方法来获取 Git 中每次提交中更改文件的列表?

【问题讨论】:

  • 想知道为什么git log 不像很多人期望/想要的那样只支持-v 开关吗?

标签: svn git logging


【解决方案1】:

这个简短的命令对于列出每次提交更改的所有文件非常有帮助。

git log --name-only --oneline

--仅名称

仅显示更改文件的名称。文件名通常编码为 UTF-8。有关更多信息,请参阅有关编码的讨论 git-log1 手册页。

--单线

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

输出

【讨论】:

    【解决方案2】:

    另一个有用的命令是git diff-tree <hash>,其中hash 也可以是一个哈希范围(用<old>..<new> notation 表示)。输出示例:

    $ git diff-tree  HEAD
    :040000 040000 8e09a be406 M myfile
    

    这些字段是:

    源模式、目标模式、源哈希、目标哈希、状态和文件名

    状态是您所期望的:D(已删除)、A(已添加)、M(已修改)等。请参阅完整描述的手册页

    【讨论】:

    • 我试过这个,但它只为 repo 根目录中的文件提供了 M 状态。所以对于目录中的文件,它只会给出 ":xxxx yyy zzz aaa M dirname"
    【解决方案3】:

    git show 也是一个很棒的命令。

    有点像svn diff,但你可以传递一个 git commit hash 并查看差异。

    【讨论】:

    • 这不是提交的 GUID 而是它的 SHA1 哈希。
    • 也许是update your answer,地址brainplot's comment?但是没有“编辑:”、“更新:”或类似的 - 答案应该看起来好像是今天写的。
    • 已更新,对 10 多年的困惑感到抱歉 :)
    【解决方案4】:

    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 OP 的问题是关于如何“在每次提交中获取已更改文件的列表”,而不是关于 HEAD 之间的 diffmaster。这是两个不同的东西。
    【解决方案5】:

    我通常使用这些来获取日志:

    $ git log --name-status --author='<Name of author>' --grep="<text from Commit message>"
    
    $ git log --name-status --grep="<text from Commit message>"
    

    【讨论】:

    • 我不知道这些选项,但是如果这篇文章解释它过滤日志会更有用。有那么一刻,我认为这是一种改变作者在输出中的列出方式的方法。
    【解决方案6】:

    我发现以下是以简洁的格式列出每次提交更改的文件的理想显示:

    git log --pretty=oneline --graph --name-status
    

    【讨论】:

    【解决方案7】:

    对于已更改文件的完整路径名:

    git log --name-only
    

    对于已更改文件的完整路径名和状态:

    git log --name-status
    

    对于缩写的路径名和更改文件的差异统计:

    git log --stat
    

    还有很多选择。 Check out the documentation.

    【讨论】:

    • 我使用git log --numstat。请参阅git help log 了解更多选项。
    • git log --name-only --oneline 也非常漂亮 - 一个彩色行用于提交,每行一个文件。 stackoverflow.com/a/14227496/1995714
    • 在 git 2.7.3 中,我不得不使用 git log --name-status --find-renames 来显示重命名的文件,而不是添加 + 删除。
    • 注意--stat 是长路径的缩写;宽度是可配置的,但包装直方图更难阅读。 --numstat 等其他格式始终打印完整路径。
    • @ma11hew28 谢谢。从 git 2.22.00 开始,--numstat 位于该手册页的第 946 行。这比大多数人需要的选择多很多
    【解决方案8】:

    带有示例输出的答案摘要

    这是使用具有五个简单提交的本地存储库。

    ‣ 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 whatchanged 已弃用,请改用 git log

      鼓励新用户使用 git-log[1] 代替。这 whatchanged 命令本质上与 git-log[1] 但默认显示 原始格式差异输出并跳过合并。

      保留该命令主要是出于历史原因;许多人的手指 早在git log 被阅读发明之前就学过 Git 的人 Linux 内核邮件列表经过训练可以输入。


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

      参考文献

      【讨论】:

        【解决方案10】:

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

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

        为了简短起见,请在您的 .gitconfig 中添加别名:

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

        【讨论】:

        • 我的非常接近,git log --pretty=oneline --graph --name-status。我觉得它更简洁,只显示更改的文件列表。
        • @谢谢,--stat 标志部分会显示文件和更改文件的总统计信息数,而您的 --name-status 部分类似,但更好的是,只显示文件
        【解决方案11】:

        我用这个:

        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
        ...
        

        【讨论】:

          【解决方案12】:

          如果您只想获取文件名而不获取提交消息的其余部分,您可以使用:

          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
          

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

          【讨论】:

          • 请注意以上示例中的空格 - 就像 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)
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2015-04-02
          • 1970-01-01
          • 2017-06-19
          • 1970-01-01
          • 2011-12-05
          • 2012-12-06
          • 2012-12-21
          相关资源
          最近更新 更多