¿Guardar solo un archivo de varios archivos que han cambiado con Git?

3071

¿Cómo puedo guardar solo uno de los múltiples archivos modificados en mi sucursal?

Rachel
fuente
109
No creo que la respuesta aceptada de @bukzor sea una respuesta correcta a la pregunta tal como fue formulada. git stash --keep-indexmantiene el índice, pero oculta todo , tanto dentro como fuera del índice.
Raman
@ Antonio Me parece que tu recompensa debería ser una pregunta separada, ya que la pregunta original no tiene nada que ver específicamente con TortoiseGit.
JesusFreke
1
@JesusFreke Sí, dado el resultado, podría haber ahorrado 50 repeticiones :) Es solo que esta es la pregunta a la que se te redirige si intentas buscar "tortoisegit oculto parcial". Tortoisegit no parece ser un tema popular aquí stackoverflow.com/questions/tagged/tortoisegit
Antonio
77
>>>>>>>>> git diff -- *filename* > ~/patchluego git checkout -- *filename*y luego puede volver a aplicar el parche congit apply ~/patch
neaumusic
36
La mayoría de las respuestas existentes a continuación están desactualizadas. Desde Git 2.13 (Q2 2017) es compatible con git stash push [--] [<pathspec>...].
Ohad Schneider

Respuestas:

1372

Descargo de responsabilidad : la siguiente respuesta es para git antes de git 2.13. Para git 2.13 y más, mira otra respuesta más abajo .


Advertencia

Como se señaló en los comentarios, esto pone todo en el alijo, tanto en escena como en escena. --Keep-index solo deja el índice solo después de que se realiza el escondite. Esto puede causar conflictos de fusión cuando más tarde revienta el alijo.


Esto esconderá todo lo que no haya agregado previamente. Solo git addlas cosas que desea conservar, luego ejecútelo.

git stash --keep-index

Por ejemplo, si desea dividir una confirmación anterior en más de un conjunto de cambios, puede utilizar este procedimiento:

  1. git rebase -i <last good commit>
  2. Marcar algunos cambios como edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Arregle las cosas según sea necesario. No te olvides de git addningún cambio.
  7. git commit
  8. git stash pop
  9. Repita, desde el n. ° 5, según sea necesario.
  10. git rebase --continue
bukzor
fuente
47
Creo que este enfoque es mucho más simple: stackoverflow.com/a/5506483/457268
k0pernikus
561
No estoy seguro de por qué se está votando esto. Todos deben tener una expectativa diferente a la mía. La publicación original pregunta "¿Cómo guardo solo una parte de los cambios no confirmados?" Cuando lo uso git stash save -k, sí, el índice (entrada verde git stat) se conserva, pero todo el conjunto de cambios (tanto verde como rojo) entra en el alijo. Esto viola la solicitud del OP, "esconder solo algunos cambios". Quiero esconder solo algunos de los rojos (para uso futuro).
Pistos
70
Si está más interesado en la respuesta a la pregunta planteada por @Pistos (como estaba yo), mire aquí: stackoverflow.com/questions/5506339/…
Raman
27
@Raman: ¡Excelente! git stash -pes exactamente lo que estaba buscando Me pregunto si este interruptor se agregó recientemente.
Pistos
14
ADVERTENCIA: git stash --keep-indexestá roto. Si realiza más cambios, intente git stash popluego obtener conflictos de fusión porque el alijo incluye los archivos modificados que guardó, no solo los que no guardó. Por ejemplo: cambio los archivos A y B, luego oculto B, porque quiero probar los cambios en A; Encuentro un problema con A que luego soluciono; Yo cometo A; Ahora no puedo deshacerme porque una versión antigua de A está en el alijo sin ninguna buena razón causando un conflicto de fusión. En la práctica, A y B pueden ser muchos archivos, tal vez incluso imágenes binarias o algo así, básicamente tengo que rendirme y perder B.
rjmunro
3015

También puedes usar git stash save -p "my commit message". De esta manera, puede seleccionar qué trozos se deben agregar al alijo, también se pueden seleccionar archivos completos.

