git: cambia ramo e ignora eventuali modifiche senza impegnarsi


318

Stavo lavorando su un ramo git ed ero pronto a eseguire il commit delle mie modifiche, quindi ho fatto un commit con un utile messaggio di commit. Ho quindi distrattamente apportato lievi modifiche al codice che non vale la pena conservare. Ora voglio cambiare ramo, ma git mi dà,

errore: sono presenti modifiche locali a "X"; impossibile cambiare ramo.

Posso cambiare filiale senza impegnarmi? In tal caso, come posso impostarlo? In caso contrario, come posso uscire da questo problema? Voglio ignorare i cambiamenti minori senza impegnarmi e cambiare i rami.


1
Credo che ciò accada solo quando i cambiamenti sono messi in scena per il commit ma non per il commit? git checkout funziona bene per cambiare i rami se non hai ancora messo in scena i file usando git add o simili.
Jeremy Wall,

1
Ciao Jeremy, cosa intendi con "messa in scena"? Costringere l'utente a eseguire il commit del file prima di modificare i rami non sembra un grande flusso di lavoro. Ad esempio, se mi trovo nel repository principale e voglio verificare rapidamente qualcosa in un ramo. Devo prima assegnare il codice al master, anche se il codice è scritto per metà! Stai dicendo che in effetti, dovrebbe essere possibile controllare un ramo in questa situazione?
Daniel Farrell,

@boyfarrell Puoi usare 'Git stash' per salvare temporaneamente le modifiche senza impegnarti.
Howiecamp,


1
quando si passa a un ramo senza eseguire modifiche nel ramo precedente, git tenta di unire le modifiche ai file nel nuovo ramo. Se l'unione avviene senza alcun conflitto, i rami swithing avranno esito positivo e potrai vedere le modifiche nel nuovo ramo. Ma se si verifica un conflitto, otterrai error: You have local changes to '<filename>'; cannot switch branches.e il ramo non cambierà. puoi fare git checkout -m <branch-name>per unire i conflitti e fare il checkout al ramo e risolvere i conflitti tu stesso o git checkout -f <branch-name>ignorare le modifiche.
Samad Montazeri,

Risposte:


400

È necessario uno stato pulito per cambiare i rami. Il checkout delle filiali sarà consentito solo se non influisce sui "file sporchi" (come osserva Charles Bailey nei commenti).

Altrimenti, dovresti:

  • riporre la modifica corrente o
  • reset --hard HEAD (se non ti dispiace perdere quei piccoli cambiamenti) o
  • checkout -f (Quando si cambiano i rami, procedere anche se l'indice o l'albero di lavoro differisce da HEAD. Viene utilizzato per eliminare le modifiche locali.)

O, più recentemente:

Procedere anche se l'indice o l'albero di lavoro differisce da HEAD.
Sia l'indice che l'albero di lavoro vengono ripristinati per corrispondere al target di commutazione.

Ciò differisce da quello git switch -m <branch-name>che innesca una fusione a tre vie tra il ramo corrente, il contenuto dell'albero di lavoro e il nuovo ramo è fatto: non perderai il lavoro in corso in quel modo.


34
"Hai bisogno di uno stato pulito per cambiare i rami." è vero solo se la modifica del ramo influenza i "file sporchi".
CB Bailey,

10
Per il metodo stash, ho digitato "git stash save", "git checkout otherbranch", quindi infine "git stash pop".
Venkat D.

1
Attualmente non vedo questo messaggio di errore e le modifiche che ho apportato su un ramo vengono visualizzate sull'altro quando eseguo "git status". è cambiato qualcosa?
Senthil A Kumar,

2
Grazie. il check -f era quello di cui avevo bisogno. ho fatto ripristinare git --hard git clean -f git checkout mybranch -f
nologo

1
Ecco l'unica cosa che Git ha sbagliato totalmente violando la definizione di base di un ramo. A differenza di git branch significa due aree di lavoro totalmente diverse, biforcute da un repository.
Nehem,

125

Se si desidera annullare le modifiche,

git checkout -- <file>
git checkout branch

Se vuoi mantenere le modifiche,

git stash save
git checkout branch
git stash pop

10
In effetti quello che dice Romerun (per essere completo): git stash save(quando si lavora nel ramo Y) quindi git checkout branchXfare qualcosa git add/commit -mecc. git checkout branchYE git stash popper recuperare la scorta
Highmastdon

