¿Cómo le dices a git que esconda el índice solamente?

Acabo de usar "git add -p" para agregar un montón de cambios al índice, y me di count de que me perdí un cambio que debería haber pasado a la confirmación anterior.

No puedo comprometerme –mendar ahora porque he agregado todos estos cambios nuevos al índice, y no quiero usar 'git reset' para eliminarlos del índice, ya que llevará años agregarlos a todos de nuevo adentro.

Lo que necesito es algo así como 'git stash' que solo esconderá el índice, debería dejar los files de trabajo en paz. Luego puedo esconder el índice, agregar el cambio que falta, confirmarlo, luego abrir el escondite y volver a tener mi índice como estaba.

No parece que 'git stash' pueda hacer esto, pero ¿me falta algo? ¡Gracias!

La forma más simple es dejar ese cambio en ese momento, hacer su nueva confirmación, luego crear una segunda confirmación con solo ese cambio que quiera usar para enmendar y luego usar git rebase -i para aplastarlo con la CABEZA original.

Una alternativa sería hacer su commit, labelrlo, deshacer con git reset HEAD^ , agregar ese cambio y corregir HEAD, luego seleccionar cuidadosamente su commit labeldo.

Lo más parecido que he encontrado es git stash --patch . Lo guía a través de cada uno de los cambios al tree de trabajo y al índice, lo que le permite elegir qué esconder.

http://www.kernel.org/pub/software/scm/git/docs/git-stash.html

Confirme su índice, cree un compromiso de reparación y vuelva a calcular usando autosquash:

 git commit git add -p # add the change forgotten from HEAD^ git commit --fixup HEAD^ # commits with "fixup! <commit message of HEAD^>" git rebase --autosquash -i HEAD~3 

git stash realidad crea una confirmación con el contenido del índice, y luego agrega una confirmación con el contenido de todos los files rastreados en la parte superior

Para ver esto: crea un alijo, luego ejecuta

 git log --oneline --graph stash@{0} 

Entonces, técnicamente, cuando guardas, puedes recuperar tu índice a través del stash@{0}^2 :

 $ git show --name-only stash@{0}^2 $ git checkout stash@{0}^2 -- . 

También puede esconder y luego get el contenido de los files rastreados pero no agregados :

 # get the diff between what was indexed and the full stashed content : $ git diff -p stash@{0}^2 stash@{0} > diff.patch # apply this diff : $ git apply diff.patch 

Esto parece funcionar No lo he probado en todas las situaciones para asegurarme de que sea robusto:

 git commit -m _stash && git stash && git reset HEAD^ && git stash save && git stash pop stash@{1} 

Sin embargo, compromete el índice de manera efectiva, oculta el directory de trabajo, revierte el compromiso para recuperar el índice, lo guarda como otro escondite y luego restaura el directory de trabajo original nuevamente desde el alijo.

Esto se simplifica al agregar esto como alias de git:

 [alias] istash = "!f() { git commit -m _stash && git stash && git reset HEAD^ && git stash save $1 && git stash pop stash@{1}; }; f" 

Esto me permite usarlo como:

 git istash [optional stash name] 

Solución 1:

¿Por qué no hacer trampa?

 git stash --keep-index 

para sacar todo lo que no está en el índice actualmente. Entonces,

 git stash 

para get un escondite con solo lo que está organizado.

 git stash pop 

el primer alijo, agrega tus cambios. Entonces,

 git commit --amend ... git reset --hard 

para limpiar el tree de trabajo y luego

 git stash pop --index 

para recuperar sus cambios de índice.

Magit para emacs te permite hacer esto con el command magit-stash-index

Tuve que hacer esto y terminé usando algunas de las opciones de git stash para scripting. Git stash create le permite crear (pero no aplicar) un object oculto (que incluye el índice). La tienda de Git Stash lo agrega a la stack de git stash sin hacer el reinicio de git, pero ese ahorro de git stash lo hace implícitamente. Esto, efectivamente, permite ocultar un índice agregando un object oculto a la stack y reiniciando el índice manualmente:

 # This will add an entry to your git stash stack, but *not* modify anything git stash store -m "Stashed index" $(git stash create) # This will reset the index, without touching the workspace. git reset --mixed 

Ahora, de hecho, has ocultado tu índice y puedes hacer un pop-git git stash cuando hayas terminado.

Una advertencia es que el object escondido creado incluye tanto los files modificados en el área de trabajo como en el índice, aunque solo le preocupa el índice, por lo que existe la posibilidad de que surjan conflictos cuando intente extraerlos de la stack aunque haya utilizado el – indicador de índice (que significa "también aplicar el índice del alijo", no "solo aplicar el índice del alijo"). En ese caso, puede hacer un "reinicio de git –hard" antes de abrir (porque los cambios que está restableciendo también son los mismos que los cambios que está reventando o aplicando inmediatamente después, no es tan peligroso como parece.)

Aquí hay un pequeño guión que se me ocurrió en el pasado para hacer exactamente esto:

(Nota: originalmente publiqué esto en http://sofes.miximages.com/a/17137669/531021 , pero parece aplicarse aquí también. Estas no son exactamente preguntas duplicadas, así que creo que sirve como una posible respuesta en ambos casos)

 #!/bin/sh # first, go to the root of the git repo cd `git rev-parse --show-toplevel` # create a commit with only the stuff in staging INDEXTREE=`git write-tree` INDEXCOMMIT=`echo "" | git commit-tree $INDEXTREE -p HEAD` # create a child commit with the changes in the working tree git add -A WORKINGTREE=`git write-tree` WORKINGCOMMIT=`echo "" | git commit-tree $WORKINGTREE -p $INDEXCOMMIT` # get back to a clean state with no changes, staged or otherwise git reset -q --hard # Cherry-pick the index changes back to the index, and stash. # This cherry-pick is guaranteed to suceed git cherry-pick -n $INDEXCOMMIT git stash # Now cherry-pick the working tree changes. This cherry-pick may fail # due to conflicts git cherry-pick -n $WORKINGCOMMIT CONFLICTS=`git ls-files -u` if test -z "$CONFLICTS"; then # If there are no conflicts, it's safe to reset, so that # any previously unstaged changes remain unstaged # # However, if there are conflicts, then we don't want to reset the files # and lose the merge/conflict info. git reset -q fi 

Puede save el script anterior como git-stash-index algún lugar de su ruta, y luego puede invocarlo como git stash-index

 # <hack hack hack> git add <files that you want to stash> git stash-index 

Ahora el alijo contiene una nueva input que solo contiene los cambios que había organizado, y su tree de trabajo aún contiene cambios no registrados.

El problema principal es que es posible que no pueda eliminar limpiamente los cambios indexados sin causar conflictos, por ejemplo, si el tree de trabajo contiene cambios que dependen de los cambios indexados.

En este caso, cualquier conflicto de este tipo se dejará en el estado de conflicto no compartido usual, de manera similar a después de un cherry-pick / merge.

p.ej

 git init echo blah >> "blah" git add -A git commit -m "blah" echo "another blah" >> blah git add -A echo "yet another blah" >> blah # now HEAD contains "blah", the index contains "blah\nanother blah" # and the working tree contains "blah\nanother blah\nyetanother blah" git stash-index # A new stash is created containing "blah\nanother blah", and we are # left with a merge conflict, which can be resolved to produce # "blah\nyet another blah"