Pregunta

Tengo un pequeño parche guardado en mi escondite de git. Lo he aplicado a mi copia de trabajo usando git stash apply . Ahora, me gustaría retroceder esos cambios mediante la aplicación inversa del parche (algo así como lo que git revert haría pero en contra del 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 un código de depuración o experimental que está en el escondite. 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 parece que stash lo admita actualmente, pero un git stash apply --reverse sería una buena característica.

¿Fue útil?

Solución

Según la página de manual de git-stash , " Un alijo se representa como un commit cuyo árbol registra el estado del directorio de trabajo, y su primer padre es el commit en HEAD cuando se creó el alijo, " y git stash show -p nos da " los cambios registrados en el alijo como una diferencia entre el estado escondido y su padre original.

Para mantener sus otros cambios intactos, use git stash show -p | parche --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

Edición :

Una mejora ligera para esto es usar git apply en lugar del parche:

git stash show -p | git apply --reverse

Alternativamente, también puede usar git apply -R como una forma abreviada de git apply --reverse .

He estado encontrando esto realmente útil últimamente ...

Otros consejos

git stash [guardar] toma su estado de directorio de trabajo y su estado de índice, y los guarda, configurando el índice y el área de trabajo en la versión HEAD .

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

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

git checkout -f

eliminará cualquier cambio que no sea de confirmación.

Corte directo n pegar desde la página de manual de git Está claramente redactado e incluso incluye un alias;

Desinstalar un alijo En algunos escenarios de casos de uso, es posible que desee aplicar cambios escondidos, hacer algo de trabajo, pero luego anular la aplicación de los cambios que originalmente provienen del alijo. Git no proporciona un comando de aplicación de escondite, pero es posible lograr el efecto simplemente recuperando el parche asociado con un escondite y aplicándolo al revés:

$ git stash show -p stash@{0} | git apply -R

Nuevamente, si no especificas un alijo, Git asume el alijo más reciente:

$ git stash show -p | git apply -R

Es posible que desee crear un alias y agregar efectivamente un comando stash-nopply 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

Esto ya se ha vencido, pero si interpreto el problema correctamente, he encontrado una solución simple, tenga en cuenta que esta es una explicación en mi propia terminología:

git stash [save] guardará los cambios actuales y establecerá su rama actual en el estado limpio "

git stash list ofrece algo como: stash @ {0}: en desarrollo: cosas de prueba guardadas

git apply stash @ {0} establecerá la rama actual como antes de stash [guardar]

git checkout. establecerá la rama actual como después de stash [save]

El código que se guarda en el alijo no se pierde, se puede encontrar git apply stash @ {0} nuevamente.

¡De todos modos, esto funcionó para mí!

Además de la respuesta @Greg Bacon, en caso de que se agreguen archivos binarios al índice y formen parte del alijo utilizando

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

Agregar --binary resuelve el problema, pero desafortunadamente aún no he descubierto por qué.

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

Esto se suma a las respuestas anteriores, pero agrega la búsqueda del alijo git en función del mensaje, ya que el número de alijo puede cambiar cuando se guardan nuevos alijos. He escrito un par de funciones bash:

apply(){
  if [ "$1" ]; then
    git stash apply `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"`
  fi
}
remove(){
  if [ "$1" ]; then
    git stash show -p `git stash list | grep -oPm1 "(.*)(?=:.*:.*$1.*)"` | git apply -R
    git status
  fi
}
  1. Crear alijo con nombre (mensaje) $ git stash save " my stash "
  2. Para aplicar el nombre $ apply " my stash "
  3. Para eliminar el alijo con nombre $ remove " my stash "
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top