Domanda Stash un solo file di più file modificati con Git?


Come posso nascondere solo uno dei vari file modificati sul mio ramo?


2435
2018-06-14 20:52


origine


risposte:


avvertimento

Come notato nei commenti, questo mette tutto nella scorta, sia messa in scena che non. --keep-index lascia solo l'indice dopo che è stato eseguito lo stash. Ciò può causare conflitti di unione quando si apre la scorta.


Questo immagazzinerà tutto ciò che non hai precedentemente aggiunto. Appena git add le cose che vuoi mantenere, quindi eseguilo.

git stash --keep-index

Ad esempio, se si desidera dividere un vecchio commit in più di un changeset, è possibile utilizzare questa procedura:

  1. git rebase -i <last good commit>
  2. Segna alcune modifiche come edit.
  3. git reset HEAD^
  4. git add <files you want to keep in this change>
  5. git stash --keep-index
  6. Risolvi le cose se necessario. Non dimenticare di git add eventuali modifiche.
  7. git commit
  8. git stash pop
  9. Ripeti, dal n. 5, se necessario.
  10. git rebase --continue

1216
2017-11-30 21:28



Puoi anche usare git stash save -p "my commit message". In questo modo puoi selezionare quali hunk devono essere aggiunti alla stash, anche interi file possono essere selezionati.

Ti verrà richiesto un paio di azioni per ogni hunk:

   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

2610
2017-07-31 11:59



Dato che git è fondamentalmente sulla gestione di tutti i repository soddisfare e indice (e non uno o più file), git stash offerte, non a caso, con la directory di tutti i lavori.

In realtà, dal momento che Git 2.13 (2 ° trim. 2017), è possibile memorizzare singoli file, con:

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

Vedi "Stash cambia in file specifici" per più.


La risposta originale (di seguito, giugno 2010) riguardava la selezione manuale di ciò che si desidera memorizzare.

Casebash Commenti:

Questo il stash --patch soluzione originale) è bello, ma spesso ho modificato molti file, quindi l'uso della patch è fastidioso

bukzor'S risposta (upvoted, novembre 2011) suggerisce una soluzione più pratica, basata su
git add + git stash --keep-index.
Vai a vedere e invertire la sua risposta, che dovrebbe essere quella ufficiale (invece della mia).

A proposito di questa opzione, chhh indica un flusso di lavoro alternativo nei commenti:

dovresti "git reset --soft"dopo una tale scorta per ottenere la tua chiara messa in scena:
  Per arrivare allo stato originale - che è una chiara area di staging e con solo alcune modifiche non programmate, è possibile ripristinare l'indice per ottenere (senza commettere nulla come te - ha fatto bukzor).


(Risposta originale giugno 2010: scorta manuale)

Ancora, git stash save --patch potrebbe permetterti di ottenere lo stashing parziale che stai cercando:

Con --patch, è possibile selezionare in modo interattivo gli hunk nella differenza tra HEAD e l'albero di lavoro da nascondere.
  La voce stash è costruita in modo tale che lo stato dell'indice sia lo stesso dello stato dell'indice del repository e il suo worktree contenga solo le modifiche selezionate in modo interattivo. Le modifiche selezionate vengono quindi ripristinate dal tuo albero di lavoro.

Comunque questo salverà l'indice completo (che potrebbe non essere quello che vuoi dato che potrebbe includere altri file già indicizzati), e un albero di lavoro parziale (che potrebbe sembrare quello che vuoi mettere da parte).

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

potrebbe essere una misura migliore.


Se --patchnon funziona, un processo manuale potrebbe:

Per uno o più file, una soluzione intermedia sarebbe:

  • copialo fuori dal repository Git
    (In realtà, eleotlecram propone un interessante alternativa)
  • git stash
  • copiarli indietro
  • git stash # questa volta, solo i file che desideri sono nascosti
  • git stash pop stash@{1} # riapplicare tutte le modifiche ai file
  • git checkout -- afile # reimposta il file sul contenuto HEAD, prima di eventuali modifiche locali

Alla fine di questo processo piuttosto ingombrante, avrai solo uno o più file nascosti.


236
2018-06-14 21:23



quando git stash -p (o git add -p con stash --keep-index) sarebbe troppo macchinoso, l'ho trovato più facile da usare diff, checkout e apply:

Per "memorizzare" solo un file / dir particolare:

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

Quindi dopo

git apply stashed.diff

76
2018-02-12 13:44



Diciamo che hai 3 file

a.rb
b.rb
c.rb

e vuoi mettere in archivio solo b.rb e c.rb ma non a.rb

puoi fare qualcosa di simile

# 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

E hai finito! HTH.


43
2017-10-31 07:10



Uso git stash push, come questo:

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

Per esempio:

git stash push -- my/file.sh

Disponibile da Git 2.13, rilasciato nella primavera 2017.


33
2017-08-15 13:10



Un altro modo per farlo:

# 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">

L'ho inventato dopo che io (ancora una volta) sono arrivato a questa pagina e non mi sono piaciute le prime due risposte (la prima risposta non risponde alla domanda e non mi piaceva lavorare con il -p modalità interattiva).

L'idea è la stessa di quanto suggerito da @VonC usando i file al di fuori del repository, si salvano le modifiche che si desidera da qualche parte, si rimuovono le modifiche che non si desiderano nella memoria e poi si applicano nuovamente le modifiche che si sono spostate. Tuttavia, ho usato il git stash come "da qualche parte" (e come risultato, c'è un passo in più alla fine: rimuovere i cahnge che hai messo nella scorta, perché li hai spostati anche fuori strada).


25
2018-02-05 10:16



Aggiornamento (14/02/2015) - Ho riscritto un po 'lo script, per gestire meglio il caso dei conflitti, che dovrebbero ora essere presentati come conflitti non uniti piuttosto che come file .rej.


Trovo spesso più intuitivo fare l'inverso dell'approccio di @ bukzor. Cioè, per mettere in scena alcune modifiche e quindi memorizzare solo quelle modifiche graduali.

Sfortunatamente, git non offre un git stash --only-index o simile, quindi ho montato uno script per farlo.

#!/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

Puoi salvare lo script di cui sopra come git-stash-index da qualche parte sul tuo percorso e può quindi invocarlo come git stash-index

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

Ora lo stash contiene una nuova voce che contiene solo le modifiche che hai messo in scena e la tua struttura di lavoro contiene ancora modifiche non modificate.

In alcuni casi, le modifiche alla struttura di lavoro possono dipendere dalle modifiche dell'indice, pertanto quando si eseguono le modifiche all'indice, le modifiche alla struttura di lavoro presentano un conflitto. In questo caso, otterrai i soliti conflitti non raggruppati che puoi risolvere con git merge / git mergetool / etc.


22
2018-06-16 21:00



Poiché la creazione di rami in Git è banale, è sufficiente creare un ramo temporaneo e controllare i singoli file in esso contenuti.


16
2018-06-28 12:07