Reputation: 6085
I've been looking for a way to get all the changed files in a repository during the staging process (uncommitted) in a list, but all I can find is how to do it between 2 commits.
Doing git status
shows a list of modified files, but I need to get the list in a format that I can parse easily with a script.
How can I accomplish this?
Upvotes: 2
Views: 1252
Reputation: 30868
git ls-files -c
to list all the staged files, -d
for deleted files, -m
for modified, and -i
for ignored, and -o
for others (untracked).
Upvotes: 0
Reputation: 488193
Your question is a good one, because it leads you into the first big secret of Git's index: that the index acts as a storage area for all the files that will be in the next commit.
In other words, you have a current commit (aka HEAD
), and a work-tree (which you can just look at). But you have this invisible area, the staging area or index or cache (it has three names), that also has copies of every file.
Git lets you compare any of these:
git diff commit1 commit2
;git diff
(this is what you can stage for a commit);git diff commit
, e.g., git diff HEAD
—but this ignores the staging area; and last, perhaps what you want:git diff --cached commit
, e.g., git diff --cached HEAD
. If you omit the commit
, it defaults to HEAD
, so git diff --cached
gets what you want here.Your own answer mentions git status --short
(or -s
). This actually runs two git diff
commands internally. That's why there are two columns for each status letter, and two question-marks for untracked files: the first column shows the result of comparing HEAD
to the staging-area/cache/index, and the second shows the result of comparing the staging-area/cache/index to the work-tree.
If you have modified file changed/file/1
but have not yet copied it to the staging area, the version of the file in the HEAD
commit matches the version of the file in the staging area. So the first column's status is blank (no change). The copy of the file in the work-tree is different, so its column gets an M
.
If you git add changed/file/1
, this copies it from the work-tree to the staging-area, overwriting the version that matches the HEAD
commit. Now git status -s
sees that the first comparison shows "modified" and the second shows "the same", so the M
goes in the first column and the second column is blank.
You can modify the file in the work-tree yet again, and run git status -s
, and this time you will get two M
s: one says that HEAD
and index/staging-area differ, and the other says that index/staging-area differs from work-tree.
Upvotes: 1
Reputation: 94483
git diff --cached
shows staged hunks.
git diff --cached --name-only
list staged files.
Upvotes: 0
Reputation: 1051
You can use the command mentioned above and then, cut, sed it to fetch only file name.
git status -s --porcelain | cut -c4-
git status -s --porcelain | sed -e 's!.*/!!'
if you wish to track unstaged files.
git status -uno
Upvotes: 3
Reputation: 6085
While I was researching this question I decided to look at the help page for git status
and found this:
-s, --short
Give the output in the short-format.
--porcelain[=<version>]
Give the output in an easy-to-parse format for scripts. This is similar to the short output, but will remain stable across Git versions and regardless of user
configuration. See below for details.
Using git status -s --porcelain
will give the list below:
M changed/file/1
M changed/file/2
M changed/file/3
?? untracked/
?? untrackedfile.txt
?? untracked/folder/2
?? other/untracked/folder
I also tried this on a repository with no untracked files, and the space in front of the M
still remains.
Upvotes: 0