How can I find out the number of modified files in the index? That is to say, files that show as "modified" when running git status
.
I know lots of visual git tools that do this, as well as shell add-ons that show the count next to the prompt, but I just don't see how to do it on the command line in a reasonable way.
You can get the number of modified file using :
git status -s -uno | wc -l
From the git status documentation, -s
give output in short format, and -uno
does not show untrack files.
You probably want either HEAD vs work-tree or HEAD vs index, or perhaps HEAD vs index plus index vs work-tree. If you want to keep the two comparisons separate, you cannot do it in one step.
There are several possible answers depending on precisely what question you meant. Note that for all of the diff commands below, you can use --name-only
if you're not interested in the particular change(s) in the file(s). The status letter (Added, Deleted, Modified, etc.) is useful if you decide to add --diff-filter
to choose to examine only specific kinds of changes. For instance, if you want to know how many files are strictly modified, not counting files added or deleted, you could filter on M
.
git diff --cached --name-status HEAD | wc -l
git diff --name-status HEAD | wc -l
git diff --name-status | wc -l
git status -s -uno | wc -l
(as in mpromonet's comment).Each produces a different result:
Compares HEAD
to the index: what would be different in the commit you would make now if you ran git commit
right now, compared to what's in the commit that is HEAD
right now? That is, you have a current commit now, and if you make a new commit, the current commit will be the new commit's parent. What will be different?
(Remember, the index represents the next commit to make. It starts out with copies of the exact same files as in HEAD
. Each time you git add
a file, you copy the file back from the work-tree, into the index. This is therefore comparing what you will commit now if you commit, to what you have in your HEAD
commit. As a special case here, you can omit the name HEAD
; --cached
will assume HEAD
.)
In the long git status
output, these come out in the first section: Changes to be committed
.
Compares HEAD
to the work-tree. These are files that are modified in the work-tree, but are not staged for commit. In the longer git status
output, these generally come out in the second section, Changes not staged for commit
—but see the very next bit.
Compares the index to the work-tree. These, too, are files that are modified in the work-tree—but this time they're changed with respect to the files already copied back into the index. To the extent that the index matches the HEAD
commit, #2 and #3 produce the same list of files. But suppose README
is in HEAD
as Version H (for Head). You modify README
and git add README
, copying version W (for Work-tree) into version I (for Index). Then you modify version W again. Now all three are different! Using git status --short
or git status -s
, you will see MM README
in the output: it's modified twice.
The output from this section is really what shows up in the second half of the git status
output, the Changes not staged for commit
part.
Compares HEAD
vs index, then compares index vs work-tree, then prints—in a summary, combined format—the name and status of each file, using two letters for each file.
To illustrate this clearly, consider this repository with a single initial commit, with one file in it. The file is named README
and the initial commit version contains the text Read me.
$ git init
Initialized empty Git repository in ...
$ echo 'Read me.' > README
$ git add README
$ git commit -m initial
[master (root-commit) a9362c4] initial
1 file changed, 1 insertion(+)
create mode 100644 README
$ echo 'Please read me.' > README
$ git add README
$ echo 'Read me, for I am very readable.' > README
There are now three active versions of file README
, and:
$ git status -s
MM README
The long version of git status
shows us that README
is both ready to commit, and has changes not staged for commit:
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: README
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: README
Look, though, at what happens if we put the initial text back, then compare HEAD
to the work-tree:
$ echo 'Read me.' > README
$ git diff --name-status HEAD
$
The current commit matches the work-tree, so there is no difference here. If you git add README
, the short status goes from MM README
to empty:
$ git status -s
MM README
$ git add README
$ git status -s
$
So, if you are wondering "what do I get if I add and commit everything", you will want to compare HEAD
with the work-tree. If you are wondering "what do I get if I commit now", you want to compare HEAD
to index.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With