如何在Git存储库中列出一个目录以及每个目录项的最新提交信息?

如何在Git存储库中列出一个目录以及每个目录项的最新提交信息?,git,Git,我想列出Git存储库中的一个目录以及每个目录项的最新提交信息。与GitHub显示目录的方式或viewvc在SVN/CVS存储库中显示目录的方式类似 目前我是这样做的: 使用git ls tree master获取目录条目,并从输出中解析目录结构 然后对每个目录条目执行以下操作:git log-n1 master--filename,并解析其中的提交信息(我指定了一个特殊的格式字符串以简化此操作,但这与我的问题无关) 很明显,这非常慢,因为我必须为每个文件调用Git。有没有更快的方法?也许我可以执

我想列出Git存储库中的一个目录以及每个目录项的最新提交信息。与GitHub显示目录的方式或viewvc在SVN/CVS存储库中显示目录的方式类似

目前我是这样做的:

  • 使用
    git ls tree master
    获取目录条目,并从输出中解析目录结构

  • 然后对每个目录条目执行以下操作:
    git log-n1 master--filename
    ,并解析其中的提交信息(我指定了一个特殊的格式字符串以简化此操作,但这与我的问题无关)


  • 很明显,这非常慢,因为我必须为每个文件调用Git。有没有更快的方法?也许我可以执行一个命令,一次获得我需要的所有数据?

    你也许可以解析
    git whatchanged master
    ,继续在历史中倒退,直到“看到”所有文件路径


    根据您的历史记录的长度和某些文件的使用时间,这可能会更快。

    您可以请求
    git log-n 1
    。因此,您可以在非递归模式下解析git ls树,只需在您所在级别的每个文件/目录中运行它。

    Oneliner要解析
    git whatchanged
    输出并打印带有最近提交ID的注释树:

    git whatchanged -r --pretty=oneline | perl -ne 'our %q; if (/^([0-9a-f]{40})/) {$c = $1} if (/:.{38}(.*)/) { $q{$1} = $c unless exists $q{$1} }; END { print map {"$q{$_} $_\n"} (keys %q); }'  | sort -k 2
    
    示例输出:

    b32f7f65f19e547712388d2b22ea8d5355702ce2 code/unfreezemodule/file.c
    b32f7f65f19e547712388d2b22ea8d5355702ce2 code/unfreezemodule/Makefile
    b32f7f65f19e547712388d2b22ea8d5355702ce2 code/unfreezemodule/unfreezemodule.c
    efeda0a22e4d1d5f3d755fee5b72fa99c0046e38 code/unfreezer/.gitignore
    b822361ffbc4548d918df5381ce94c296459598a code/unfreezer/unfreezer.c
    18ed76836182eba702e89b929eff2c0ea78ffb3e code/whole/wh
    1e111ce4e8c0813b397f34e3634309f7594cb864 code/xbmctest/.gitignore
    cb67943c4c18e3461267a34935fc8efaca5e2166 .config/awesome/awesome.lua
    d5e2b7c1d24bed1d0b53338f43747dc856c9cfe4 .config/awesome/rc.lua
    13ca8dbcd7f1ec684a7eba494442ee743ed577c0 cr
    566b54fb72e32947fcbf7d5c58fed78b5abe976d d
    392ac1a2456e8a29b2ebb7af9499c3f69d24a559 Desktop/CityInfo.desktop
    392ac1a2456e8a29b2ebb7af9499c3f69d24a559 Desktop/.directory
    

    您可以根据需要调整
    git whatchanged
    参数和/或过滤输出。

    假设历史记录很大,并且有一些文件和目录在创建存储库后从未更改过。所以我不得不解析整个历史来找到所有的文件。我想这不会更快。在这种情况下,我不知道有什么更好的解决方案(至少使用Git提供的工具,而不是直接使用对象文件)。由于树对象没有绑定到特定的分支,所以它们不引用提交信息。正如我在问题中所写的,这正是我所做的。问题是是否有一个更快的方法。它是对一个目录中的所有文件和目录的Git调用吗?这个命令总是打印整个树的所有最新更改。是否有一些选项仅列出特定目录中的更改?当项目相当大,我只想列出一个小目录时,我想获取整个树的数据,然后过滤掉我不需要的任何东西会非常慢。示例:
    git whatchanged-r--pretty=oneline | perl-ne'print if/[0-9a-f]{40};打印如果我!(?:\S+\S+{5}一些_dir/!'|。但是资源节约不会太大。这个脚本也可以修改为每个文件打印两个最后的提交ID,例如…你也可以1。限制要深入搜索的提交数,2。将第一阶段的结果缓存到某个位置,并针对其生成报告,而无需反复运行
    git whatchanged