Se te indicarán algunas acciones para cada trozo:

   y - stash this hunk
   n - do not stash this hunk
   q - quit; do not stash this hunk or any of the remaining ones
   a - stash this hunk and all later hunks in the file
   d - do not stash this hunk or any of the later hunks in the file
   g - select a hunk to go to
   / - search for a hunk matching the given regex
   j - leave this hunk undecided, see next undecided hunk
   J - leave this hunk undecided, see next hunk
   k - leave this hunk undecided, see previous undecided hunk
   K - leave this hunk undecided, see previous hunk
   s - split the current hunk into smaller hunks
   e - manually edit the current hunk
   ? - print help
konrad.kruczynski
fuente
55
No era. Fue prestado de Darcs, unos 7 años después del hecho.
nomen
66
Soy un adicto a TortoiseGit. Sin embargo, TortoiseGit no es compatible stash -p. Otorgo esta respuesta porque sigue siendo la más interactiva / fácil de usar.
Antonio
27
es posible que desee agregar git stash save -p my stash message:; ya que el orden de los argumentos no es muy intuitivo ...
Chris Maes
15
Entre esto y git log -p, creo que la -pbandera debe significar "hacer lo genial que quiero pero no sé cómo expresarme".
Kyle Strand
2
¿Por qué demonios esta gran respuesta está en la posición 12? después de todas esas respuestas 0, +1, +2 ??????
DenisFLASH el
550

Dado que git se trata fundamentalmente de administrar un contenido e índice de todo el repositorio (y no uno o varios archivos), las git stashofertas, no sorprendentemente,con todo el directorio de trabajo.

En realidad, desde Git 2.13 (Q2 2017), puede guardar archivos individuales con git stash push:

git stash push [--] [<pathspec>...]

Cuando pathspecse le da a ' git stash push', el nuevo alijo registra los estados modificados solo para los archivos que coinciden con la especificación de la ruta. Consulte " Cambios del alijo a archivos específicos " para obtener más información.

Ejemplo simplificado:

 git stash push path/to/file

El caso de prueba para esta función muestra algunas opciones más desactivadas:

test_expect_success 'stash with multiple pathspec arguments' '
    >foo &&
    >bar &&
    >extra &&
    git add foo bar extra &&

    git stash push -- foo bar &&   

    test_path_is_missing bar &&
    test_path_is_missing foo &&
    test_path_is_file extra &&

    git stash pop &&
    test_path_is_file foo &&
    test_path_is_file bar &&
    test_path_is_file extra

La respuesta original (a continuación, junio de 2010) fue sobre seleccionar manualmente lo que desea guardar.

CasebashComentarios de :

Este el stash --patch solución original) es buena, pero a menudo modifico muchos archivos, por lo que usar parche es molesto

bukzor 's respuesta (upvoted, noviembre de 2011) sugiere una solución más práctica, en base a
git add+git stash --keep-index .
Ve a ver y vota su respuesta, que debería ser la oficial (en lugar de la mía).

Sobre esa opción, chhh señala un flujo de trabajo alternativo en los comentarios:

deberías " git reset --soft" después de un alijo para recuperar tu puesta en escena clara:
para llegar al estado original, que es un área de puesta en escena clara y con solo algunas modificaciones seleccionadas sin puesta en escena, uno podría restablecer suavemente el índice para obtener (sin cometer algo como tú, bukzor, lo hizo).


(Respuesta original de junio de 2010: alijo manual)

Sin embargo, git stash save --patchpodría permitirte lograr el alijo parcial que buscas:

Con --patch, puede seleccionar interactivamente trozos en la diferencia entre HEAD y el árbol de trabajo que se va a guardar.
La entrada oculta se construye de manera tal que su estado de índice es el mismo que el estado de índice de su repositorio, y su árbol de trabajo contiene solo los cambios que seleccionó interactivamente. Los cambios seleccionados se revierten de su árbol de trabajo.

Sin embargo, eso guardará el índice completo (que puede no ser lo que desea, ya que podría incluir otros archivos ya indexados) y un árbol de trabajo parcial (que podría parecerse al que desea guardar).

git stash --patch --no-keep-index

podría ser una mejor opción.


Si --patch no funciona, un proceso manual podría:

Para uno o varios archivos, una solución intermedia sería:

  • copiarlos fuera del repositorio de Git
    (en realidad, eleotlecram propone una alternativa interesante )
  • git stash
  • copiarlos de nuevo
  • git stash # esta vez, solo se guardan los archivos que deseas
  • git stash pop stash@{1} # vuelve a aplicar todas las modificaciones de tus archivos
  • git checkout -- afile # restablecer el archivo al contenido HEAD, antes de cualquier modificación local

