I have a small patch saved away in my git stash. I\'ve applied it to my working copy using git stash apply
. Now, I\'d like to back out those changes by revers
This is long over due, but if i interpret the problem correctly i have found a simple solution, note, this is an explanation in my own terminology:
git stash [save]
will save away current changes and set your current branch to the "clean state"
git stash list
gives something like: stash@{0}: On develop: saved testing-stuff
git apply stash@{0}
will set current branch as before stash [save]
git checkout .
Will set current branch as after stash [save]
The code that is saved in the stash is not lost, it can be found by git apply stash@{0}
again.
Anywhay, this worked for me!
You can follow the image i shared to unstash if u accidentally tapped stashing.
git checkout -f
will remove any non-commit changes.
git stash show -p | git apply --reverse
Warning, that would not in every case: "git apply -R"(man) did not handle patches that touch the same path twice correctly, which has been corrected with Git 2.30 (Q1 2021).
This is most relevant in a patch that changes a path from a regular file to a symbolic link (and vice versa).
See commit b0f266d (20 Oct 2020) by Jonathan Tan (jhowtan).
(Merged by Junio C Hamano -- gitster -- in commit c23cd78, 02 Nov 2020)
apply: when
-R
, also reverse list of sectionsHelped-by: Junio C Hamano
Signed-off-by: Jonathan Tan
A patch changing a symlink into a file is written with 2 sections (in the code, represented as "struct patch"): firstly, the deletion of the symlink, and secondly, the creation of the file.
When applying that patch with
-R
, the sections are reversed, so we get: (1) creation of a symlink, then (2) deletion of a file.This causes an issue when the "deletion of a file" section is checked, because Git observes that the so-called file is not a file but a symlink, resulting in a "wrong type" error message.
What we want is: (1) deletion of a file, then (2) creation of a symlink.
In the code, this is reflected in the behavior of
previous_patch()
when invoked fromcheck_preimage()
when the deletion is checked.
Creation then deletion means that when the deletion is checked,previous_patch()
returns the creation section, triggering a mode conflict resulting in the "wrong type" error message.But deletion then creation means that when the deletion is checked,
previous_patch()
returnsNULL
, so the deletion mode is checked against lstat, which is what we want.There are also other ways a patch can contain 2 sections referencing the same file, for example, in 7a07841c0b ("
git-apply
: handle a patch that touches the same path more than once better", 2008-06-27, Git v1.6.0-rc0 -- merge). "git apply -R"(man) fails in the same way, and this commit makes this case succeed.Therefore, when building the list of sections, build them in reverse order (by adding to the front of the list instead of the back) when
-R
is passed.
According to the git-stash manpage, "A stash is represented as a commit whose tree records the state of the working directory, and its first parent is the commit at HEAD
when the stash was created," and git stash show -p
gives us "the changes recorded in the stash as a diff between the stashed state and its original parent.
To keep your other changes intact, use git stash show -p | patch --reverse
as in the following:
$ git init
Initialized empty Git repository in /tmp/repo/.git/
$ echo Hello, world >messages
$ git add messages
$ git commit -am 'Initial commit'
[master (root-commit)]: created 1ff2478: "Initial commit"
1 files changed, 1 insertions(+), 0 deletions(-)
create mode 100644 messages
$ echo Hello again >>messages
$ git stash
$ git status
# On branch master
nothing to commit (working directory clean)
$ git stash apply
# On branch master
# Changed but not updated:
# (use "git add <file>..." to update what will be committed)
# (use "git checkout -- <file>..." to discard changes in working directory)
#
# modified: messages
#
no changes added to commit (use "git add" and/or "git commit -a")
$ echo Howdy all >>messages
$ git diff
diff --git a/messages b/messages
index a5c1966..eade523 100644
--- a/messages
+++ b/messages
@@ -1 +1,3 @@
Hello, world
+Hello again
+Howdy all
$ git stash show -p | patch --reverse
patching file messages
Hunk #1 succeeded at 1 with fuzz 1.
$ git diff
diff --git a/messages b/messages
index a5c1966..364fc91 100644
--- a/messages
+++ b/messages
@@ -1 +1,2 @@
Hello, world
+Howdy all
Edit:
A light improvement to this is to use git apply
in place of patch:
git stash show -p | git apply --reverse
Alternatively, you can also use git apply -R
as a shorthand to git apply --reverse
.
I've been finding this really handy lately...
In addition to @Greg Bacon answer, in case binary files were added to the index and were part of the stash using
git stash show -p | git apply --reverse
may result in
error: cannot apply binary patch to '<YOUR_NEW_FILE>' without full index line
error: <YOUR_NEW_FILE>: patch does not apply
Adding --binary
resolves the issue, but unfortunately haven't figured out why yet.
git stash show -p --binary | git apply --reverse