I have a particular issue that I'm working on where I need to parse the changes NOT staged for commit.
If you do git status --porcelain
you can get an output like this:
M change1
M change2
MM change3
M change4
M change5
Changes 1 and 2 are staged, changes 3 to 5 are not. MM
means something else I haven't looked at yet.
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" category of git status
.
You can get which tracked files have unstaged changes with git diff --name-only
or git ls-files . -m
.
You can get untracked but not ignored files with git ls-files . --exclude-standard --others
. (From this answer).
Put them together to get all files which are not ignored and are untracked or have unstaged changes.
git ls-files . --exclude-standard --others -m
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.)
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