Al final de ese proceso bastante engorroso, solo tendrá uno o varios archivos escondidos.

VonC
fuente
3
Esto es bueno, pero a menudo he modificado muchos archivos, por lo que usar parche es molesto
Casebash es el
66
@VonC: Es un buen estilo tener solo una respuesta por respuesta. Además, copiar y pegar las respuestas de los demás en las suyas es de mala educación.
bukzor
3
@bukzor: Lamento que mi respuesta editada pareciera incorrecta. Mi única intención era dar a su respuesta más visibilidad. He editado de nuevo mi publicación para aclarar esa intención.
VonC 12/12/11
1
@Kal: verdadero, stackoverflow.com/a/13941132/6309 sugiere un git reset(mixto)
VonC
3
git is fundamentally about managing a all repository content and index and not one or several files- esa es la implementación que eclipsa el problema que se está resolviendo; Es una explicación, pero no una justificación. Cualquier sistema de control de fuente es sobre "administrar varios archivos". Solo mira qué comentarios son los más votados.
Victor Sergienko
90

Cuando git stash -p(o git add -pcon stash --keep-index) sería demasiado engorroso, me resultó más fácil de usar diff, checkoutyapply :

Para "esconder" solo un archivo / directorio particular:

git diff path/to/dir > stashed.diff
git checkout path/to/dir

Luego después

git apply stashed.diff
azulado
fuente
1
Alternativa interesante a la git add -pque mencioné en mi propia respuesta anterior. +1.
VonC
11
Tenga en cuenta que si tiene archivos binarios (como PNG), no se enviarán al archivo diff. Entonces esta no es una solución 100%.
void.pointer
1
@RobertDailey: Ese es un punto interesante para mí, ya que son git diff > file.diffy git applyson mis herramientas habituales de escondite parcial. Puede que tenga que considerar cambiar a git stash -pconjuntos de cambios más grandes.
thekingoftruth
1
@thekingoftruth Aquí es el alias que uso para crear archivos de revisión, y se hace binarios de apoyo: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Sin embargo, tenga en cuenta que esto requiere que se confirmen los cambios para el parche.
void.pointer
2
Esto no funcionaba limpiamente para mí si el archivo para guardar era algo así ../../foo/bar.txt. El parche genera OK, pero luego necesito moverme a la raíz del repositorio para que se aplique el parche. Entonces, si tiene problemas con esto, solo asegúrese de hacerlo desde el directorio raíz del repositorio.
Michael Anderson
86

Uso git stash push, así:

git stash push [--] [<pathspec>...]

Por ejemplo:

git stash push -- my/file.sh

Está disponible desde Git 2.13, lanzado en la primavera de 2017.

Sandstrom
fuente
1
Pero git stash pushya mencioné en mi respuesta anterior el pasado marzo, hace 5 meses. Y detallé ese nuevo comando Git 2.13 aquí: stackoverflow.com/a/42963606/6309 .
VonC
¡Estoy feliz de que Git esté avanzando tan rápido, durante mucho tiempo esto no fue posible y luego se lanzó 2.13 y de repente hay una solución simple disponible!
Sandstrom
1
@VonC tienes razón, también mencionas la respuesta correcta, sin embargo, entre las dos respuestas, esta es más fácil de leer (no hay texto confuso y también hay un ejemplo). Tal vez deberían haber editado tu respuesta en su lugar
Utopik
@Utopik Me tenías en "tienes razón" ... pero sí, he editado mi respuesta para incluir un ejemplo.
VonC
¿Se usa uno git stash applypara recuperar los cambios escondidos?
Chad
49

Digamos que tienes 3 archivos

a.rb
b.rb
c.rb

y desea guardar solo b.rb y c.rb pero no a.rb

puedes hacer algo como esto

# commit the files temporarily you don't want to stash
git add a.rb
git commit -m "temp" 

# then stash the other files
git stash save "stash message"

# then undo the previous temp commit
git reset --soft HEAD^
git reset

Y ya está! HTH

venkatareddy
fuente
29

Otra forma de hacer esto:

# Save everything
git stash 

