Reputation: 44381
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
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
Reputation: 66244
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
# 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