¿Cómo escondes un archivo no rastreado?

1437

Tengo cambios en un archivo, más un nuevo archivo, y me gustaría usar git stash para guardarlos mientras cambio a otra tarea. Pero git stash por sí solo oculta solo los cambios en el archivo existente; el nuevo archivo permanece en mi árbol de trabajo, abarrotando mi trabajo futuro. ¿Cómo guardo este archivo no rastreado?

skiphoppy
fuente
27
Tenga en cuenta que si solo tiene archivos no rastreados en su alijo, parecerá que está vacío, ya que git stash showno devuelve nada y puede sentirse tentado a soltarlo (como acabo de hacer mientras contenía un script útil que escribí hace unos meses) → cómo recuperar un alijo caído )
Maxime R.

Respuestas:

1925

Para esconder su directorio de trabajo, incluidos los archivos no rastreados (especialmente aquellos que están en .gitignore), entonces probablemente quiera usar este cmd:

git stash --include-untracked

Más detalles:

Actualización 17 de mayo de 2018:

Ahora hay nuevas versiones de git git stash --allque ocultan todos los archivos, incluidos los archivos no rastreados e ignorados.
git stash --include-untrackedya no toca los archivos ignorados (probado en git 2.16.2).

Respuesta original a continuación:

Advertencia, hacer esto eliminará permanentemente sus archivos si tiene alguna entrada de directorio / * en su archivo gitignore.

A partir de la versión 1.7.7, puede usar git stash --include-untrackedo git stash save -uguardar archivos sin seguimiento sin organizarlos.

Agregue ( git add) el archivo y comience a rastrearlo. Entonces esconder. Como todo el contenido del archivo es nuevo, se guardará y podrá manipularlo según sea necesario.

sykora
fuente
44
¿Por qué stash todavía oculta los archivos existentes a pesar de que esos cambios no se han organizado?
Alan Christensen
66
@ alan-christensen Lea la DESCRIPCIÓN de kernel.org/pub/software/scm/git/docs/git-stash.html . El punto es tener un árbol de trabajo limpio después del escondite.
Kelvin
3
@Kelvin, lo que quise decir en mi comentario fue que no almacena archivos nuevos a menos que hayan sido almacenados, pero sí almacena archivos existentes, incluso si no han sido almacenados. Me parece inconsistente.
Alan Christensen
11
@AlanChristensen, el punto es esconder cosas que podrían sobrescribirse al pagar en una sucursal diferente.
jwg
3
Como tiene la respuesta principal aquí, le pediría que enumere git stash --include-untrackedantes git stash --allen su respuesta por dos razones. En primer lugar, responde a la pregunta del PO mejor ahora en 2019 y segundo porque --all hace algo que la mayoría de los usuarios probablemente no quiero, ya que elimina todos los archivos que se .gitignored
Daniel Flippance
411

A partir de git 1.7.7, git stashacepta la --include-untrackedopción (o abreviatura -u). Para incluir archivos no rastreados en su escondite, use cualquiera de los siguientes comandos:

git stash --include-untracked
git stash -u

Advertencia, hacer esto eliminará permanentemente sus archivos si tiene alguna entrada de directorio / * en su archivo gitignore.

