untracked stash name files git git-stash

name - Cómo ignorar trozos agregados en `git stash-p`



git stash untracked files (3)

Imagina este escenario:

# edit two files git add -p // add hunks from one file

Ahora, cuando ejecute git stash -p , nuevamente le preguntará si desea esconder los trozos que acaba de seleccionar a través de git add -p . ¿Hay alguna forma de configurar git para ignorar estos hunts ya agregados de forma predeterminada? La mayoría de las veces, no quiero esconder cosas que ya agregué.


Cuando se trata de git stash push (ya que llamar git stash sin ningún argumento es equivalente a git stash push ), considere agregar la opción --keep-index .

Significa que todos los cambios ya agregados al índice se dejan intactos.

Por lo tanto, la opción -p ( patch ) no debe consultar a esos tipos (ya en caché).

Nota: la opción --patch implica --keep-index , así que (para realizar pruebas) asegúrese de estar usando la última versión de Git disponible (2.17) e intente con git stash push -p .

Si el problema persiste, entonces, como se comentó, hacer una confirmación primero permitirá que un stash -p funcione con un índice limpio.
El git reset --soft @~ restaurará el índice confirmado.


De acuerdo con los comentarios, lo que se busca es un alijo de todos los cambios que aún no se han agregado (ya sea que se hayan excluido durante un git add -p , o simplemente no se hayan agregado todavía).

El motivo de esto es aplicar algunas pruebas / posibles ajustes al estado en etapas, antes de cometerlo.

Es un git stash -k directo git stash -k , guarda todo como de costumbre, pero mantén el estado indexado y el árbol de trabajo correspondiente, es decir, limpia del árbol de trabajo todo lo que no estoy dispuesto a cometer.

Asi que:

git stash -k git clang-format git commit

y el repositorio ahora tiene cuatro instantáneas interesantes: el contenido original, también conocido como base de alijo, el índice de instantáneas, el área de trabajo con instantáneas, y el índice actual (, commit y worktree) que es la instantánea de índice en el stash^2 con las limpiezas aplicadas. Tenga en cuenta que las tres nuevas instantáneas, también conocidas como confirmaciones aquí, tienen la base de ocultación como principal.

Ahora desea que su worktree vuelva a cambiar, pero claramente los cambios de la base al índice oculto y worktree no coinciden con los del índice actual y worktree (y nuevo commit, todos coinciden), por lo que cuando git va a hacer estallar el stash encontrará conflictos: los cambios de la base oculta al índice oculto no coinciden con los cambios de la base oculta al índice actual.

Si Git le ofreció lo que desea directamente, un "escondite de todos los cambios del árbol de trabajo, excepto los que están en el índice", usted podría haber usado eso y luego el pop de stash no tendría ningún problema, un git stash pop directo lo haría. Afortunadamente, si Git es bueno en algo, se está fusionando, combinando, dividiendo y, en general, compartiendo diferencias.

git cherry-pick -nm2 stash # cherry-pick updated the index, too. maybe git reset here to unstage that stuff. git stash drop

Stash pop es una combinación de los cambios de la base de ocultación al estado de ocultación con los cambios de la base de ocultación (que generalmente es notablemente similar a la base actual) al estado actual. Desea que los cambios del árbol de trabajo escondido vuelvan a estar en su árbol de trabajo, pero solo los que no ha agregado, ya que los que ha agregado todavía están aquí, son un poco diferentes ahora.

Por lo tanto, cherry-pick es -n , no commit, -m2 , la línea principal para los cambios es su segundo padre, es decir, todas las diferencias que hizo pero que no agregó al esconder.

Un ejemplo podría ayudar,

cd `mktemp -d` git init printf >file %s//n 1 2 3 4 5 git add .;git commit -m1 printf >file %s//n 1 2a 3 4 5 git add . printf >file %s//n 1 2a 3 4a 5

ahora ya ha git add -p ''d the 2a change, y el cambio de 4a es solo en su worktree.

$ git stash -k $ cat file 1 2a 3 4 5 $ sed -i ''2s,^,_,'' file # indent the 2a line $ git commit -am2

Ahora, el compromiso inicial,: :/1 , es 1 2 3 4 5 , su compromiso, índice y árbol de trabajo actuales son todos 1 _2a 3 4 5 , su índice oculto es 1 2a 3 4 5 y su árbol de trabajo escondido es 1 2a 3 4a 5 .

Los cambios que desea recuperar son la diferencia entre su índice escondido y su árbol de trabajo escondido, es decir, las diferencias del compromiso escondido de su segundo padre. Por lo tanto, esa selección de cereza.

Las formas alternativas de deletrear la selección de cereza incluyen

git cherry-pick -nm1 -Xours stash

que aplica todos los cambios de árbol de trabajo ocultos pero toma la versión local en caso de conflicto (básicamente es encontrar y deshacerse de las diferencias conflictivas en lugar de simplemente evitarlas como lo hace el -m2 ) y

git diff stash^2..stash|git apply -3

Hacer todo esto más fácil para ti mismo es un territorio de scripting, la forma más fácil de hablar sobre cómo configurarlo es como un alias de git,

git config --global alias.poptree ''!git cherry-pick -nm2 stash; git reset; git stash pop''

y ahora tienes un comando git poptree para hacer lo que quieras.

edición: como una nueva versión, supongamos que ha seguido adelante y realizado un trabajo más antes de recordar los cambios en su árbol de trabajo escondido, Cherry-Pick actualizará correctamente el árbol de trabajo y el índice, pero el restablecimiento anulará cualquier cambio que ya haya agregado al nuevo índice. Ahora estás en el territorio del comando del núcleo,

( index=`git write-tree` && git cherry-pick -nm2 stash && git read-tree $index && git stash drop )

Es como implementaría esto de verdad.


Hay un ejemplo similar en la página del manual:

hombre git alijo:

"Testing partial commits You can use git stash save --keep-index when you want to make two or more commits out of the changes in the work tree, and you want to test each change before committing: # ... hack hack hack ... $ git add --patch foo # add just first part to the index $ git stash save --keep-index # save all other changes to the stash"*

Puedo confirmar:

Si usa git stash -p (lo que implica --keep-index ), aún se le preguntará si los cambios que ya están en el índice deben ocultarse (como lo ha descrito).

Entonces, parece que la página de manual es confusa, que también se menciona en otra parte: https://github.com/progit/progit2/issues/822

Para resumirlo:

--keep-index (o -p que implica --keep-index ) simplemente deja el índice intacto. Los cambios ya efectuados todavía se insertan en el alijo. Y AFAIK, no hay manera de hacer lo que describiste.

O, más concretamente (de la página del manual):

With --patch, you can interactively select hunks from the diff between HEAD and the working tree to be stashed. The stash entry is constructed such that its index state is the same as the index state of your repository, and its worktree contains only the changes you selected interactively.

Alternativas:

Hay al menos 3 formas en que podría lograr lo que quiere (más o menos):

  • No uses -p con git stash. Guarde todo (con - --keep-index y posiblemente - --all , para asegurarse de que haya guardado todo de forma segura).
  • Confirma tus cambios en escena antes de esconder. De esa manera, no tendrá una diferencia entre HEAD y el árbol de trabajo para estos cambios que desea omitir del alijo. Pero, ¿qué pasa si no estás seguro de querer cometer esto todavía? Siempre puede hacer cambios más tarde y usar - --amend para cambiar la confirmación existente.
  • Cancele los cambios (elimínelos del índice) y luego guárdelos.