Stash solo un file su più file che sono stati modificati con Git?


3071

Come posso conservare solo uno dei file multipli modificati sul mio ramo?


109
Non credo che la risposta accettata da @ bukzor sia una risposta corretta alla domanda così come è stata posta. git stash --keep-indexmantiene l'indice, ma nasconde tutto , sia nell'indice che all'esterno.
Raman,

@Antonio Mi sembra che la tua generosità dovrebbe in realtà essere una domanda separata, dal momento che la domanda originale non ha nulla a che fare con TortoiseGit in particolare.
JesusFreke,

1
@JesusFreke Sì, dato il risultato che avrei potuto risparmiare 50 rep :) È solo che questa è la domanda a cui tieni reindirizzato se provi a cercare "tartaruga stash parziale". Tortoisegit non sembra essere un argomento popolare qui stackoverflow.com/questions/tagged/tortoisegit
Antonio

7
>>>>>>>>> git diff -- *filename* > ~/patchquindi git checkout -- *filename*e in seguito è possibile riapplicare la patch congit apply ~/patch
neaumusic il

36
La maggior parte delle risposte esistenti di seguito sono obsolete. Da Git 2.13 (Q2 2017) è supportato da git stash push [--] [<pathspec>...].
Ohad Schneider,

Risposte:


1372

Disclaimer : la seguente risposta è per git prima di git 2.13. Per git 2.13 e oltre, controlla un'altra risposta più in basso .


avvertimento

Come notato nei commenti, questo mette tutto nella scorta, sia in scena che in scena. --Keep-index lascia solo l'indice da solo al termine dello stash. Ciò può causare conflitti di unione quando successivamente si pop la scorta.


Questo riporterà tutto ciò che non hai aggiunto in precedenza. Solo git addle cose che vuoi conservare, 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. Correggi le cose se necessario. Non dimenticare di git addapportare modifiche.
  7. git commit
  8. git stash pop
  9. Ripetere, dal n. 5, se necessario.
  10. git rebase --continue

47
Trovo che questo approccio sia molto più semplice: stackoverflow.com/a/5506483/457268
k0pernikus

561
Non sono sicuro del motivo per cui questo è stato valutato. Tutti devono avere aspettative diverse rispetto a me. Il post originale chiede "come posso riporre solo una parte delle modifiche non confermate?" Quando uso git stash save -k, sì l'indice (verde in git stat) viene conservato, ma l' intero changeset (sia verde che rosso) va nella scorta. Ciò viola la richiesta del PO, "nasconde solo alcune modifiche". Voglio nascondere solo un po 'di rosso (per un utilizzo futuro).
Pistos,

