The MM
state means there are some changes staged, and some changes not-staged.
More precisely, it means that the index version of that path differs from the HEAD
version—this is the first M
—and that the work-tree version of that path differs from the index version.
For instance, suppose you have a README and you stage a change:
$ echo stuff >> README; git add README; git status --porcelain
M README
Now you make a second change to the same file. To make it especially interesting, let's remove the added stuff
line:
$ ed README << 'end'
$d
w
q
end
2634
2628
$ git status --porcelain
MM README
Now if we git add
the file, this stages the work-tree version which is the same as the HEAD
version, and:
$ git add README
$ git status --porcelain
$
I can parse this output, but I am wondering if there's a better way to just show the files in the "Changes not staged for commit" of 'git status'.
You need to decide what to do about files in this state, and if there is the potential for unmerged states—if there may be files that have not yet had a conflicted merge resolved, these are the unmerged files—what to do for them as well.
In general, though, if you want a diff, use git diff
. There are many sub-flavors of diff
: you can compare a tree (such as that for HEAD
) to the index, or to the work-tree, or compare two trees to each other. See the documentation for details, but in short git diff
compares the index to the work-tree and hence corresponds to the second column of the status output.
To get diff to emit only the names of the files, use --name-only
. So git diff --name-only
will give you changes you could stage. (This doesn't help with untracked files; see Schwern's answer for using git ls-files
for that.)