2
Può darsi. Ho una situazione in cui voglio fare ciò che dice la risposta, se la sto capendo bene: nascondi i cambiamenti, passa da Y a X, quindi fai apparire i cambiamenti e commettili su X.
Ben Klein,

1
nota che git stash saveora è deprecato a favore digit stash push
Argento

Questo alias semplifica il caso di mantenere le modifiche quando si cambiano i rami.
Tom Hale,

62

bene, dovrebbe essere

git stash save
git checkout branch
// do something
git checkout oldbranch
git stash pop

5
Sì, la scorta è globale, non specifica del ramo, se nascondo il pop dopo il cambio di ramo otterrò la stessa scorta di altri rami
Aditya Mittal

6
Va notato git stashche per impostazione predefinitagit stash save
Charlie-Greenman l'

Grazie, è molto utile per me
Govind Kumar


16

Nota che se hai unito filiali remote o hai commit locali e vuoi tornare a HEAD remoto devi fare:

git reset --hard origin/HEAD

HEAD da solo si riferirà solo al commit / merge locale - diverse volte ho dimenticato che quando si ripristina e si finisce con "il repository è X commette in anticipo .." quando ho intenzione di annotare completamente TUTTE le modifiche / commit e tornare al ramo remoto .


9

Se hai apportato modifiche ai file che Git deve cambiare anche quando cambi ramo, non te lo consentirà. Per annullare le modifiche funzionanti, utilizzare:

git reset --hard HEAD

Quindi, sarai in grado di cambiare ramo.


9

Nessuna di queste risposte mi ha aiutato perché avevo ancora file non tracciati anche dopo il reset e lo stash. Ho dovuto fare:

git reset --hard HEAD
git clean -d -f

4

passare a una nuova filiale perdendo le modifiche:

git checkout -b YOUR_NEW_BRANCH_NAME --force

passare a una filiale esistente perdendo le modifiche:

git checkout YOUR_BRANCH --force

4

Risposta semplice:

è forzare il checkout di un ramo

git checkout -f <branch_name>

Forzare il checkout di un ramo sta dicendo a git di eliminare tutte le modifiche apportate nel ramo corrente e di verificare quello desiderato.

o nel caso tu stia verificando un commit

git checkout -f <commit-hash>


"ho pensato che avrei potuto cambiare filiale senza impegnarmi. In tal caso, come posso impostarlo? In caso contrario, come posso uscire da questo problema?"

La risposta a questa domanda è No , questa è letteralmente la filosofia di Git che tieni traccia di tutte le modifiche e che ogni nodo (ovvero commit) deve essere aggiornato con le ultime modifiche che hai apportato, a meno che tu non abbia fatto un nuovo impegno ovviamente.


Hai deciso di mantenere i cambiamenti?

Quindi nascondili usando

git stash

e quindi per annullare la modifica delle modifiche nel ramo desiderato, utilizzare

git stash apply

che ti applicherà le modifiche ma le manterrà anche nella coda di scorta. Se non si desidera tenerli nella pila di oggetti, farli apparire usando

git stash pop

Questo è l'equivalente di applye quindidrop


2

Chiudi il terminale, elimina la cartella in cui si trova il tuo progetto, quindi clona nuovamente il tuo progetto e voilá.


2
git non è progettato per spingerti a eliminare il progetto e clonarlo di nuovo! se vuoi ottenere l'ultima versione dall'origine, sei solo tu reset --hard!
Ahmed Nour Jamal El-Din,

2

Se si desidera mantenere le modifiche e modificare il ramo in un comando a riga singola

git stash && git checkout <branch_name> && git stash pop

1

Sposta le modifiche non impegnate in un nuovo ramo

Ho creato un .gitconfigalias per questo:

[alias]
spcosp = !"git stash push && git checkout \"$@\" && git stash pop --index #"

Per passare a new-branch-name, utilizzare:

git spcosp new-branch-name

E tutte le modifiche di file e indici non impegnate verranno mantenute.


1

git checkout -f your_branch_name

git checkout -f your_branch_name

se hai problemi a ripristinare le modifiche:

git checkout .

se si desidera rimuovere directory e file non tracciati:

git clean -fd

0

Per passare a un altro ramo senza eseguire le modifiche quando git stash non funziona. È possibile utilizzare il comando seguente:

git checkout -f nome-ramo

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.