blueFast
blueFast

Reputation: 44381

Report number of modified files, per-directory

Somehow related to this other question (actually, the opposite). I would like to get a report like this:

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

Where dir1 and dir2 are direct children of the current directory. The report would not be recursive, just applied to the current directory.

Can git status provide such a report?

Upvotes: 0

Views: 63

Answers (2)

Schwern
Schwern

Reputation: 164829

With git diff --name-status or git status --porcelain you can get a list of all files which have changed and how. Then you can format it however you like.

git status --porcelain will give you a complete status regardless of whether the changes are indexed or not, just like git status.

git diff --name-status will act like normal git diff and only give you changes relative to the index. Run an extra --staged to get the complete view.

Here's an example.

$ 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

Upvotes: 1

jub0bs
jub0bs

Reputation: 66244

Shell script

What follows isn't a full solution, but it's a start. A more efficient and robust approach would use awk instead of sed to compute the three counts in only one pass over the output of 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

Toy example

# 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

Upvotes: 1

Related Questions