2

Is it possible to staged twice the same file and compare (diff) the two staged version? Example with the file myclass.java:

  • I stage my file ==> git add myclass.java (staged file version 1)
  • I do some changes on this file
  • I stage again my file (staged file version 2)

Can I compare staged file version 1 and staged file version 2?

Thx!

Luke Girvin
  • 13,221
  • 9
  • 64
  • 84
paranoia25
  • 626
  • 1
  • 5
  • 23

2 Answers2

4

The second git add overwrites the first, but you can still get the diff.

# edit edit edit
$ git add myclass.java
# edit some more

Now git diff will show you the diff between the staged file and the last edits. If you want the diff between the staged file and the last commit, you have to do git diff --staged.

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
3

The Git index is where files are staged for commits; take a look at this StackOverflow answer for more information. When you stage files for commit, the index reflects the latest staged information. Staging a file a second time will change the Git index to reflect the file's content in the working directory.

However, with some additional work, you can see the content of the file as it was for each stage. You can use git ls-files after each stage to get a list of file blobs that you can then use later for comparison using diff or some other difference tool.

Here's a little sample session as an example.

$ git init
Initialized empty Git repository in /home/user/tmp/.git/
$ echo "foo" > foo
$ git add foo
$ git ls-files --stage
100644 257cc5642cb1a054f08cc83f2d943e56fd3ebe99 0   foo
$ echo "bar" > foo
$ git add foo
$ git ls-files --stage
100644 5716ca5987cbf97d6bb54920bea6adde242d87e6 0   foo
$ git cat-file blob 257cc56 > foo.257cc56
$ git cat-file blob 5716ca5 > foo.5716ca5
$ diff foo.257cc56 foo.5716ca5 
1c1
< foo
---
> bar

But this is a lot of work and requires careful planning and storing of blob hash values to accomplish.

Community
  • 1
  • 1
Go Dan
  • 15,194
  • 6
  • 41
  • 65
  • +1 cause I hadn't thought of that, but it is a lot of work and probably shouldn't be used by a git newbie. Using straight-up `git diff` to compare staged vs. working copy should suffice for most users, but in the case that they do want diffs of multiple staged versions, it seems this is what they'd have to do. – johnny Oct 06 '11 at 12:43
  • As a follow up, does anyone know if this possible without doing `ls-tree` each time? I'm going to have a look into the logs a bit... – johnny Oct 06 '11 at 12:44
  • 1
    @johnny Totally agree; this is not something Git newbies should get into. But it's the only way I found to answer the OP's question. I too am curious if there's a better way. – Go Dan Oct 06 '11 at 12:49
  • To answer my follow-up, the logs don't keep track of the index, but if you really, really, really wanted to find that old staged version, you can use `git fsck` to find it (assuming it hasn't been garbage collected, of course) – johnny Oct 06 '11 at 12:55
  • @johnny You could use `git fsck` to find dangling blobs. But, if you have many staged files overwritten by subsequent staging, it will quickly become an involved process to review the contents of each blob to determine if that blob may possibly be the contents of the staged file at some previous point; blobs don't store file name or directory information. This too drags you deeper down the advanced Git rabbit hole. – Go Dan Oct 06 '11 at 13:08
  • Hence the 'really, really, really' reiteration :p - just wanted to make it known that it's at least available (even if it's extremely painful), but I agree that it's certainly a further step down the 'advanced Git rabbit hole' (which it seems is quite deep and at some points rather steep :)) - combining with something like `awk '{print $3}' | git cat-file --batch | grep 'something in the file'` could automate it a bit, but that's also more advanced :p – johnny Oct 06 '11 at 13:15