Jeeter
Jeeter

Reputation: 6085

Git - List all changed files during staging

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

Answers (5)

ElpieKay
ElpieKay

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).

More about git-ls-files

Upvotes: 0

torek
torek

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:

  • any two commits: git diff commit1 commit2;
  • the index and the work-tree: git diff (this is what you can stage for a commit);
  • any commit and the work-tree: git diff commit, e.g., git diff HEAD—but this ignores the staging area; and last, perhaps what you want:
  • any commit and the staging area: 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 Ms: one says that HEAD and index/staging-area differ, and the other says that index/staging-area differs from work-tree.

Upvotes: 1

phd
phd

Reputation: 94483

git diff --cached shows staged hunks.

git diff --cached --name-only list staged files.

Upvotes: 0

nevihs
nevihs

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

Jeeter
Jeeter

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

Related Questions