报告每个目录的已修改文件数

时间:2015-03-18 16:30:56

标签: git

以某种方式与this other问题相关(实际上,相反)。我想得到一份这样的报告:

dir1 : 2 files modified, 3 deleted, 2 sub-dirs modified
dir2 : 7 files modified, 2 added, 7 deleted

dir1dir2是当前目录的直接子项。该报告不会递归,只应用于当前目录。

git status可以提供此类报告吗?

2 个答案:

答案 0 :(得分:1)

使用git diff --name-statusgit status --porcelain,您可以获得已更改的所有文件及其方式的列表。然后你可以随意格式化它。

无论更改是否已编入索引,

git status --porcelain都会为您提供完整的状态,就像git status一样。

git diff --name-status将像普通git diff一样行事,只会针对索引提供相应的更改。运行额外的--staged以获得完整视图。

以下是一个例子。

$ git st
On branch Kavorka
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

    deleted:    META.json

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   lib/Method/Signatures.pm
    modified:   t/array_param.t
    modified:   t/examples/silly.t

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    t/lib/Errors.pm

$ git diff --name-status
M   lib/Method/Signatures.pm
M   t/array_param.t
M   t/examples/silly.t

$ git diff --name-status --staged
D   META.json

$ git status --porcelain
D  META.json
 M lib/Method/Signatures.pm
 M t/array_param.t
 M t/examples/silly.t
?? t/lib/Errors.pm

答案 1 :(得分:1)

Shell脚本

以下内容不是一个完整的解决方案,但它是一个开始。一种更有效且更健壮的方法是使用awk代替sed来计算git status --porcelain输出中仅一次传递中的三个计数。

#!/bin/sh

# git-status-perdir.sh
#
#      Reports the numbers of modified, added, and deleted files in each
#      subdirectory of the current directory

for f in *; do
    if [ -d "$f" ]; then                     # if f is a directory...
        out=$(git status --porcelain -- $f)
        mod=$(printf "$out" | grep -c '^ M') # count modified
        add=$(printf "$out" | grep -c '^A')  # count added
        del=$(printf "$out" | grep -c '^D')  # count deleted
        printf "%s : %d modified, %d added, %d deleted\n" \
            "$f" "$mod" "$add" "$del"
     fi
done

玩具示例

# set things up
$ mkdir testgit
$ cd testgit/
$ git init

# create dir1, dir1/foo1.txt and dir1/bar1.txt
$ mkdir dir1
$ touch dir1/foo1.txt
$ touch dir1/bar1.txt

# stage all and commit
$ git add .
$ git commit -m "add foo1 and bar1"

# create and stage dir2 and dir2/foo2.txt
$ mkdir dir2
$ touch dir2/foo2.txt
$ git add test2/

# remove the (tracked) file dir1/foo1.txt
$ git rm dir1/foo1.txt

# modify dir1/bar1.txt
$ printf "Hello, world\n" > dir1/bar1.text

# run the script
$ sh git-status-perdir.sh
dir1 : 1 modified, 0 added, 1 deleted
dir2 : 0 modified, 1 added, 0 deleted