# Re-apply everything, but keep the stash
git stash apply

git checkout <"files you don't want in your stash">

# Save only the things you wanted saved
git stash

# Re-apply the original state and drop it from your stash
git stash apply stash@{1}
git stash drop stash@{1}

git checkout <"files you put in your stash">

Se me ocurrió esto después de que (una vez más) llegué a esta página y no me gustaron las dos primeras respuestas (la primera respuesta simplemente no responde la pregunta y no me gustó mucho trabajar con el -pmodo interactivo).

La idea es la misma que lo que @VonC sugirió usar archivos fuera del repositorio: guarda los cambios que desea en algún lugar, elimina los cambios que no desea en su escondite y luego vuelve a aplicar los cambios que quitó del camino. Sin embargo, utilicé el escondite de git como "en alguna parte" (y como resultado, hay un paso adicional al final: eliminar los depósitos que colocaste en el escondite, porque también los quitaste del camino).

Jaspe
fuente
1
Prefiero este enfoque más. Proporciona un flujo de trabajo fácil en tortoisegit utilizando solo comandos de ocultación y reversión.
Mark Ch
No es aconsejable consultar las respuestas sobre SO utilizando posiciones. Las posiciones cambian a medida que cambian las calificaciones.
Bryan Ash
2
@BryanAsh Bueno, no es que importe aquí. Estoy dando una anécdota en lugar de referirme realmente a las otras respuestas. El mensaje es que no me gustaron las respuestas que le gustaban a la comunidad y no lo que realmente contienen estas respuestas. Además, la brecha de 900 votos entre la segunda y la tercera respuesta hace que sea poco probable que esto cambie en el futuro cercano, y si alguna vez cambia, siempre puedo editarlo para decir "la parte superior de las respuestas en ese momento". Realmente, no veo cómo esto es algún tipo de problema en esta situación.
Jasper
23

Actualización (14/02/2015) - Reescribí el script un poco, para manejar mejor el caso de conflictos, que ahora deberían presentarse como conflictos no fusionados en lugar de archivos .rej.


A menudo me resulta más intuitivo hacer lo contrario del enfoque de @bukzor. Es decir, organizar algunos cambios y luego esconder solo esos cambios organizados.

Desafortunadamente, git no ofrece una reserva de git: solo index o similar, así que preparé un script para hacer esto.

#!/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 succeed
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 guardar el script anterior como en git-stash-indexalgún lugar de su ruta y luego 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 entrada que solo contiene los cambios que había organizado, y su árbol de trabajo aún contiene los cambios no organizados.

En algunos casos, los cambios del árbol de trabajo pueden depender de los cambios del índice, por lo que cuando oculta los cambios del índice, los cambios del árbol de trabajo tienen un conflicto. En este caso, obtendrá los conflictos no fusionados habituales que puede resolver con git merge / git mergetool / etc.

JesusFreke
fuente
Recomiende en pushdlugar de cdy popdal final del script, de modo que si el script tiene éxito, el usuario termina en el mismo directorio que antes de ejecutarlo.
Nate
1
@Nate: que yo sepa, solo debería cambiar el directorio del usuario si obtuvo el script. Si ejecuta el script normalmente (~ / bin / git-stash-index), o mediante git (git stash-index), se ejecuta en una sesión de terminal separada, y cualquier cambio de directorio de trabajo en esa sesión no afecta el directorio de trabajo en la sesión de terminal del usuario. ¿Conoces un caso de uso común cuando esto no es cierto? (aparte de obtener el guión, que no consideraría "común")
JesusFreke
20

Si no desea especificar un mensaje con sus cambios escondidos, pase el nombre del archivo después de un doble guión.

$ git stash -- filename.ext

Si se trata de un archivo nuevo / sin seguimiento, primero deberá organizarlo.

Este método funciona en git versiones 2.13+

sealocal
fuente
Esa respuesta es detallada, esto es conciso. Si ayuda a alguien, lo dejaré. Nadie en esta página menciona esta sintaxis y el resultado; en cambio, mencionan `git stash push`.
sealocal
Esta es la respuesta que estaba buscando. ¡Gracias! +1
nicodp
19

Dado que crear ramas en Git es trivial, puede crear una rama temporal y verificar los archivos individuales en ella.

