1

I am using git 1.7.1 . My scenario is something as described below:-

I have added 5 new files to my project and modified 1 existing file. I now decide the current changes to stash and move to some different branch. So, I add all new 5 files to staging area and then I stash it. Let stash@{0} be my stash. So in the stash stash@{0}, there are 5 new files in staging area and 1 modified file in the working directory.

Now I do a git stash list. It gives me say below list of stashes:

stash@{0}
stash@{1}
stash@{2}
stash@{3}
stash@{4}
stash@{5} 

After a day or two, I came back and wanted to check the available list of stashes and then wanted to check which stash contains what. Therefore I tried, git stash show -p stash@{0} . This gives me the changes of only 1 file which I have modified in working directory. It doesn't give any info that there are 5 new files in the staging area. One way I could do is apply the stash to a branch and do a git status. That would give the desired output.

But what I am looking here is to get this info before applying a stash to any branch. Any help is highly appreciated!

ckruczek
  • 2,361
  • 2
  • 20
  • 23
Deca
  • 1,155
  • 1
  • 10
  • 19

1 Answers1

3

A stash consists of two (or sometimes three) commits. These commits are not on a branch, but rather are found through the special stash reference (refs/stash) and its reflog (stash@{n}, for any integer n, is a reflog name). These two (or three) commits hold the index/staging-area state, the work-tree state, and—if the third commit is present—the untracked files or the extra "all" files (from git stash save -u or git stash save -a). I like to refer to these as the i, w, and u commits of a "stash bag", since if you draw these two (or three) commits as part of a commit-graph drawing, they look like a little bag hanging off a commit.

The git stash show command runs git diff to compare the w commit to its parent. What you need is to compare the i commit (to i's or w's parent, marked * in the diagram below) instead. There is no flag to git stash show to do this, but you can make use of the stash-bag's structure:

  • The stash or stash@{n} reference points directly to to the w commit.
  • The first parent of the w commit is the commit that was HEAD when the stash was saved.
  • The i commit is the second parent of the w commit. (This means that the w commit is a merge commit; but do not try to use it as a merge!) The i commit has a single parent, which is the same parent as w's first parent.
  • If the u commit exists, it is the third parent of w, and it is itself a root commit (has no parent).

I find that the Unicode arrow characters do not display properly on all viewers so this diagram has the arrows drawn a bit larger:

...<-- o <-- o <-- * <-- o <-- o   <-- branch
                   ^
                   |\
                   | \
                   i<-w   <-- stash@{3}

In this diagram, commit * is the commit that was the HEAD commit when this stash was saved (but since then, there have been two more commits added to branch).

Git has some special syntax for going from any specific commit to its parents, as described in the gitrevisions documentation, so you can get a diff comparing commit w to commit *:

git diff stash@{3} stash@{3}^

This is what git stash show does: stash@{3} names commit w and stash@{3}^ names its parent, which is commit *. But what you want is to compare commit i to commit *:

git diff stash@{3}^2 stash@{3}^

Note that you can also compare i and w, if you like, by naming stash@{3}^2 (w's second parent = i) and stash@{3} (w itself), in that order.

(As a shortcut, you can use git show on the i commit, since git show diffs a commit against its parent(s). Note that using git show on w is less useful: w has two parents, so git show produces a combined diff, which is reasonable for regular merge commits, but rarely very useful for these w commits, since they are not normal merge commits.)

Community
  • 1
  • 1
torek
  • 448,244
  • 59
  • 642
  • 775
  • thanks much for your elaborate ans..... :) I am going through the links you provided as reference, and then will come back and ask you if I understood it or if I have some doubts! – Deca Jul 07 '16 at 08:48