【问题标题】:Count number of lines in a git repository计算 git 存储库中的行数
【发布时间】:2011-06-16 21:16:50
【问题描述】:

如何计算 git 存储库中所有文件的总行数?

git ls-files 给了我一个 git 跟踪的文件列表。

我正在寻找cat 所有这些文件的命令。类似的东西

git ls-files | [cat all these files] | wc -l

【问题讨论】:

    标签: bash git shell line-count


    【解决方案1】:

    xargs 将让您将所有文件放在一起cat,然后再将它们传递给wc,就像您问的那样:

    git ls-files | xargs cat | wc -l
    

    但是跳过中间的cat 可以为您提供更多信息并且可能更好:

    git ls-files | xargs wc -l
    

    【讨论】:

    • 我猜是微不足道的;仅包含源代码文件(例如 *.cpp)怎么样。我们提交了一些 bin 文件 :)
    • xargs之前粘贴grep cpp |,然后。
    • 如果您的文件名称中包含空格,请使用 git ls-files -z | xargs -0 wc -l
    • 对于包含/排除某些文件,请使用:git ls-files | grep -P ".*(hpp|cpp)" | xargs wc -l 其中 grep 部分是您想要的任何 perl 正则表达式!
    • 如果您只对 .java 文件感兴趣,可以使用 git ls-files | grep "\.java$" | xargs wc -l
    【解决方案2】:
    git diff --stat 4b825dc642cb6eb9a060e54bf8d69288fbee4904
    

    这显示了从空树到当前工作树的差异。这恰好计算了当前工作树中的所有行。

    要获取当前工作树中的数字,请执行以下操作:

    git diff --shortstat `git hash-object -t tree /dev/null`
    

    它会给你一个类似1770 files changed, 166776 insertions(+)的字符串。

    【讨论】:

    • 顺便说一句,您可以通过运行 git hash-object -t tree /dev/null 来获取该哈希值。
    • 还有更简洁的:git diff --stat `git hash-object -t tree /dev/null`
    • 这是更好的解决方案,因为这不包括在上述版本中计算的档案或图像等二进制文件!
    • +1 我更喜欢这个解决方案,因为二进制文件不会被计算在内。此外,我们真的只对 git diff 输出的最后一行感兴趣:git diff --stat `git hash-object -t tree /dev/null` | tail -1
    • 改为使用git diff --shortstat `git hash-object -t tree /dev/null` 获取最后一行,不需要tail。
    【解决方案3】:

    如果您想要这个计数是因为您想了解项目的范围,您可能更喜欢CLOC(“Count Lines of Code”)的输出,它可以为您提供重要和不重要代码行的细分按语言。

    cloc $(git ls-files)
    

    (此行等效于git ls-files | xargs cloc。它使用sh$() command substitution 功能。)

    样本输出:

          20 text files.
          20 unique files.                              
           6 files ignored.
    
    http://cloc.sourceforge.net v 1.62  T=0.22 s (62.5 files/s, 2771.2 lines/s)
    -------------------------------------------------------------------------------
    Language                     files          blank        comment           code
    -------------------------------------------------------------------------------
    Javascript                       2             13            111            309
    JSON                             3              0              0             58
    HTML                             2              7             12             50
    Handlebars                       2              0              0             37
    CoffeeScript                     4              1              4             12
    SASS                             1              1              1              5
    -------------------------------------------------------------------------------
    SUM:                            14             22            128            471
    -------------------------------------------------------------------------------
    

    您必须先安装 CLOC。您可能可以install cloc with your package manager - 例如,brew install clocHomebrew

    cloc $(git ls-files) 通常是对cloc . 的改进。例如,上面带有git ls-files 的示例输出报告了 471 行代码。对于同一个项目,cloc . 报告高达 456,279 行(运行需要 6 分钟),因为它在 Git 忽略的 node_modules 文件夹中搜索依赖项。

    【讨论】:

    • CLOC 会忽略某些语言,例如 TypeScript。
    • @MarceloCamargo 目前支持 TypeScript
    • 对于初学者,最好执行“cloc DIRECTORY_WHERE_YOUR_GIT_IN”计算行数。
    • 这些天你可以只使用cloc --vcs git,这样可以避免一些带有错误命名文件(或太多)的边缘情况。
    • @MadhuNair 当然不是。 cloc 计算本地目录中的文件行数,而无需访问网络。它甚至不知道代码是否来自 GitHub。
    【解决方案4】:

    我在处理大量文件时遇到了git ls-files | xargs wc -l 的批处理问题,其中行数将被分成多个total 行。

    从问题Why does the wc utility generate multiple lines with "total"? 中得到提示,我发现以下命令可以绕过该问题:

    wc -l $(git ls-files)

    或者如果您只想检查一些文件,例如代码:

    wc -l $(git ls-files | grep '.*\.cs')

    【讨论】:

    • 这很好,但对于包含空格的路径似乎失败了。有办法解决吗?
    • 在 grep '.*\.m' 获取二进制文件(如 .mp3、.mp4)时遇到问题。使用 find 命令列出代码文件更成功wc -l $(git ls-files | find *.m *.h)
    • @LeaHayes 这是一种方法:wc -l --files0-from=<(git ls-files -z)<(COMMAND) 语法返回文件的名称,其内容是 COMMAND 的结果。
    • @LeaHayes 我想出了这个脚本,我认为它对你有用:``` #!/bin/bash results=$(git ls-files | xargs -d '\n' wc -l) let grand_total=0 for x in $(echo "$results" | egrep '[[:digit:]]+ total$'); do let grand_total+=$(echo "$x" | awk '{print $1}') done echo "${results}" echo "grand total: ${grand_total}" ``
    • -n 开关和xargs 可用于增加块内的最大行数
    【解决方案5】:

    无论如何,对我来说,最好的解决方案是埋在@ephemient 的答案中。我只是把它拉到这里,这样它就不会被忽视。这应该归功于@FRoZeN(和@ephemient)。

    git diff --shortstat `git hash-object -t tree /dev/null`
    

    返回 repo 工作目录中的文件和行的总数,没有任何额外的噪音。作为奖励,只计算源代码 - 二进制文件不包括在计数中。

    上面的命令适用于 Linux 和 OS X。它的跨平台版本是

    git diff --shortstat 4b825dc642cb6eb9a060e54bf8d69288fbee4904
    

    这也适用于 Windows。

    为了记录,排除空行的选项,

    • -w/--ignore-all-space,
    • -b/--ignore-space-change,
    • --ignore-blank-lines,
    • --ignore-space-at-eol

    --shortstat 一起使用时没有任何效果。计算空行。

    【讨论】:

    • git mktree </dev/nulltrue|git mktreegit mktree <&-:|git mktree 用于我们中间的击键计数器 :-) - 在 repo 周围漂浮的备用空树不会伤害任何东西。
    • 对于那些想知道这是什么乱七八糟的人:stackoverflow.com/questions/9765453/…
    【解决方案6】:

    这适用于cloc 1.68:

    cloc --vcs=git

    【讨论】:

    • --vcs 对我不起作用,也许它已被删除。 cloc . 在 git repo 中确实有效,OTOH。
    • --vcs=git 在 v1.90 版本上为我工作 =) 但是是的,我在根目录下运行它,它只是告诉 cloc 它可以忽略什么的一个选项
    【解决方案7】:

    我使用以下:

    git grep ^ | wc -l
    

    这会在所有由 git 版本控制的文件中搜索正则表达式 ^,它表示行的开头,因此该命令会给出总行数!

    【讨论】:

      【解决方案8】:

      我在玩cmder (http://gooseberrycreative.com/cmder/),我想计算html、css、java 和javascript 的行数。虽然上面的一些答案有效,但 grep 中的 or 模式没有 - 我在这里 (https://unix.stackexchange.com/questions/37313/how-do-i-grep-for-multiple-patterns) 发现我必须逃避它

      这就是我现在使用的:

      git ls-files | grep "\(.html\|.css\|.js\|.java\)$" | xargs wc -l

      【讨论】:

      • 这对我来说似乎是用块来回应的。将您的 grep 与 Justin Aquadro 的解决方案结合使用对我来说效果很好。 wc -l $(git ls-files | grep "\(.html\|.css\|.js\|.php\|.json\|.sh\)$")
      【解决方案9】:

      我这样做了:

      git ls-files | xargs file | grep "ASCII" | cut -d : -f 1 | xargs wc -l
      

      如果您将存储库中的所有文本文件都视为感兴趣的文件,则此方法有效。如果某些被认为是文档等,则可以添加排除过滤器。

      【讨论】:

        【解决方案10】:

        github上的这个工具https://github.com/flosse/sloc可以以更具描述性的方式给出输出。它将创建您的源代码的统计信息:

        • 物理线条
        • 代码行(源代码)
        • 带有 cmets 的行
        • 单行cmets
        • 带有块 cmets 的行
        • 与源代码和 cmets 混淆的行
        • 空行

        【讨论】:

          【解决方案11】:

          试试:

          find . -type f -name '*.*' -exec wc -l {} + 
          

          在有问题的目录上

          【讨论】:

            【解决方案12】:

            如果要获取某个作者的行数,试试下面的代码:

            git ls-files "*.java" | xargs -I{} git blame {} | grep ${your_name} | wc -l
            

            【讨论】:

              【解决方案13】:

              根据是否要包含二进制文件,有两种解决方案。

              1. git grep --cached -al '' | xargs -P 4 cat | wc -l
              2. git grep --cached -Il '' | xargs -P 4 cat | wc -l

                "xargs -P 4" 表示它可以使用四个并行进程读取文件。如果您正在扫描非常大的存储库,这将非常有用。根据机器的容量,您可能会增加进程数。

                -a,将二进制文件作为文本处理(包括二进制)
                -l '',只显示文件名而不是匹配的行(只扫描非空文件)
                -I,不匹配二进制文件中的模式(排除二进制)
                --cached,在索引而不是工作树中搜索(包括未提交的文件)

              【讨论】:

                【解决方案14】:

                如果要查找非空行的总数,可以使用 AWK:

                git ls-files | xargs cat | awk '/\S/{x++} END{print "Total number of non-empty lines:", x}'

                这使用正则表达式来计算包含非空白字符的行数。

                【讨论】:

                  【解决方案15】:

                  Carl Norum 的答案假设没有带有空格的文件,IFS 的字符之一是tabnewline。解决方案是用 NULL 字节终止该行。

                   git ls-files -z | xargs -0 cat | wc -l
                  

                  【讨论】:

                    【解决方案16】:
                    : | git mktree | git diff --shortstat --stdin
                    

                    或者:

                    git ls-tree @ | sed '1i\\' | git mktree --batch | xargs | git diff-tree --shortstat --stdin
                    

                    【讨论】:

                      猜你喜欢
                      • 2012-08-12
                      • 2014-11-20
                      • 2018-03-19
                      • 2019-05-06
                      • 2010-11-18
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2011-05-28
                      相关资源
                      最近更新 更多