shangxiao
fuente
2
No puede crear una rama con ediciones sin etapas. Puede mover fácilmente todas las ediciones a una nueva rama (stash / stash pop) pero luego vuelve al punto de partida: ¿cómo prueba su rama con solo algunas de esas ediciones, sin perder las otras?
bukzor
77
No puede cambiar de sucursal si tiene cambios locales. Sin embargo, puede crear una nueva rama y agregar / confirmar selectivamente archivos, y luego crear otra rama y hacer lo mismo de forma recursiva ... luego retirar la rama original y fusionarla selectivamente. Lo acabo de hacer. En realidad, parece la forma natural de hacer las cosas, ya que esencialmente estás creando ramas de características.
desde
3
@iain puede cambiar de sucursal si tiene cambios locales, siempre que no requieran una fusión. Ver ejemplo Gist . Esto es cierto a partir de Git v2.7.0 al menos.
Colin D Bennett
18

Simplemente puedes hacer esto:

git stash push "filename"

o con un mensaje opcional

git stash push -m "Some message" "filename"
vinodsaluja
fuente
1
Esto no agrega nada nuevo. Git stash push ya se menciona en varias respuestas
JesusFreke,
12

Guarde el siguiente código en un archivo, por ejemplo, llamado stash. El uso es stash <filename_regex>. El argumento es la expresión regular para la ruta completa del archivo. Por ejemplo, para guardar a / b / c.txt, stash a/b/c.txto stash .*/c.txt, etc.

$ chmod +x stash
$ stash .*.xml
$ stash xyz.xml

Código para copiar en el archivo:

#! /usr/bin/expect --
log_user 0
set filename_regexp [lindex $argv 0]

spawn git stash -p

for {} 1 {} {
  expect {
    -re "diff --git a/($filename_regexp) " {
      set filename $expect_out(1,string)
    }
    "diff --git a/" {
      set filename ""
    }
    "Stash this hunk " {
      if {$filename == ""} {
        send "n\n"
      } else {
        send "a\n"
        send_user "$filename\n"
      }
    }
    "Stash deletion " {
      send "n\n"
    }
    eof {
      exit
    }
  }
}
albaricoque
fuente
2
Gran método Hubiera elegido esto como la respuesta. Consejo para futuros lectores: tienes que coincidir en el camino completo. ej. stash subdir / foo.c
er0
12

En caso de que realmente quiera decir cambios de descarte cada vez que usa git stash(y realmente no usa git stash para guardarlo temporalmente), en ese caso puede usar

git checkout -- <file>

[ NOTA ]

Esa git stashes solo una alternativa más rápida y simple para ramificarse y hacer cosas.

Devesh
fuente
8

El problema con la solución `` intermedia '' de VonC de copiar archivos al exterior del repositorio de Git es que pierde la información de ruta, lo que hace que copiar un montón de archivos más tarde sea una molestia.

A resulta más fácil usar tar (herramientas similares probablemente lo harán) en lugar de copiar:

  • tar cvf /tmp/stash.tar ruta / a / some / file ruta / a / some / other / file (... etc.)
  • ruta de pago git / a / some / file ruta / a / some / other / file
  • escondite
  • tar xvf /tmp/stash.tar
  • etc. (ver la sugerencia 'intermedia' de VonC)
eleotlecram
fuente
checkout -fno es necesario, checkout(sin -f) es suficiente, he actualizado la respuesta.
eleotlecram
8

A veces he realizado un cambio no relacionado en mi rama antes de comprometerlo, y quiero moverlo a otra rama y confirmarlo por separado (como maestro). Hago esto:

git stash
git checkout master
git stash pop
git add <files that you want to commit>
git commit -m 'Minor feature'
git stash
git checkout topic1
git stash pop
...<resume work>...

Tenga en cuenta que lo primero stashy stash poppuede eliminarse, puede llevar todos sus cambios a la mastersucursal cuando realice el pago, pero solo si no hay conflictos. Además, si está creando una nueva rama para los cambios parciales, necesitará el alijo.

Puede simplificarlo suponiendo que no haya conflictos ni una nueva rama:

git checkout master
git add <files that you want to commit>
git commit -m 'Minor feature'
git checkout topic1
...<resume work>...

El escondite ni siquiera es necesario ...

void.pointer
fuente
8