70
Se sei più interessato alla risposta alla domanda posta da @Pistos (com'ero), guarda qui: stackoverflow.com/questions/5506339/…
Raman

27
@Raman: eccellente! git stash -pè esattamente quello che stavo cercando. Mi chiedo se questa opzione è stata aggiunta solo di recente.
Pistos

14
ATTENZIONE: git stash --keep-indexè rotto. Se si apportano ulteriori modifiche, provare in git stash popseguito a riscontrare conflitti di unione perché lo stash include i file modificati conservati, non solo quelli che non sono stati conservati. Ad esempio: cambio i file A e B, quindi nascondo B, perché voglio testare le modifiche in A; Trovo un problema con A che poi risolvo; Commetto A; Ora non riesco a rimuovere perché una vecchia versione di A è nella scorta senza motivo per causare un conflitto di unione. In pratica A e B potrebbero essere molti file, forse anche immagini binarie o qualcosa del genere, quindi in pratica devo rinunciare e perdere B.
rjmunro,

3015

Puoi anche usare git stash save -p "my commit message". In questo modo è possibile selezionare quali hunk devono essere aggiunti allo stash, è possibile selezionare anche interi file.

Ti verranno richieste alcune azioni per ogni pezzo:

   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

5
Non era. È stato preso in prestito da Darcs, circa 7 anni dopo il fatto.
nomen

6
Sono un drogato di TortoiseGit. Tuttavia TortoiseGit non supporta stash -p. Premetto questa risposta perché rimane la più interattiva / intuitiva.
Antonio,

27
potresti voler aggiungere git stash save -p my stash message:; poiché l'ordine dell'argumenst non è molto intuitivo ...
Chris Maes,

15
Tra questo e git log -p, penso che la -pbandiera debba significare "fai la cosa bella che voglio ma non so come esprimere".
Kyle Strand,

2
perché mai questa grande risposta è al 12 ° posto ?? dopo tutte quelle risposte 0, +1, +2 ??????
DenisFLASH,

550

Dato che git si basa fondamentalmente sulla gestione di tutti i repository di contenuti e indici (e non uno o più file) git stash, non sorprende,con la directory all working.

In realtà, a partire da Git 2.13 (2 ° trimestre 2017), puoi archiviare singoli file con git stash push:

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

Quando pathspecviene assegnato a ' git stash push', la nuova scorta registra gli stati modificati solo per i file che corrispondono al pathspec. Per ulteriori informazioni, vedere " Cambiamenti di scorta in file specifici ".

Esempio semplificato:

 git stash push path/to/file

Il test case per questa funzione mostra alcune altre opzioni:

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 risposta originale (sotto, giugno 2010) riguardava la selezione manuale di ciò che si desidera conservare.

Commenti di casebash :

Questa (la stash --patchsoluzione originale) è carina, ma spesso ho modificato molti file, quindi usare la patch è fastidioso

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

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

dovresti " git reset --soft" dopo una tale scorta per riavere la tua chiara messa in scena:
per raggiungere lo stato originale - che è una chiara area di messa in scena e con solo alcune modifiche non messe in scena selezionate, potresti ripristinare delicatamente l'indice per ottenere (senza commettere qualcosa come te - bukzor - ha fatto).


(Risposta originale giugno 2010: scorta manuale)

Tuttavia, git stash save --patchpotrebbe consentirti di ottenere lo stash parziale che stai cercando:

Con --patch, puoi selezionare interattivamente gli hunk nel diff tra HEAD e l'albero di lavoro da nascondere.
La voce stash è costruita in modo tale che il suo stato di indice sia uguale allo stato di indice del repository e la sua colonna di lavoro contiene solo le modifiche selezionate in modo interattivo. Le modifiche selezionate vengono quindi ripristinate dal tuo worktree.

Tuttavia, ciò salverà l'indice completo (che potrebbe non essere quello che desideri poiché potrebbe includere altri file già indicizzati) e un albero di lavoro parziale (che potrebbe assomigliare a quello che desideri conservare).

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 quella di:

  • copiarli al di fuori del repository Git
    (in realtà, eleotlecram propone un'alternativa interessante )
  • git stash
  • copiarli indietro
  • git stash # questa volta, vengono archiviati solo i file desiderati
  • git stash pop stash@{1} # riapplica tutte le modifiche ai tuoi file
  • git checkout -- afile # ripristina il file sul contenuto HEAD, prima di qualsiasi modifica locale

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


3
Questo è carino, ma spesso ho modificato molti file, quindi l'uso della patch è fastidioso
Casebash

6
@VonC: è buona norma avere una sola risposta per risposta. Inoltre, incollare le risposte degli altri nelle tue è cattive maniere.
Bukzor,

3
@bukzor: mi dispiace se la mia risposta modificata non è corretta. La mia unica intenzione era di dare maggiore visibilità alla tua risposta. Ho modificato di nuovo il mio post, al fine di rendere più chiara tale intenzione.
VonC,

1
@Kal: vero, stackoverflow.com/a/13941132/6309 suggerisce una git reset(misto)
VonC

3
git is fundamentally about managing a all repository content and index and not one or several files- questa implementazione mette in ombra il problema da risolvere; è una spiegazione, ma non una giustificazione. Qualsiasi sistema di controllo del codice sorgente riguarda la "gestione di più file". Guarda quali commenti vengono più votati.
Victor Sergienko,

90

Quando git stash -p(o git add -pcon stash --keep-index) sarebbe troppo ingombrante, ho trovato più facile da usare diff, checkoute apply:

Per "riporre" solo un determinato file / dir:

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

Poi dopo

git apply stashed.diff

1
Interessante alternativa a quella git add -pcitata nella mia risposta sopra. +1.
VonC,

11
Si noti che se si dispone di file binari (come PNG) non verranno emessi nel file diff. Quindi questa non è una soluzione al 100%.
void.pointer

1
@RobertDailey: Questo è un punto interessante per me, come git diff > file.diffe git applysono i miei soliti strumenti Stash parziali. Potrei dover considerare di passare a git stash -pchangeets più grandi.
thekingoftruth,

1
@thekingoftruth Ecco l'alias che uso per creare file di patch, e fa i binari di supporto: patch = log --pretty=email --patch-with-stat --reverse --full-index --binary. Nota, tuttavia, ciò richiede che le modifiche apportate alla patch vengano impegnate.
void.pointer

2
Questo non funzionava in modo pulito per me se il file da riporre era qualcosa del genere ../../foo/bar.txt. La patch genera OK, ma devo passare alla radice del repository per applicare la patch. Quindi, se hai problemi con questo, assicurati di farlo dalla directory principale del repository.
Michael Anderson,

86

Usa in git stash pushquesto modo:

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

Per esempio:

git stash push -- my/file.sh

Questo è disponibile da Git 2.13, rilasciato nella primavera del 2017.


1
Ma cito git stash pushgià nella mia risposta sopra lo scorso marzo, 5 mesi fa. E ho dettagliato questo nuovo comando Git 2.13 qui: stackoverflow.com/a/42963606/6309 .
VonC,

Sono contento che Git stia avanzando così rapidamente, per molto tempo questo non è stato possibile e quindi 2.13 è stato rilasciato e improvvisamente c'è una soluzione semplice disponibile!
sandstrom,

1
@VonC hai ragione, citi anche la risposta corretta, tuttavia, tra le due risposte, questa è più facile da leggere (nessun testo confuso e c'è anche un esempio). Forse avrebbero dovuto modificare la tua risposta
Utopik,

@Utopik Mi avevi in ​​"hai ragione" ... ma sì, ho modificato la mia risposta per includere un esempio.
VonC,

Si usa quindi git stash applyper recuperare le modifiche nascoste?
Chad,

49

Supponiamo che tu abbia 3 file

a.rb
b.rb
c.rb

e vuoi conservare solo b.rb e c.rb ma non a.rb

puoi fare qualcosa del genere

# 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 il gioco è fatto! HTH.


29

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

Ho pensato a questo dopo che (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 è proprio piaciuto lavorare con -p modalità interattiva).

L'idea è la stessa di quella suggerita da @VonC utilizzando i file all'esterno del repository, si salvano le modifiche desiderate da qualche parte, si rimuovono le modifiche che non si desidera nella propria scorta, quindi si applicano nuovamente le modifiche che si sono spostate di mezzo. Tuttavia, ho usato git stash come "da qualche parte" (e, di conseguenza, alla fine c'è un ulteriore passo: rimuovere i calhnges che hai inserito nello stash, perché li hai spostati anche di mezzo).


1
preferisco questo approccio di più. Fornisce un flusso di lavoro semplice in tortoisegit utilizzando solo i comandi stash e ripristina.
Mark Ch

Non è consigliabile fare riferimento alle risposte su SO utilizzando le posizioni. Le posizioni cambiano quando cambiano le valutazioni.
Bryan Ash,

2
@BryanAsh Beh, non è come importa qui. Sto dando un aneddoto piuttosto che riferirmi realmente alle altre risposte. Il messaggio è che non mi sono piaciute le risposte che la community ha apprezzato e non ciò che queste risposte effettivamente contengono. Inoltre, il gap di 900 voti tra la seconda e la terza risposta rende improbabile che questo cambi nel prossimo futuro, e se dovesse mai cambiare, posso sempre modificarlo per dire "il massimo delle risposte in quel momento". Davvero, non vedo come questo sia un problema in questa situazione.
Jasper,

23

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


Trovo spesso più intuitivo fare l'inverso dell'approccio di @ bukzor. Cioè, per mettere in scena alcuni cambiamenti, e quindi nascondere solo quei cambiamenti graduali.

Sfortunatamente, git non offre uno stash git - solo-index o simili, quindi ho creato 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 sopra come git-stash-indexda qualche parte sul tuo percorso e 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 il tuo albero di lavoro contiene ancora eventuali modifiche non messe in scena.

In alcuni casi, le modifiche dell'albero di lavoro possono dipendere dalle modifiche dell'indice, quindi quando si ripongono le modifiche dell'indice, le modifiche dell'albero di lavoro hanno un conflitto. In questo caso, otterrai i soliti conflitti non uniti che puoi risolvere con git merge / git mergetool / etc.


Consiglia pushdinvece di cde popdalla fine dello script, quindi se lo script ha esito positivo, l'utente finisce nella stessa directory di prima di eseguirlo.
Nate,

1
@Nate: per quanto ne so, dovrebbe cambiare la directory per l'utente solo se ha ottenuto lo script. Se si esegue normalmente lo script (~ / bin / git-stash-index) o tramite git (git stash-index), viene eseguito in una sessione terminale separata e qualsiasi modifica della directory di lavoro in quella sessione non influisce sul directory di lavoro nella sessione terminale dell'utente. Sei a conoscenza di un caso d'uso comune quando questo non è vero? (oltre a reperire la sceneggiatura, che non considererei "comune")
JesusFreke,

20

Se non si desidera specificare un messaggio con le modifiche nascoste, passare il nome file dopo un doppio trattino.

$ git stash -- filename.ext

Se si tratta di un file non tracciato / nuovo, dovrai prima metterlo in scena.

Questo metodo funziona nelle versioni git 2.13+


Questa risposta è dettagliata, questa è concisa. Se aiuta qualcuno, lo lascerò. Nessuno in questa pagina menziona questa sintassi e questo risultato - menzionano invece "git stash push".
Sealocal

Questa è la risposta che stavo cercando. Grazie! +1
nicodp

19

Dal momento che la creazione di rami in Git è banale, puoi semplicemente creare un ramo temporaneo e controllare i singoli file al suo interno.


2
Non è possibile creare un ramo con modifiche non messe in scena. Puoi facilmente spostare tutte le modifiche in un nuovo ramo (stash / stash pop) ma poi sei di nuovo al punto di partenza: come fai a testare il tuo ramo solo con alcune di quelle modifiche, senza perdere le altre?
Bukzor,

7
Non puoi cambiare filiale se hai delle modifiche locali. Tuttavia, puoi creare un nuovo ramo e aggiungere / eseguire il commit selettivo dei file, quindi creare un altro ramo e fare lo stesso in modo ricorsivo ... quindi controlla il ramo originale e ricollegalo selettivamente. L'ho appena fatto. In realtà sembra il modo naturale di fare le cose, in quanto stai essenzialmente creando rami di caratteristiche.
Iain

3
@iain puoi cambiare succursale se hai cambiamenti locali, purché non richiedano l'unione. Vedi esempio Gist . Questo vale almeno per Git v2.7.0.
Colin D Bennett,

18

Puoi semplicemente farlo:

git stash push "filename"

o con un messaggio opzionale

git stash push -m "Some message" "filename"

1
Questo non aggiunge nulla di nuovo. Git stash push è già menzionato in più risposte
JesusFreke,

12

Salvare il seguente codice in un file, ad esempio, denominato stash. L'uso è stash <filename_regex>. L'argomento è l'espressione regolare per il percorso completo del file. Ad esempio, per stash a / b / c.txt, stash a/b/c.txto stash .*/c.txt, ecc.

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

Codice da copiare nel file:

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

2
Ottimo metodo. Avrei scelto questo come risposta. Suggerimento per i futuri lettori: devi abbinare l'intero percorso. es. stash subdir /
foo.c

12

Nel caso in cui intendi effettivamente annullare le modifiche ogni volta che lo usi git stash(e non usi davvero git stash per riporlo temporaneamente), in quel caso puoi usare

git checkout -- <file>

[ NOTA ]

Questa git stashè solo un'alternativa più rapida e semplice alla ramificazione e al fare cose.


8

Il problema con la soluzione "intermedia" di VonC di copiare i file all'esterno del repository Git è che si perdono le informazioni sul percorso, il che rende la copia di un gruppo di file in un secondo momento una seccatura.

A trovare più facile usare tar (strumenti simili probabilmente lo faranno) invece di copiare:

  • tar cvf /tmp/stash.tar path / to / some / file path / to / some / other / file (... ecc.)
  • git checkout path / to / some / file path / to / some / other / file
  • git stash
  • tar xvf /tmp/stash.tar
  • ecc. (vedi il suggerimento "intermedio" di VonC)

checkout -fnon è necessario, checkout(senza -f) è abbastanza, ho aggiornato la risposta.
eleotlecram,

8

A volte ho apportato una modifica non correlata al mio ramo prima di averlo commesso e voglio spostarlo in un altro ramo e commetterlo separatamente (come il master). Lo faccio:

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>...

Nota il primo stashe stash poppuò essere eliminato, puoi trasferire tutte le modifiche al filemaster ramo al momento del checkout, ma solo se non ci sono conflitti. Inoltre, se stai creando un nuovo ramo per le modifiche parziali, avrai bisogno dello stash.

Puoi semplificarlo supponendo che non vi siano conflitti né nuove filiali:

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

Stash non è nemmeno necessario ...


8

Questo può essere fatto facilmente in 3 passaggi usando SourceTree.

  1. Impegna temporaneamente tutto ciò che non desideri venga nascosto.
  2. Git aggiungere tutto il resto, quindi riporlo.
  3. Pop il tuo commit temporaneo eseguendo git reset, indirizzando il commit prima di quello temporaneo.

Tutto ciò può essere fatto in pochi secondi in SourceTree, dove puoi semplicemente fare clic sui file (o anche sulle singole righe) che desideri aggiungere. Una volta aggiunto, esegui il commit in un commit temporaneo. Quindi, fai clic sulla casella di controllo per aggiungere tutte le modifiche, quindi fai clic su Stash per riporre tutto. Con le modifiche nascoste di mezzo, dai un'occhiata alla tua lista di commit e nota l'hash per il commit prima del tuo commit temporaneo, quindi esegui 'git reset hash_b4_temp_commit', che è fondamentalmente come "fare scoppiare" il commit ripristinando il tuo ramo sul impegnarsi subito prima. Ora, ti rimangono solo le cose che non volevi riporre.


8

Vorrei usare git stash save --patch. Non trovo che l'interattività sia fastidiosa perché ci sono opzioni durante l'applicazione per applicare l'operazione desiderata a interi file.


3
Stupito c'è così poco sostegno per questa risposta, è la soluzione migliore senza bisogno di un saggio.
robstarbuck,

Sicuramente la buona risposta, git stash -pti consente di riporre rapidamente un intero file e di uscire successivamente.
Richard Dally,

7

Ogni risposta qui è così complicata ...

Che ne dici di "stash":

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

Questo per ripristinare la modifica del file:

git apply /tmp/stash.patch

Esatto comportamento come riporre un file e ripristinarlo.


L'ho provato ma non succede nulla. Quando non git applyho alcun errore ma non sono state apportate modifiche
ClementWalter il

Il file patch generato in / tmp è stato probabilmente eliminato. Potresti aver riavviato tra il diff e il apply. Prova un'altra posizione più permanente. Funziona Controlla anche il contenuto del file patch.
Christophe Fondacci,

4

Ho esaminato le risposte e i commenti per questo e una serie di discussioni simili. Tenere presente che nessuno dei seguenti comandi è corretto allo scopo di poter riporre file specifici tracciati / non tracciati :

  • git stash -p (--patch): seleziona gli hunk manualmente, esclusi i file non tracciati
  • git stash -k (--keep-index): nasconde tutti i file monitorati / non tracciati e li mantiene nella directory di lavoro
  • git stash -u (--include-untracked): nasconde tutti i file monitorati / non tracciati
  • git stash -p (--patch) -u (--include-untracked): comando non valido

Attualmente, il metodo più ragionevole per essere in grado di archiviare file specifici tracciati / non tracciati è:

  • Effettua temporaneamente il commit dei file che non desideri conservare
  • Aggiungi e nascondi
  • Pop il commit temporaneo

Ho scritto un semplice script per questa procedura in una risposta a un'altra domanda , e qui ci sono passaggi per eseguire la procedura in SourceTree .


4

Soluzione

Modifiche locali:

  • file_A (modificato) non in scena
  • file_B (modificato) non in scena
  • file_C (modificato) non in scena

Per creare uno stash "my_stash" con solo le modifiche su 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}

Fatto.


Spiegazione

  1. aggiungi file_C di gestione
  2. crea uno stash temporaneo chiamato "temp_stash" e mantieni le modifiche su file_C
  3. crea lo stash desiderato ("my_stash") con solo le modifiche su file_C
  4. applica le modifiche in "temp_stash" (file_A e file_B) sul codice locale ed elimina lo stash

Puoi usare lo stato git tra i passaggi per vedere cosa sta succedendo.


3

Quando si tenta di passare tra due rami, si verifica questa situazione.

Prova ad aggiungere i file usando "git add filepath ".

Successivamente esegui questa riga

git stash --keep-index


3

Per riporre un singolo file, utilizzare git stash --patch [file] .

Questo sta per messaggio: Stash this hunk [y,n,q,a,d,j,J,g,/,e,?]? ?. Basta digitare a(stash questo pezzo e tutti gli hunk successivi nel file) e stai bene.


Manca pushcome ingit stash push --patch [file]
Filipe Esperandio

@FilipeEsperandio pushfunziona solo nelle versioni più recenti di Git, in passato save. In entrambi i casi pusho savesono impliciti chiamando stash: "Chiamare git stash senza argomenti equivale a git stash push", docs
patrick,

2

Situazione simile. Commesso e realizzato che non è ok.

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

Sulla base delle risposte questo mi ha aiutato.

# 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

2

In questa situazione, io git add -p(interattivo), git commit -m blahquindi riposto ciò che resta, se necessario.


2

Non so come farlo dalla riga di comando, usando solo SourceTree. Supponiamo di aver modificato il file A e di avere due blocchi di modifica nel file B. Se si desidera riporre solo il secondo pezzo nel file B e lasciare tutto il resto intatto, procedere come segue:

  1. Metti in scena tutto
  2. Apporta le modifiche alla tua copia di lavoro che annullano tutte le modifiche nel file A. (ad esempio, avvia lo strumento diff esterno e abbina i file).
  3. Rendi il file B come se fosse applicato solo un secondo cambiamento. (ad es. avviare lo strumento diff esterno e annullare la prima modifica.)
  4. Crea uno stash usando "Mantieni modifiche graduali".
  5. Disimballare tutto
  6. Fatto!

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)

1
Bene, non dovresti farlo. La risposta dovrebbe fornire una soluzione alla domanda. Potresti semplicemente porre la tua domanda.
L_J

questa soluzione è una delle risposte più semplici per QUESTA domanda. leggi la domanda, confronta tutte le risposte e le mie quindi se hai qualche dubbio che questa risposta non sia una soluzione applicabile né informazioni insufficienti sulla domanda, allora possiamo parlare di nuovo.
Celikz,

Questo non funzionerà, perché il terzo comando, "git stash" non rispetterà i file organizzati. Sia i file in scena che quelli non in scena andranno allo stash. Le domande chiedono in particolare come
conservare

0

Un modo complicato sarebbe innanzitutto impegnare tutto:

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

Ripristina il commit originale ma controlla the_one_file dal nuovo commit:

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

Ora puoi riporre the_one_file:

git stash

Pulisci salvando il contenuto sottoposto a commit nel tuo file system mentre ripristini il commit originale:

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

Sì, un po 'imbarazzante ...


0

Non ho trovato alcuna risposta per essere ciò di cui avevo bisogno ed è facile come:

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

Questo blocca esattamente un file.


0

Risposta rapida


Per ripristinare uno specifico file modificato in git, puoi fare la seguente riga:

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

Ecco un esempio reale:

git checkout master -- battery_monitoring/msg_passing.py


0

Se vuoi conservare alcuni file modificati, semplicemente

Aggiungi i file che non desideri conservare, in Stage , quindi eseguigit stash save --keep-index

Stash tutti i file modificati non messi in scena

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.