jakun
jakun

Reputation: 674

Exclude deleted lines in git diff

I have made several changes to a function and staged one of them with git add -p. Before committing it I would like to check that this change actually does what it is supposed to do.

Therefore I would like to print the code exactly as it is in the staged area so that I can copy this function and test it in a separate file.

In gitk there would be this useful radio button where I could select New version instead of Diff. However, I can not use gitk here because I am connected via ssh to a computer without graphical user interface.

If the change was already committed I could use git show HEAD:myfile (although that would print the entire file, which is far more than I am currently interested in) but I don't know how to specify the staged area instead of HEAD.

I am interested in both:

  1. How can I print the staged changes with context lines but without deleted lines?
  2. How can I specify the staged area in git show so that I can print the entire file?

I have found this answer but -e is not documented in git diff --help and when trying to use it I get error: invalid option: -e.

Of course I could commit the changes, search them in the output of git show HEAD:myfile and then change the commit if necessary with git commit --amend but I feel like there must be an easier way.

Upvotes: 3

Views: 1114

Answers (1)

torek
torek

Reputation: 489758

The thing that is called the staging area is also called the index. Hence the staged copy of the file is also the index copy of the file. To refer to the index copy of a particular file, use the leading-colon syntax: :digit:filename, e.g., :0:myfile:

git show :0:myfile

The index holds either 1 copy of the file, in staging slot zero, or (up to) three copies of the files, in staging slots 1, 2, and 3. The latter occurs only during a merge, while resolving conflicts. Since you are not in the middle of a conflicted merge, your file exists only at stage zero. You can omit the digit and second colon to mean "staging slot zero":

git show :myfile

(Compare with git show HEAD:myfile, which extracts the copy of the file from the HEAD commit, or git show hash:myfile, which extracts the copy of the file from the given commit hash. All of these work on the internal, Git-ified copies of files, in the special Git-only, read-only format for committed files—files that have been copied into the index are already in this form.)

To diff the HEAD commit against the index, use:

git diff --cached

Note that this compares every file in HEAD against every file in the index. Most files in the index will already match the copy in HEAD, of course. In particular, if you did:

git checkout master
<edit some file>
git add [options] just-one-file

then every file except the just-one-file file in the index / staging-area matches its counterpart in HEAD, so the diff will show only the one file anyway.

If there are multiple files in the index that differ from their HEAD counterparts, you can limit the git diff output further using path names:

git diff --cached -- myfile

for instance. (This will still show any lines that are deleted.)

(There is a common misconception that the staging area holds only new files. That's not the case—it actually holds every file, ready to be committed, at all times—but due to the way the staging area is described in many tutorials and due to the fact that git diff doesn't show you anything for unchanged files, it can seem that way at first. To see a list of all the files in the staging area, along with information about them, use git ls-files --stage. Note that this listing can be quite long!)

Upvotes: 1

Related Questions