Esto se puede hacer fácilmente en 3 pasos usando SourceTree.

  1. Compromete temporalmente todo lo que no quieres guardar.
  2. Agregue todo lo demás, luego guárdelo.
  3. Pop su confirmación temporal ejecutando git reset, apuntando a la confirmación antes de su temporal.

Todo esto se puede hacer en cuestión de segundos en SourceTree, donde puede hacer clic en los archivos (o incluso en las líneas individuales) que desea agregar. Una vez agregado, simplemente compromételos a una confirmación temporal. Luego, haga clic en la casilla de verificación para agregar todos los cambios, luego haga clic en esconder para guardar todo. Con los cambios ocultos fuera del camino, eche un vistazo a su lista de confirmación y observe el hash para la confirmación antes de su confirmación temporal, luego ejecute 'git reset hash_b4_temp_commit', que es básicamente como "hacer estallar" la confirmación restableciendo su rama al comprometerse justo antes de eso. Ahora, te quedan solo las cosas que no querías guardar.

Triynko
fuente
8

Me gustaría utilizar git stash save --patch. No creo que la interactividad sea molesta porque hay opciones durante la misma para aplicar la operación deseada a archivos completos.

Raffi Khatchadourian
fuente
3
Sorprendido de que haya tan poco respaldo para esta respuesta, es la mejor solución sin necesidad de un ensayo.
robstarbuck
Definitivamente la buena respuesta, le git stash -ppermite guardar un archivo completo rápidamente y salir después.
Richard Dally
7

Cada respuesta aquí es tan complicada ...

¿Qué pasa con esto para "esconder":

git diff /dir/to/file/file_to_stash > /tmp/stash.patch
git checkout -- /dir/to/file/file_to_stash

Esto para hacer estallar el cambio de archivo:

git apply /tmp/stash.patch

Exactamente el mismo comportamiento que guardar un archivo y volverlo a colocar.

Christophe Fondacci
fuente
Lo intenté pero no pasa nada. Cuando no git applytengo ningún error, pero los cambios tampoco se devuelven
ClementWalter
El archivo de parche que generó en / tmp probablemente se eliminó. Es posible que haya reiniciado entre el diff y el apply. Pruebe con otra ubicación más permanente. Funciona Compruebe también el contenido del archivo de parche.
Christophe Fondacci
4

He revisado las respuestas y comentarios para esto y una serie de hilos similares. Tenga en cuenta que ninguno de los siguientes comandos son correctos con el fin de poder ocultar cualquier archivo específico rastreado / no rastreado :

  • git stash -p (--patch): seleccione trozos manualmente, excluyendo archivos no rastreados
  • git stash -k (--keep-index): esconde todos los archivos rastreados / no rastreados y mantenlos en el directorio de trabajo
  • git stash -u (--include-untracked): esconde todos los archivos rastreados / no rastreados
  • git stash -p (--patch) -u (--include-untracked): comando inválido

Actualmente, el método más razonable para poder almacenar cualquier archivo específico rastreado / no rastreado es:

  • Confirma temporalmente los archivos que no quieres guardar
  • Agregar y guardar
  • Pop el commit temporal

Escribí un script simple para este procedimiento en una respuesta a otra pregunta , y aquí hay pasos para realizar el procedimiento en SourceTree .

ZimbiX
fuente
4

Solución

Cambios locales:

  • archivo_A (modificado) no organizado
  • archivo_B (modificado) no organizado
  • file_C (modificado) no organizado

Para crear un alijo "my_stash" con solo los cambios en file_C :

1. git add file_C
2. git stash save --keep-index temp_stash
3. git stash save my_stash
4. git stash pop stash@#{1}

Hecho.


Explicación

  1. agregar file_C al área de preparación
  2. cree un alijo temporal llamado "temp_stash" y mantenga los cambios en el archivo_C
  3. cree el alijo deseado ("my_stash") con solo los cambios en file_C
  4. aplique los cambios en "temp_stash" (archivo_A y archivo_B) en su código local y elimine el alijo

Puede usar el estado de git entre los pasos para ver qué está sucediendo.

Alex 75
fuente
3

Cuando intenta cambiar entre dos ramas, se produce esta situación.

Intente agregar los archivos usando " git add filepath".

Más tarde ejecuta esta línea

git stash --keep-index

