2009-06-19 12 views
154

Tengo un pequeño parche guardado en mi escondite git. Lo he aplicado a mi copia de trabajo usando git stash apply. Ahora, me gustaría dar marcha atrás a esos cambios aplicando el parche de forma inversa (algo así como lo que haría git revert pero en contra del alijo).¿Cómo revertir la aplicación de un alijo?

¿Alguien sabe cómo hacer esto?

aclaración: Hay otros cambios en mi copia de trabajo. Mi caso particular es difícil de describir, pero puedes imaginar algún código de depuración o experimental que esté en el alijo. Ahora está mezclado en mi copia de trabajo con algunos otros cambios y me gustaría ver el efecto con y sin los cambios del alijo.

No se ve como escondite apoya este momento, pero una git stash apply --reverse sería una buena característica.

+0

¿Hay cambios en el árbol de trabajo que no sean el alijo aplicado? –

+0

¿No se puede simplemente crear un parche invertido difiriendo entre la revisión actual y la anterior? ¿Y luego aplicar ese? – ralphtheninja

Respuesta

139

De acuerdo con la git-stash manpage, "Un escondite se representa como una confirmación cuyo árbol registra el estado del directorio de trabajo, y su primer padre es el cometer en HEAD cuando se creó el escondite," y git stash show -p nos da "los cambios registrada en el alijo como un diff entre el estado escondido y su matriz original de

Para mantener los otros cambios intacta, utilice git stash show -p | patch --reverse como en el siguiente:.

$ 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 

Editar:

Una ligera mejora a esto es utilizar git apply en lugar del parche:

git stash show -p | git apply --reverse 

Como alternativa, también se puede utilizar como una abreviatura git apply -R a git apply --reverse.

que he ido encontrando esta realmente útil últimamente ...

+2

Impresionante, gracias. Parece que esta podría ser una buena característica para esconderse. –

+5

Sí, 'git apply -R' es una mejora, al menos para mí en mi caja de Windows con git bash, ya que' patch --reverse' tenía problemas para localizar el archivo a parche (no tenía idea de por qué funcionaba la alternativa).+1 y buena explicación – hakre

+0

¿no sería mejor agregar '--index' justo como este' git stash show -p | git apply --reverse --index'. Porque ya no necesita agregar en el índice los cambios que se revierten. – theUnknown777

61

git stash[save] toma su estado de directorio de trabajo, y su estado de índice, y los esconde, configurando el índice y el área de trabajo a HEAD versión.

git stash apply trae de vuelta esos cambios, por lo que git reset --hard los eliminaría nuevamente.

git stash pop recupera esos cambios y elimina el cambio superior oculto, por lo que git stash [save] volverá al estado anterior (pre-pop) en este caso.

11

Esto es más largo debido, pero si se interpenetran el problema correctamente Me han encontrado una solución simple, nota, esta es una explicación en mi propia terminología:

git stash [save] ahorrará distancia cambios actuales y establecer su rama actual al "estado limpio"

git stash list da algo así como: [email protected]{0}: On develop: saved testing-stuff

git apply [email protected]{0} establecerá rama actual como antesstash [save]

git checkout . fijará rama actual como despuésstash [save]

El código que se guarda en el alijo no se pierde, se puede encontrar por git apply [email protected]{0} nuevo.

Anywhay, esto funcionó para mí!

+0

Solo para estar seguro, he aplicado un 'git stash apply - -reverse' primero y luego simplemente regresó a 'git stash apply stash @ {x}' como usted menciona. Trabajó sin problemas –

16

Corte directo n pegar desde git man page Está redactado con claridad e incluso incluye un alias;

Un-aplicación de un Stash En algunos escenarios de casos de uso es posible que desee aplicar los cambios escondido, hacer algún trabajo, pero luego de la ONU a aplicar esos cambios que se produjeron originalmente del alijo. Git no proporciona un comando de cancelar la aplicación, tales escondite, pero es posible lograr el efecto simplemente recuperar el parche asociado con un alijo y su aplicación a la inversa:

$ git stash show -p [email protected]{0} | git apply -R 

De nuevo, si no se especifica un alijo , Git asume la más reciente escondite:

$ git stash show -p | git apply -R 

Es posible que desee crear un alias y añadir efectivamente un comando alijo-cancelar la aplicación a su Git. Por ejemplo:

$ git config --global alias.stash-unapply '!git stash show -p | git apply -R' 
$ git stash apply 
$ #... work work work 
$ git stash-unapply 
23
git checkout -f 

eliminará cualquier no-confirmar los cambios.

+1

gracias, me ayudaste de cambio escenificado que no fue desaplicado. –

0

Además de respuesta @ Greg Bacon, en caso de que se añadieron los archivos binarios en el índice y eran parte de la escondite usando

git stash show -p | git apply --reverse 

puede resultar en

error: cannot apply binary patch to '<YOUR_NEW_FILE>' without full index line 
error: <YOUR_NEW_FILE>: patch does not apply 

Adición --binary resuelve el problema , pero desafortunadamente aún no entienden por qué.

git stash show -p --binary | git apply --reverse 
Cuestiones relacionadas