I wish to create a .patch
file based on the diff of an old stash that I can view with git stash show -p stash@{2}
I tried this, but no luck:
git format-patch stash@{2} --stdout > file.patch
I assumed it would work like a normal commit? Apologies for being most likely uber-thick.
Thanks!
Retrieve Stashed Changes To retrieve changes out of the stash and apply them to the current branch you're on, you have two options: git stash apply STASH-NAME applies the changes and leaves a copy in the stash. git stash pop STASH-NAME applies the changes and removes the files from the stash.
You can reapply stashed changes with the commands git stash apply and git stash pop . Both commands reapply the changes stashed in the latest stash (that is, stash@{0} ). A stash reapplies the changes while pop removes the changes from the stash and reapplies them to the working copy.
The output of git stash show -p
is itself a valid patch. You can use it directly:
git stash show -p stash@{2} > file.patch
Per the git format-patch
documentation, if you specify a single commit,1 then:
- A single commit,
since
, specifies that the commits leading to the tip of the current branch that are not in the history that leads to thesince
to be output.
Thus, format-patch
tries to find "commits leading to the tip of the current branch" (HEAD
) that are neither themselves stash@{2}
nor ancestors of stash@{2}
. It's hard to say precisely which commits these will be without knowing the actual commit graph, but if the graph looks something like this:
... - o - o - * - * <-- HEAD=branch
|\
i-w <-- stash@{2}
then format-patch
would make a patch containing the two commits marked *
: they are the only ancestors of HEAD
that are not removed by starting at the w
commit and working backwards.
If the graph looks more like this:
* <-- HEAD=branch
/
... - o - o - o - o <-- anotherbranch
|\
i-w <-- stash@{2}
then once again you would get the commit marked *
(one commit this time, just to be a bit different).
(In fact, you get precisely the same commits as for stash@{2}..HEAD
, since this gitrevisions
syntax means what's in item 1 of the format-patch
documentation).
One solution is to proceed to item 2 in the format-patch
documentation:
- Generic revision range expression (see "SPECIFYING REVISIONS" section in gitrevisions(7)) means the commits in the specified range.
Here you need only specify the commits from "just before the w
commit in the stash-bag" to "the w
commit itself", which is simply stash@{2}^..stash@{2}
:
git format-patch [additional options like --stdout here] stash@{2}^..stash@{2}
Since this is a single commit, the only difference between this and just using git show
(as John Zwinck suggested) is the precise formatting of the patch (format-patch
makes mailbox style patches by default).
Alternatively, you can always turn a stash into a "real branch" using git stash branch
. This turns the index commit i
of the stash into a real commit if needed, and restores the work directory state (and the untracked or all-files state as well, if one of those was included in the stash) after creating a new branch starting at the parent commit, i.e., the one the stash-bag is attached to. Commit the resulting work-tree and you have an ordinary branch, which you can manipulate with all the ordinary branch operations (including format-patch
).
1See some of my other descriptions about git "stash bags" to see that a stash is a small clump of commits, but note that the name stash@{2}
identifies a single commit, specifically the work-tree commit in the "stash bag".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With