John Kary
fuente
15
Genial: finalmente funciona como se describe en la página del manual. No guardar (y limpiar) archivos nuevos es un comportamiento roto.
Steve Bennett
1
mi versión de git es 1.9.1 e incluso si lo que tengo en esto se .gitignoreve así ignoredDirectoryy no ignoredDirectory/*, todavía elimina los que no se rastrean. Incluso archivos sin seguimiento, no solo directorios.
theUnknown777
22
¿Puedes por favor explicar la advertencia? ¿Por qué eliminaría esos archivos? ¿Los elimina y no los esconde? He usado Git por un tiempo y no me he encontrado con este problema.
Aleksandr Dubinsky
¿La advertencia se aplica también a las *.extensionentradas?
arekolek
3
@ aleksandr-dubinsky, @arekolek - La opción git1.8.3 -u( --include-untracked) puede esconder y reventar archivos git stash showno rastreados, pero no enumera los archivos no rastreados que están en el escondite
xilef
77

Agregue el archivo al índice:

git add path/to/untracked-file
git stash

Todo el contenido del índice, más cualquier cambio no escalonado a los archivos existentes, lo incluirá en el alijo.

skiphoppy
fuente
¿Qué sucede si no desea guardar los cambios que ya están en el índice? ¿Es posible guardar el nuevo archivo?
allyourcode
Confirme el índice, guarde el nuevo archivo, luego revierta el commit y / o extraiga los archivos del commit. Es una solución poco clara, pero debería funcionar.
Gdalya
git add .no lo estaba tomando en consideración por alguna razón
TheBilTheory
53

En git bash, el almacenamiento de archivos no rastreados se logra mediante el comando

git stash --include-untracked

o

git stash -u

http://git-scm.com/docs/git-stash

git stash elimina cualquier archivo no rastreado o no confirmado de su espacio de trabajo. Y puede revertir git stash usando los siguientes comandos

git stash pop

Esto colocará el archivo nuevamente en su espacio de trabajo local.

Mi experiencia

Tuve que realizar una modificación en mi archivo gitIgnore para evitar el movimiento de los archivos .classpath y .project en el repositorio remoto. No tengo permitido mover este .gitIgnore modificado en repositorio remoto a partir de ahora.

Los archivos .classpath y .project son importantes para eclipse, que es mi editor de Java.

En primer lugar, agregué selectivamente el resto de los archivos y me comprometí para la puesta en escena. Sin embargo, el empuje final no se puede realizar a menos que los archivos .gitIgnore modificados y los archivos no rastreados sean. .project y .classpath no están escondidos.

solía

 git stash 

para guardar el archivo .gitIgnore modificado.

Para guardar el archivo .classpath y .project, utilicé

git stash --include-untracked

y eliminó los archivos de mi espacio de trabajo. La ausencia de estos archivos me quita la capacidad de trabajar en mi ubicación de trabajo en eclipse. Continué completando el procedimiento para enviar los archivos comprometidos a control remoto. Una vez que esto se hizo con éxito, usé

git stash pop

Esto pegó los mismos archivos en mi espacio de trabajo. Esto me devolvió mi capacidad de trabajar en el mismo proyecto en eclipse. Espero que esto deje de lado los conceptos erróneos.

DolphinJava
fuente
2
¿Por qué no usas gitignore global para archivos IDE? Es decir. uso ~/.gitignore.
Antti Pihlaja
20

Como se ha dicho en otra parte, la respuesta es al git addarchivo. p.ej:

git add path/to/untracked-file
git stash

Sin embargo, la pregunta también se plantea en otra respuesta: ¿Qué sucede si realmente no desea agregar el archivo? Bueno, por lo que puedo ver, tienes que hacerlo. Y lo siguiente NO funcionará:

git add -N path/to/untracked/file     # note: -N is short for --intent-to-add
git stash

esto fallará, como sigue:

path/to/untracked-file: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state

¿Entonces que puedes hacer? Bueno, realmente debe agregar el archivo, sin embargo , puede desagruparlo efectivamente más adelante, con git rm --cached:

git add path/to/untracked-file
git stash save "don't forget to un-add path/to/untracked-file" # stash w/reminder
# do some other work
git stash list
# shows:
# stash@{0}: On master: don't forget to un-add path/to/untracked-file
git stash pop   # or apply instead of pop, to keep the stash available
git rm --cached path/to/untracked-file

Y luego puede continuar trabajando, en el mismo estado en el que estaba antes git add(es decir, con un archivo path/to/untracked-fileno rastreado llamado ; más cualquier otro cambio que haya tenido que rastrear archivos).

Otra posibilidad para un flujo de trabajo en esto sería algo como:

git ls-files -o > files-to-untrack
git add `cat files-to-untrack` # note: files-to-untrack will be listed, itself!
git stash
# do some work
git stash pop
git rm --cached `cat files-to-untrack`
rm files-to-untrack

[Nota: Como se menciona en un comentario de @mancocapac, es posible que desee agregar --exclude-standardal git ls-filescomando (así que git ls-files -o --exclude-standard).]

... que también se puede escribir fácilmente: incluso los alias funcionarían (presentado en sintaxis zsh; ajustar según sea necesario) [también, acorté el nombre del archivo para que todo se ajuste en la pantalla sin desplazarse en esta respuesta; no dude en sustituir un nombre de archivo alternativo de su elección]:

alias stashall='git ls-files -o > .gftu; git add `cat .gftu`; git stash'
alias unstashall='git stash pop; git rm --cached `cat .gftu`; rm .gftu'

Tenga en cuenta que este último podría ser mejor como un script o función de shell, para permitir que los parámetros que se deben proporcionar a git stash, en caso de que no desea popsino apply, y / o quieren ser capaces de especificar un alijo específica, en lugar de limitarse a tomar la parte superior uno. Quizás esto (en lugar del segundo alias, arriba) [espacio en blanco despojado para ajustarse sin desplazarse; re-agregar para mayor legibilidad]:

function unstashall(){git stash "${@:-pop}";git rm --cached `cat .gftu`;rm .gftu}

Nota : en este formulario, debe proporcionar un argumento de acción, así como el identificador si va a proporcionar un identificador oculto, por ejemplo, unstashall apply stash@{1}ounstashall pop stash@{1}

Lo que, por supuesto, pondría en su .zshrco equivalente para hacer que exista a largo plazo.

Esperemos que esta respuesta sea útil para alguien, ya que reúne todo en una sola respuesta.

lindes
fuente
1
git ls-files -o muestra muchos más archivos que los que me interesan. del siguiente estado de git que encontré agregando --exclude-standard works. git ls-files -o --exclude-standard. Mi opinión sobre esto es que solo "incluye" los archivos sin seguimiento que normalmente no ignoraría, es decir, solo muestra los archivos sin seguimiento que su .gitignore no filtraría
mancocapac
20

En git versión 2.8.1: lo siguiente funciona para mí.

Para guardar archivos modificados y no rastreados en un alijo sin nombre

git stash save -u

Para guardar archivos modificados y sin seguimiento en un alijo con un nombre

git stash save -u <name_of_stash>

Puede usar pop o aplicar más tarde de la siguiente manera.

git stash pop

git stash apply stash@{0}
usuario1012513
fuente
Esto no eliminó los archivos no rastreados de mi computadora, aunque ya no figuraban como no rastreados. git stash showNo les mostró. Cuando lo intenté git stash apply, recibí "error: no se pudieron restaurar los archivos no rastreados desde el escondite". Sin embargo, los archivos se enumeraron una vez más como no rastreados, pero los cambios en los archivos rastreados no se restauraron. Creo que esos archivos podrían restaurarse individualmente al sacarlos del escondite, pero esta solución no era lo que esperaba.
hBrent
9

Pude esconder solo los archivos no rastreados haciendo:

git stash save "tracked files I'm working on"
git stash save -u "untracked files I'm trying to stash"
git stash pop stash@{1}

El último muestra el alijo de los archivos rastreados, dejando solo los archivos no rastreados escondidos.

Oded
fuente
git stash save -uno solo guarda los untrackedarchivos, sino también los archivos trackedy untracked. Creo que el primer salvamento que estás haciendo no es necesario en este caso. Hay un buen diagrama en atlassian.com/git/tutorials/saving-changes/…
Drenai
2
La pregunta es cómo esconder solo los archivos no rastreados. Si omite el primer alijo, ¿qué sacará? La idea es: 1) Stash rastreado. 2) Alijo sin seguimiento. 3) Pop rastreado. Resultado: los restos no rastreados escondidos.
Oded
3

Si desea guardar archivos no rastreados, pero mantener los archivos indexados (los que está a punto de confirmar, por ejemplo), simplemente agregue la -kopción (mantener índice) a-u

git stash -u -k
Tdy
fuente
2

supongamos que el archivo nuevo y sin seguimiento se llama: "views.json". si desea cambiar de sucursal ocultando el estado de su aplicación, generalmente escribo:

git add views.json

Entonces:

git stash

Y sería escondido. Entonces puedo cambiar de rama con

git checkout other-nice-branch
martline1
fuente
1

Hay varias respuestas correctas aquí, pero quería señalar que para los nuevos directorios enteros, 'git add path'lo hará NO trabajo. Entonces, si tiene un montón de archivos nuevos en la ruta sin seguimiento y haga esto:

git add untracked-path
git stash "temp stash"

esto se esconderá con el siguiente mensaje:

Saved working directory and index state On master: temp stash
warning: unable to rmdir untracked-path: Directory not empty

y si sin seguimiento de la ruta es el único camino que eres esconder, el alijo "escondite temporal" será un alijo vacía. La forma correcta es agregar la ruta completa, no solo el nombre del directorio (es decir, finalizar la ruta con un '/'):

git add untracked-path/
git stash "temp stash"
DrStrangepork
fuente
Al menos en mi sistema su suposición es incorrecta. Funciona sin la barra! Los directorios vacíos se ignoran de todos modos. (macos git 2.6.2)
phobie
0

Pensé que esto podría resolverse diciéndole a git que el archivo existe, en lugar de enviar todo el contenido al área de preparación, y luego llamar git stash. Araqnid describe cómo hacer lo primero.

git add --intent-to-add path/to/untracked-file

o

git update-index --add --cacheinfo 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 path/to/untracked-file

Sin embargo, este último no funciona:

$ git stash
b.rb: not added yet
fatal: git-write-tree: error building trees
Cannot save the current index state
Andrew Grimm
fuente
1
Por lo que puedo decir, el primero tampoco funciona. Vea mi respuesta para una solución a este problema.
lindes
0
git stash --include-untracked

mi favorito, ya que guarda también los archivos que ha agregado y no los ha montado.

Hovhannes Babayan
fuente
0

Encontré un problema similar al usar Sourcetree con archivos recién creados (tampoco se incluirían en el alijo).

Cuando elegí por primera vez 'poner todo en escena' y luego esconder los componentes recién agregados donde fueron rastreados y, por lo tanto, incluidos en el alijo.

Ivo van Leeuwen
fuente
Esta pregunta tiene 11 años y ya tiene 14 respuestas. ¿Los has leído antes de publicar?
Mickael B.
-7

Solía ​​reflexionar y desear la misma característica. Pero con el tiempo, noté que realmente no es necesario. Cuando guardas, está bien dejar los nuevos archivos. Nada "malo" puede sucederles (cuando revisas algo más, git producirá un error y no sobrescribirá el archivo sin seguimiento existente)

Y dado que, por lo general, el período de tiempo entre el git stashy el git stash popes bastante pequeño, necesitará el archivo sin seguimiento rápidamente nuevamente. Entonces, diría que el inconveniente de que el archivo aparezca git statusmientras trabajas en otra cosa (entre el git stashy el git stash pop) es menor que el inconveniente causado por el trabajo y la atención necesaria que de lo contrario costaría tratar de agregar el archivo sin seguimiento a tu escondite

Dieter_be
fuente
15
Depende del proyecto. Digamos que el archivo no rastreado es una prueba unitaria (medio escrita) y el arnés de prueba ejecuta todas las pruebas unitarias en el directorio. Etc.
Steve Bennett
1
Otro ejemplo es si trabaja en dos computadoras y puede mover datos de A a B, pero no de B a A. Si crea una nueva pieza de código para resolver un problema que ocurre primero en B pero que desea en A y B, desea poder guardar el archivo en B para que cuando vuelva a crear ese archivo en A y luego lo traiga en un paquete, pueda obtener la versión oculta para verificar que no lo hizo cometer un error.
Gdalya
77
El hecho de que un archivo no se rastree en una rama no significa que no entrará en conflicto con un archivo rastreado en otra rama.
jwg
3
contraejemplo simple: archivo de configuración en el directorio .conf.d, o cualquier otro que solo al estar allí modifica el comportamiento del software.
Fotanus
Por supuesto que se necesita la funcionalidad. Como ejemplo adicional, no es posible cambiar de una rama a otra si tiene archivos localmente no rastreados que desea guardar.
Demitrian