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}^1significa 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/stashes 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 checkoutla página del manual. No puede colocar el archivo en otra ubicación. Hay una referencia a esto en: stackoverflow.com/questions/888414/…git checkoutenfoque copia el archivo exacto del alijo, no lo combina con lo que está en su directorio de trabajo como logit stash applyharía. (Entonces, si tiene algún cambio desde la base en la que se creó el alijo, se perderán).git stash applypoder 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 popharía.Si usa en
git stash applylugar degit stash pop, aplicará el alijo a su árbol de trabajo, pero aún lo mantendrá.Una vez hecho esto, puede
add/commitel 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
0con 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.--patchhace una fusión interactiva, aplica cualquier trozo que apruebe en el shell (o lo que guarde si elige dejareel 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
diffcondifftoolpara 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 stashpara 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 stashpara esconderlos a todos,git stash applypara recuperarlos nuevamente y luegogit checkout f.cen el archivo en cuestión para restablecerlo de manera efectiva.Cuando desee deshacer la ejecución de ese archivo, ejecute a
git reset --hardy luegogit stash applyvuelva a ejecutar , aprovechando el hecho de quegit stash applyno 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 poppara desapilarlos,git add fileWantToKeeppara 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 checkoutporque 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