2010-04-02 17 views
742

Contesto: Sto lavorando su master aggiungendo una funzione semplice. Dopo pochi minuti mi rendo conto che non era così semplice e avrebbe dovuto essere meglio lavorare in una nuova filiale.Git: Crea un ramo da modifiche nonstage/uncommitted sul master

Questo succede sempre a me e non ho idea di come passare a un altro ramo e prendere tutti questi cambiamenti non modificati con me lasciando pulito il ramo principale. Supponevo git stash && git stash branch new_branch sarebbe semplicemente realizzare questo, ma questo è ciò che ottengo:

~/test $ git status 
# On branch master 
nothing to commit (working directory clean) 

~/test $ echo "hello!" > testing 

~/test $ git status 
# On branch master 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

~/test $ git stash 
Saved working directory and index state WIP on master: 4402b8c testing 
HEAD is now at 4402b8c testing 

~/test $ git status 
# On branch master 
nothing to commit (working directory clean) 

~/test $ git stash branch new_branch 
Switched to a new branch 'new_branch' 
# On branch new_branch 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 
Dropped refs/[email protected]{0} (db1b9a3391a82d86c9fdd26dab095ba9b820e35b) 

~/test $ git s 
# On branch new_branch 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

~/test $ git checkout master 
M testing 
Switched to branch 'master' 

~/test $ git status 
# On branch master 
# Changed but not updated: 
# (use "git add <file>..." to update what will be committed) 
# (use "git checkout -- <file>..." to discard changes in working directory) 
# 
# modified: testing 
# 
no changes added to commit (use "git add" and/or "git commit -a") 

Sai se c'è qualche modo per realizzare questo?

+0

Anche se c'è una soluzione più semplice al problema, potrebbe si specifica in quello che il risultato che si ottiene differisce da quello che volevi? – Gauthier

+1

facendo quanto sopra o le risposte in basso, le modifiche non modificate sono sia sul master che sul nuovo ramo. Li voglio solo sul nuovo ramo, quindi posso eseguire il checkout di master e lavorare su un'altra cosa senza che queste modifiche fluttuano intorno a – knoopx

+1

, vedere la mia risposta modificata. È necessario impegnare le modifiche locali sul nuovo ramo se si desidera eseguire il checkout di un master pulito. Le modifiche locali sono solo le differenze tra l'HEAD corrente e i tuoi file su disco. Queste modifiche sui file locali non sono versionate, devi dire a git di salvarle da qualche parte se vuoi recuperarle in seguito. – Gauthier

risposta

884

Non c'è bisogno di riporre.

git checkout -b new_branch_name 

non tocca le modifiche locali. Crea semplicemente il ramo dall'attuale HEAD e imposta lì il HEAD. Quindi immagino sia quello che vuoi.

--- Modifica per spiegare il risultato di maestro cassa ---

Sei confuso perché checkout master non ignorare le modifiche?

Poiché le modifiche sono solo locali, git non vuole che le perda troppo facilmente. Dopo aver cambiato ramo, git non sovrascrive le modifiche locali. Il risultato del vostro checkout master è:

M testing 

, il che significa che i file di lavoro non sono pulite. git ha cambiato l'HEAD, ma non ha sovrascritto i tuoi file locali. Questo è il motivo per cui il tuo ultimo stato mostra ancora le tue modifiche locali, sebbene tu sia su master.

Se si desidera veramente eliminare le modifiche locali, è necessario forzare il checkout con -f.

git checkout master -f 

Poiché le tue modifiche non sono mai state commesse, le perderai.

Prova a tornare al tuo ramo, commettere le modifiche, quindi ricontrolla il master.

git checkout new_branch 
git commit -a -m"edited" 
git checkout master 
git status 

Si dovrebbe ottenere un messaggio M dopo la prima partenza, ma poi non più dopo il checkout master, e git status dovrebbe mostrare nessun file modificati.

--- Modifica per chiarire confusione su directory (file locali) ---

lavoro In risposta alla sua prima osservazione, i cambiamenti locali sono solo ... beh, locale. Git non li salva automaticamente, devi dirgli di salvarli per dopo. Se apporti delle modifiche e non le impegni esplicitamente o le memorizzi, git non le pubblicherà. Se si modifica HEAD (checkout master), le modifiche locali non vengono sovrascritte poiché non salvate.

+0

Ecco come lo faccio sempre. Funziona esattamente come ti piacerebbe. – synic

+0

amico, mi mancava questo punto importante. Penso di aver capito perché questo accade e perché git ovviamente non può ignorare i cambiamenti (senza forzare lo scarto) se non li commetto prima. Grazie: D – knoopx

+22

La cosa confusa qui è che la pagina man di git afferma che 'git checkout'" Aggiorna i file nell'albero di lavoro in modo che corrispondano alla versione nell'indice o all'albero specificato. ". Ciò presuppone che le modifiche nel tuo file system saranno * GONE * in seguito. Senza alcuna possibilità di riaverli. Anche se dici che non lo faranno, questo lascia comunque un brutto presentimento. Non mi fido di questo * affatto *. O la documentazione è davvero pessima o il comportamento predefinito di git è veramente pericoloso. Non si dovrebbe avere fiducia in qualche euristica "automagica" per rilevare che in questo caso non si vogliono perdere le modifiche. – Evi1M4chine

46

Prova:

git stash 
git checkout -b new-branch 
git stash apply 
+5

È diverso da solo fare 'git checkout -b new-branch' da solo? –

+0

Non penso che fosse quando la risposta è stata originariamente scritta, ma potrei sbagliarmi. Sfortunatamente, a causa delle mie circostanze lavorative, ho utilizzato la perforce negli ultimi anni, quindi non posso attestare la sua precisione ora. –

+2

Oppure gli ultimi due passaggi: git stash branch new-branch – rethab

12

Due cose che puoi fare:

git stash -u 
git branch sillyname [email protected]{0} 

o

git checkout -b sillyname 
git commit -am "silly message" 
git checkout - 

(git stash -u < - la -u significa che ci vuole anche cambiamenti unstaged)

(git checkout - < - il dash è una scorciatoia per il ramo precedente in cui ti trovavi)

4

Se si utilizza il client GitHub Windows (come sono) e ci si trova nella situazione di aver apportato modifiche senza commit che si desidera spostare in un nuovo ramo, è possibile semplicemente "Crate un nuovo ramo" tramite il client GitHub . Passerà al ramo appena creato e manterrà le tue modifiche.

enter image description here

+0

che memorizza le modifiche prima di creare il nuovo ramo in modo che non le mantenga (versione 223 su Mac OS) –

Problemi correlati