Me gustaría saber si es posible extraer un solo archivo o diff de un archivo de un escondite de git sin hacer estallar el conjunto de cambios de escondite.
¿Alguien podría proporcionar algunas sugerencias / ideas sobre esto?
En la página de manual de git stash puedes leer (en la sección "Discusión", justo después de la descripción de "Opciones") que:
Una reserva se representa como una confirmación cuyo árbol registra el estado del directorio de trabajo, y su primer padre es la confirmación en HEAD cuando se creó la reserva.
Por lo tanto, puede tratar el alijo (por ejemplo, el alijo stash@{0}
primero / superior) como una confirmación de fusión y usar:
$ git diff stash@{0}^1 stash@{0} -- <filename>
Explicación: stash@{0}^1
significa el primer padre del alijo dado, que como se indica en la explicación anterior es el compromiso en el que se guardaron los cambios. Utilizamos esta forma de "git diff" (con dos commits) porque stash@{0}
/ refs/stash
es un commit de fusión, y tenemos que decirle a git contra qué padre queremos diferenciarnos. Más críptico:
$ git diff stash@{0}^! -- <filename>
también debería funcionar (consulte la página de manual de git rev-parse para obtener una explicación de la rev^!
sintaxis, en la sección "Especificar rangos").
Del mismo modo, puede usar git checkout para verificar un solo archivo fuera del escondite:
$ git checkout stash@{0} -- <filename>
o para guardarlo con otro nombre de archivo:
$ git show stash@{0}:<full filename> > <newfile>
o
$ git show stash@{0}:./<relative filename> > <newfile>
( tenga en cuenta que aquí <nombre de archivo completo> es el nombre de ruta completo de un archivo relativo al directorio superior de un proyecto (piense: relativo a stash@{0}
)).
Es posible que deba protegerse stash@{0}
de la expansión de shell, es decir, usar "stash@{0}"
o 'stash@{0}'
.
git checkout
la página del manual. No puede colocar el archivo en otra ubicación. Hay una referencia a esto en: stackoverflow.com/questions/888414/…git checkout
enfoque copia el archivo exacto del alijo, no lo combina con lo que está en su directorio de trabajo como logit stash apply
haría. (Entonces, si tiene algún cambio desde la base en la que se creó el alijo, se perderán).git stash apply
poder fusionar los cambios en un archivo que se ha modificado en el árbol de trabajo desde que se guardó el archivo, ese archivo en el árbol de trabajo debe estar organizado. Para que la fusión automática funcione, los mismos archivos no se pueden modificar tanto en la copia de trabajo como en la copia oculta para fusionar. Finalmente, la aplicación de alijo no elimina el elemento del alijo como logit stash pop
haría.Si usa en
git stash apply
lugar degit stash pop
, aplicará el alijo a su árbol de trabajo, pero aún lo mantendrá.Una vez hecho esto, puede
add
/commit
el archivo que desee y luego restablecer los cambios restantes.fuente
git stash pop stash@{0}
(lista de los cambios escondidos:git stash list
)Hay una manera fácil de obtener cambios desde cualquier rama, incluidas las reservas:
Puede omitir la especificación del archivo si desea parchear en muchas partes. O bien, omita el parche (pero no la ruta) para obtener todos los cambios en un solo archivo. Reemplace
0
con el número de alijo degit stash list
, si tiene más de uno. Tenga en cuenta que esto es asídiff
, y ofrece aplicar todas las diferencias entre las ramas. Para obtener cambios de un solo commit / stash, échale un vistazogit cherry-pick --no-commit
.fuente
git help checkout
.--patch
hace una fusión interactiva, aplica cualquier trozo que apruebe en el shell (o lo que guarde si elige dejare
el parche). La ruta sola sobrescribirá el archivo, como escribí, "todos los cambios".git config --global alias.applydiffat '!git checkout --patch "$1" -- $(git diff --name-only "$1"^ "$1")'
luegogit applydiffat stash@{4}
solo se utilizan archivos que cambiaron entre el alijo y su padre.Respuesta corta
Para ver el archivo completo:
git show stash@{0}:<filename>
Para ver la diferencia:
git diff stash@{0}^1 stash@{0} -- <filename>
fuente
diff
condifftool
para usar su diferencial externo favorito.Notas:
Asegúrese de poner espacio después de "-" y el parámetro de nombre de archivo
Reemplace cero (0) con su número de alijo específico. Para obtener una lista oculta, use:
Basado en la respuesta de Jakub Narębski - Versión más corta
fuente
Puede obtener la diferencia para un alijo con "
git show stash@{0}
" (o cualquiera que sea el número del alijo; vea "lista de alijo git"). Es fácil extraer la sección de la diferencia para un solo archivo.fuente
git show stash
para mostrar el escondite más alto (normalmente el único que tienes). Del mismo modo, puede mostrar la diferencia entre su rama actual y el alijo congit diff head stash
.El concepto más simple de entender, aunque tal vez no sea el mejor, es que tiene tres archivos modificados y desea guardar un archivo.
Si lo hace
git stash
para esconderlos a todos,git stash apply
para recuperarlos nuevamente y luegogit checkout f.c
en el archivo en cuestión para restablecerlo de manera efectiva.Cuando desee deshacer la ejecución de ese archivo, ejecute a
git reset --hard
y luegogit stash apply
vuelva a ejecutar , aprovechando el hecho de quegit stash apply
no borra la diferencia de la pila de almacenamiento.fuente
Si los archivos escondidos necesitan fusionarse con la versión actual, use las formas anteriores usando diff. De lo contrario, puede usar
git pop
para desapilarlos,git add fileWantToKeep
para organizar su archivo y hacer ungit stash save --keep-index
, para guardar todo excepto lo que está en el escenario. Recuerde que la diferencia de esta manera con las anteriores es que "saca" el archivo del alijo. Las respuestas anteriores lo mantienen degit checkout stash@{0} -- <filename>
acuerdo con sus necesidades.fuente
Use lo siguiente para aplicar los cambios a un archivo en un alijo a su árbol de trabajo.
Esto generalmente es mejor que usarlo
git checkout
porque no perderá ningún cambio que haya realizado en el archivo desde que creó el alijo.fuente
Use la extensión Git Stash en Visual Studio Code
fuente