separate name initial git git-stash

name - git initial



¿Por qué `git stash-p` a veces falla? (5)

I ♥ git stash -p . Pero a veces, después de una sesión satisfactoria de y , n , y s , obtengo esto:

Saved working directory and index state WIP on foo: 9794c1a lorum ipsum error: patch failed: spec/models/thing_spec.rb:65 error: spec/models/thing_spec.rb: patch does not apply Cannot remove worktree changes

¿Por qué?


Aplicar el estado puede fallar con conflictos; en este caso, no se elimina de la lista oculta. Debes resolver los conflictos a mano y llamar a git stash drop manualmente luego


Después de tener un git stash -p fallar de esta misma manera, tuve suerte con esta solución (git 2.0.2):

  • git add -p , dividiendo exactamente los mismos trozos, pero con respuestas inversas ("y" para add "guarda" cambios, "n" para stash cambios).
  • git stash -k para mantener el índice y esconder todo lo demás
  • git reset para seguir trabajando en mis archivos

No estoy seguro de por qué git add -p no falló de la misma manera que git stash -p . Supongo que porque agregar funciona con el índice en lugar de crear un archivo de parche?


Esto sucede para mí cada vez que trato de dividir un trozo en trozos más pequeños que están demasiado juntos (menos de 3 líneas entre los cambios). La breve explicación es que el parche tiene líneas de contexto que entran en conflicto con los cambios locales. Explicación más completa a continuación.

Supongamos que tengo un repositorio git con estos cambios no confirmados:

--- a/pangram +++ b/pangram @@ -1,8 +1,8 @@ The -quick +relatively quick brown fox -jumps +walks over the lazy

Si guardo el primer cambio, obtengo:

--- a/pangram +++ b/pangram @@ -1,5 +1,5 @@ The -quick +relatively quick brown fox jumps

El comando git stash realmente logra guardar el parche (verifique la git stash list ), pero luego git usa ese parche al revés para eliminar los cambios escondidos de mi directorio de trabajo. El contexto después de que el trozo tiene "saltos", que no coincide con los "paseos" todavía en mi directorio de trabajo. Así que git se rescata con

error: patch failed: pangram:1 error: pangram: patch does not apply Cannot remove worktree changes

y deja todos los cambios en mi directorio de trabajo, y el alijo se vuelve prácticamente inútil.

Llamaría a esto un error en el soporte de división de trozos de git. Si sabe que está dividiendo los cambios demasiado cerca, podría restar unas pocas líneas de contexto del parche, o eliminar el parche para tener las líneas de contexto modificadas en lugar de las prístinas. Alternativamente, si dividir trozos de este tipo es oficialmente incompatible, en realidad debería negarse a dividir trozos que se cierren.


La respuesta aceptada en este momento todavía puede desafortunadamente fallar, incluso en Git 2.17.

Si, como yo, hiciste un gran esfuerzo construyendo el alijo perfecto y no quieres tirar ese esfuerzo, aún es posible conseguir lo que quieres:

git stash show -p | patch -p1 -R

Esto fallará con los rechazos, pero las probabilidades son buenas. La mayoría de los problemas se aplicarán correctamente y al menos le ahorrarán el tiempo de revisar todos los archivos nuevamente.


git stash -p debería fallar con Git 2.17 (Q2 2018).
Antes de eso, " git add -p " (que comparte la lógica con git stash ) ha sido flojo en la fusión de parches de división antes de pasar el resultado a la " git apply " subyacente, dando lugar a errores de esquina; la lógica para preparar el parche que se aplicará después de las selecciones de trozos se ha ajustado.

Ver commit 3a8522f , commit b3e0fcf , commit 2b8ea7f (05 Mar 2018), commit fecc6f3 , commit 23fea4c , commit 902f414 (01 Mar 2018), y commit 11489a6 , commit e4d671c , commit 492e60c (19 Feb 2018) por Phillip Wood ( phillipwood ) .
(Fusionada por Junio ​​C Hamano - gitster - en cometer 436d18f , 14 de marzo de 2018)

add -p : ajusta las compensaciones de trozos posteriores cuando se omite uno

(Agregar, pero de nuevo, se puede aplicar al escondite)

Desde commit 8cbd431 (" git-add--interactive : replace hunk recuento con apply --recount", 2008-7-2, Git v1.6.0-rc0) si se omite un hunk entonces confiamos en las líneas de contexto para aplicar subsiguientes Trozos en el lugar correcto.

Si bien esto funciona la mayor parte del tiempo, es posible que terminen siendo aplicados en el lugar equivocado.

Para solucionarlo, ajuste el desplazamiento de los trozos siguientes para corregir cualquier cambio en el número de inserciones o eliminaciones debido al trozo omitido. El cambio en la compensación debido a trozos editados que tienen el número de inserciones o eliminaciones modificadas se ignora aquí, se solucionará en la siguiente confirmación.

Puedes ver algunas pruebas aquí .

Git 2.19 mejora git add -p : cuando el usuario edita el parche en " git add -p " y el editor del usuario está configurado para quitar espacios blancos finales indiscriminadamente, una línea vacía que no se modifica en el parche se volvería completamente vacía (en lugar de una línea) con un único SP en él).
El código introducido en el marco temporal de Git 2.17 no pudo analizar ese parche, pero ahora aprendió a notar la situación y a lidiar con ella.

Ver commit f4d35a6 (11 de junio de 2018) por Phillip Wood ( phillipwood ) .
(Fusionado por Junio ​​C Hamano - gitster - en commit 5eb8da8 , 28 de junio de 2018)