Sireesh Yarlagadda
fuente
3

Para guardar un solo archivo, use git stash --patch [file].

Esto va a indicador: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Simplemente escriba a(guarde este trozo y todos los trozos posteriores en el archivo) y estará bien.

Vinicius Brasil
fuente
Desaparecido pushcomo engit stash push --patch [file]
Filipe Esperandio
@FilipeEsperandio pushsolo funciona en versiones más recientes de Git, solía ser save. En cualquier caso pusho saveestán implícitos al llamar stash: "Llamar a git stash sin ningún argumento es equivalente a git stash push", docs
patrick
2

Situación similar. Se comprometió y se dio cuenta de que no está bien.

git commit -a -m "message"
git log -p

Basado en las respuestas esto me ayudó.

# revert to previous state, keeping the files changed
git reset HEAD~
#make sure it's ok
git diff
git status
#revert the file we don't want to be within the commit
git checkout specs/nagios/nagios.spec
#make sure it's ok
git status
git diff
#now go ahead with commit
git commit -a -m "same|new message"
#eventually push tu remote
git push
David Hrbáč
fuente
2

En esta situación, yo git add -p(interactivo), git commit -m blahy luego guardo lo que queda si es necesario.

J0hnG4lt
fuente
2

No sé cómo hacerlo en la línea de comandos, solo usando SourceTree. Digamos que ha cambiado el archivo A y tiene dos cambios en el archivo B. Si desea guardar solo el segundo trozo en el archivo B y dejar todo lo demás intacto, haga lo siguiente:

  1. Escenificar todo
  2. Realice cambios en su copia de trabajo que deshaga todos los cambios en el archivo A. (por ejemplo, inicie la herramienta de diferencias externa y haga que los archivos coincidan).
  3. Haga que el archivo B parezca que solo se le aplica un segundo cambio. (por ejemplo, inicie la herramienta de diferencia externa y deshaga el primer cambio).
  4. Crea un alijo usando "Mantener cambios por etapas".
  5. Desmonta todo
  6. ¡Hecho!
Juozas Kontvainis
fuente
2
git add .                           //stage all the files
git reset <pathToFileWillBeStashed> //unstage file which will be stashed
git stash                           //stash the file(s)
git reset .                         // unstage all staged files
git stash pop                       // unstash file(s)
celikz
fuente
1
Bueno, no deberías hacer eso. La respuesta debe proporcionar una solución a la pregunta. Podrías hacer tu propia pregunta.
L_J
Esta solución es una de las respuestas más fáciles para esta pregunta. lea la pregunta, compare todas las respuestas y la mía, luego, si tiene alguna duda de que esta respuesta no es una solución aplicable ni información insuficiente sobre la pregunta, entonces podemos hablar nuevamente.
celikz
Esto no funcionará, porque el tercer comando, "git stash" no honrará los archivos almacenados. Tanto los archivos almacenados como los no almacenados irán al alijo. Las preguntas específicamente preguntan cómo esconder solo un archivo
CyberProdigy
0

Una forma complicada sería primero comprometer todo:

git add -u
git commit // creates commit with sha-1 A

Restablezca la confirmación original pero revise the_one_file desde la nueva confirmación:

git reset --hard HEAD^
git checkout A path/to/the_one_file

Ahora puedes esconder el_un_archivo:

git stash

Limpie guardando el contenido confirmado en su sistema de archivos mientras restablece la confirmación original:

git reset --hard A
git reset --soft HEAD^

Sí, algo incómodo ...

Martin G
fuente
0

No encontré ninguna respuesta para ser lo que necesitaba y eso es tan fácil como:

git add -A
git reset HEAD fileThatYouWantToStash
git commit -m "committing all but one file"
git stash

Esto oculta exactamente un archivo.

SCBuergel.eth
fuente
0

Respuesta rápida


Para revertir un archivo modificado específico en git, puede hacer la siguiente línea:

git checkout <branch-name> -- <file-path>

Aquí hay un ejemplo real:

git checkout master -- battery_monitoring/msg_passing.py

Benyamin Jafari
fuente
0

Si desea guardar algunos archivos modificados, simplemente

Agregue los archivos que no desea guardar, en el escenario , luego ejecutegit stash save --keep-index

Guardará todos los archivos modificados sin clasificar

Amin Shojaei
fuente