Vari modi per rimuovere le modifiche Git locali


625

Ho appena clonato un repository git e verificato un ramo. Ci ho lavorato e poi ho deciso di rimuovere tutte le mie modifiche locali, come volevo la copia originale.

In breve, ho dovuto eseguire i seguenti due comandi per rimuovere le mie modifiche locali

git checkout .

git clean -f

La mia domanda è,

(1) È questo l'approccio corretto per sbarazzarsi dei cambiamenti locali, oppure per favore fatemi sapere l'approccio corretto.

(2) quando utilizziamo git reset --hardcome sono in grado di ripristinare anche senza questo comando

Grazie

* Soluzione: principali modifiche: 26/03/03: * Sostituiti molti termini vaghi con una terminologia specifica git [tracciata / non tracciata / messa in scena / non messa in scena]

Potrebbero esserci solo tre categorie di file quando apportiamo modifiche locali:

Tipo 1. File tracciati in fasi

Tipo 2. File tracciati non gestiti

Tipo 3. File non tracciati non tracciati, ovvero file non tracciati

  • Staged: quelli che vengono spostati nell'area di staging / aggiunti all'indice
  • Tracciato: file modificati
  • Non tracciato: nuovi file. Sempre in scena. Se messo in scena, significa che vengono tracciati.

Cosa fanno i comandi:

  1. git checkout . - Rimuove SOLO i file tracciati non gestiti [Tipo 2]

  2. git clean -f - Rimuove SOLO i file non tracciati non tracciati [Tipo 3]

  3. git reset --hard - Rimuove SOLO i file tracciati in fasi e non tracciati in tracce [Tipo 1, Tipo 2]

  4. git stash -u - Rimuove tutte le modifiche [Tipo 1, Tipo 2, Tipo 3]

Conclusione:

È chiaro che possiamo usare entrambi

(1) combination of `git clean -f` and `git reset --hard` 

O

(2) `git stash -u`

per ottenere il risultato desiderato.

Nota: Stashing, poiché la parola significa "Conservare (qualcosa) in modo sicuro e segretamente in un luogo specifico". Questo può sempre essere recuperato utilizzando git stash pop. Quindi scegliere tra le due opzioni precedenti è la chiamata dello sviluppatore.

Grazie Christoph e Frederik Schøning.

Modifica: 27/03

Ho pensato che valga la pena mettere la nota " attenzione "git clean -f

git clean -f

Non si può tornare indietro. Usa -no --dry-runper vedere in anteprima il danno che farai.

Se si desidera rimuovere anche le directory, eseguire git clean -f -d

Se vuoi solo rimuovere i file ignorati, esegui git clean -f -X

Se si desidera rimuovere file ignorati e non ignorati, eseguire git clean -f -x

riferimento: altro su git clean: Come rimuovere i file locali (non tracciati) dall'albero di lavoro Git corrente?

Modifica: 20/05/15

Eliminare tutti i commit locali su questo ramo [Rimozione dei commit locali]

Per scartare tutti i commit locali su questo ramo, per rendere il ramo locale identico al "monte" di questo ramo, esegui semplicemente git reset --hard @{u}

Riferimento: http://sethrobertson.github.io/GitFixUm/fixup.html

oppure git reset --hard origin/master[se la filiale locale è master]

Nota: 06/12/2015 Questo non è un duplicato dell'altra domanda SO contrassegnata come duplicata. Questa domanda riguarda come rimuovere le modifiche GIT locali [rimuovere un file aggiunto, rimuovere le modifiche aggiunte al file esistente ecc. E i vari approcci; Dove nell'altro thread SO indirizzare solo come rimuovere il commit locale. Se hai aggiunto un file e desideri rimuoverlo da solo, l'altro thread SO non ne discute. Quindi questo non è un duplicato dell'altro]

Modifica: 23/06/15

Come ripristinare un commit già trasferito in un repository remoto?

$ git revert ab12cd15

Modifica: 09/01/2015

Elimina un commit precedente dalla filiale locale e dalla filiale remota

Caso: hai appena apportato una modifica alla tua filiale locale e hai subito spinto la filiale remota, improvvisamente realizzato, Oh no! Non ho bisogno di questo cambiamento. Adesso cosa?

git reset --hard HEAD~1 [per eliminare quel commit dalla filiale locale]

git push origin HEAD --force[entrambi i comandi devono essere eseguiti. Per l'eliminazione dalla filiale remota]

Qual è il ramo? È il ramo attualmente estratto.

Modifica 09/08/2015 - Rimuovi unione git locale :

Sono sul masterramo e ho unito il masterramo con un ramo appena funzionantephase2

$ git status
# On branch master

$ git merge phase2

$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 8 commits.

D: Come sbarazzarsi di questa unione? Ho provato git reset --hard ed git clean -d -f entrambi non hanno funzionato.

L'unica cosa che ha funzionato sono le seguenti:

$ git reset --hard origin/master

o

$ git reset --hard HEAD~8

o

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - questo è quello che era presente prima che avvenissero tutti i tuoi commit di merge]


1
Immagino che questa discussione possa rispondere alle tue domande: stackoverflow.com/questions/1146973/…
Saucier

1
"git stash" rimuoverà tutte le modifiche apportate.
John Ballinger,

1
Bel riassunto! Aggiungerei un'altra categoria di file: "Tipo 4. File ignorati". git stash -a[o --all] riporterà anche i file ignorati e non tracciati. git clean -xpulirà anche i file ignorati. git clean -Xpulirà solo i file ignorati.
Jerry101,

2
@JavaDev La tua domanda era più simile a una risposta .. apprezzo che hai continuato a modificare e compilare tutte le risposte.
Bhavuk Mathur,

1
grazie ho eseguito tutti e 4 i tuoi comandi per annullare le modifiche locali
Vincent Tang,

Risposte:


505

Tutto dipende esattamente da cosa stai cercando di annullare / ripristinare. Inizia leggendo il post nel link di Ube . Ma per tentare una risposta:

Hard reset

git reset --hard [HEAD]

rimuovere completamente tutte le modifiche graduali e non programmate ai file tracciati.

Mi trovo spesso a utilizzare un hard reset, quando sono tipo "annulla tutto come se avessi fatto un nuovo clone completo dal telecomando". Nel tuo caso, dove vuoi solo il tuo repository incontaminato, questo funzionerebbe.

Pulito

git clean [-f]

Rimuovi i file che non vengono tracciati.

Per la rimozione di file temporanei, ma mantenere le modifiche graduali e non in scena ai file già tracciati. La maggior parte delle volte, probabilmente finirei per creare una regola di ignore anziché ripeterla ripetutamente, ad esempio per le cartelle bin / obj in un progetto C #, che di solito vorresti escludere dal tuo repository per risparmiare spazio o qualcosa del genere.

L'opzione -f (force) rimuoverà anche i file che non vengono tracciati e che vengono ignorati da git sebbene ignore-rule. Nel caso sopra, con una regola ignore per non tracciare mai le cartelle bin / obj, anche se queste cartelle vengono ignorate da git, l'uso dell'opzione force le rimuoverà dal tuo file system. Ho visto sporadicamente un uso per questo, ad esempio durante la distribuzione di script, e vuoi pulire il tuo codice prima di distribuire, zippare o altro.

Git clean non toccherà i file che sono già stati tracciati.

Acquista "punto"

git checkout .

In realtà non avevo mai visto questa notazione prima di leggere il tuo post. Sto facendo fatica a trovare la documentazione per questo (forse qualcuno può aiutare), ma da giocare un po ', sembra che significhi:

msgstr "annulla tutte le modifiche nel mio albero di lavoro".

Vale a dire annullare le modifiche non messe in scena nei file tracciati. Apparentemente non tocca le modifiche organizzate e lascia da soli i file non monitorati.

stashing

Alcune risposte menzionano lo stashing. Come suggerisce la formulazione, probabilmente useresti lo stashing quando sei nel mezzo di qualcosa (non pronto per un commit) e devi cambiare temporaneamente i rami o in qualche modo lavorare su un altro stato del tuo codice, in seguito per tornare al tuo "disordinato" scrivania". Non vedo che questo vale per la tua domanda, ma è sicuramente utile.

Per riassumere

Generalmente, se sei sicuro di aver commesso e forse hai spinto verso un remoto cambiamenti importanti, se stai solo giocando o simili, usare git reset --hard HEADseguito da git clean -fripulirà definitivamente il tuo codice nello stato, sarebbe in, se fosse stato solo clonato e verificato da un ramo. È davvero importante sottolineare che il ripristino rimuoverà anche le modifiche graduali, ma senza impegno. Pulirà tutto ciò che non è stato eseguito il commit (tranne i file non tracciati, nel qual caso, utilizzare clean ).

Tutti gli altri comandi sono lì per facilitare scenari più complessi, in cui è necessaria una granularità di "cose ​​annullate" :)

Sento, la tua domanda n. 1 è coperta, ma alla fine, per concludere sul n. 2: il motivo per cui non hai mai trovato la necessità di utilizzare git reset --hardè che non hai mai messo in scena nulla. Se aveste messo in scena un cambiamento, né git checkout .ne git clean -fsarebbe tornato quello.

Spero che questo copra.


Grazie per il motivo dietro l'utilizzo git reset --hard. Ho provato, e sì .. i file aggiunti all'indice (messa in scena) sono stati rimossi solo dopo git reset --hard, e presumo di default git reset --hardè git reset --hard head. Questo link è stato utile anche gitready.com/beginner/2009/01/18/the-staging-area.html
spiderman

Ho migliorato la mia risposta perché penso che git stash -uabbia più senso qui.
Christoph,

2
Grazie ad entrambi. Ho riassunto la risposta e integrato nella mia domanda. Christoph fammi sapere cosa git stash -ufa e come farlo pop, ma Frederik mi fa sapere resettare duramente e usando la combinazione di git reset --harde git clean -f, e perché no, stashè preferito in alcuni scenari. Ora, per favore, aiutami a scegliere quale devo contrassegnare come Risposta :), entrambe sono le mie risposte.
Uomo

3
.è un pathspec che si riferisce alla directory di lavoro corrente, che potrebbe essere la radice del repository. Da git-scm.com: git checkout [<tree-ish>] [--] <pathspec>…aggiorna i percorsi denominati nell'albero di lavoro dal file indice o da un <tree-ish> denominato.
Jerry101,

3
Non è mai abbastanza sottolineato che sia git reset --harde git clean -dfxsimili sono distruttivi . Ad ogni modo, correggi la lettera minuscola headnella risposta, dovrebbe essere maiuscola HEADo non presente affatto.
Pavel Šimerda,

25

Motivo per aggiungere una risposta in questo momento:

Finora stavo aggiungendo la conclusione e le "risposte" alla mia domanda iniziale stessa, rendendo la domanda molto lunga, passando quindi a una risposta separata.

Ho anche aggiunto comandi git usati più frequentemente che mi aiutano su git, per aiutare anche qualcun altro.

Fondamentalmente per pulire tutti gli impegni locali $ git reset --harde $ git clean -d -f


Il primo passo prima di eseguire qualsiasi commit è configurare il nome utente e l'e-mail visualizzati insieme al commit.

# Imposta il nome che si desidera associare alle transazioni di commit

$ git config --global user.name "[name]"

# Imposta l'e-mail che desideri allegare alle tue transazioni di commit

$ git config --global user.email "[email address]"

# Elenca la configurazione globale

$ git config --list

# Elenca l'URL remoto

$ git remote show origin

#controllare lo stato

git status

# Elenca tutte le filiali locali e remote

git branch -a

#crea un nuovo ramo locale e inizia a lavorare su questo ramo

git checkout -b "branchname" 

oppure, può essere fatto come un processo in due fasi

crea ramo: git branch branchname lavora su questo ramo:git checkout branchname

#commit local change [processo in due passaggi: - Aggiungi il file all'indice, questo significa aggiungere all'area di staging. Quindi eseguire il commit dei file presenti in questa area di gestione temporanea]

git add <path to file>

git commit -m "commit message"

#controlla qualche altra filiale locale

git checkout "local branch name"

#removeve tutte le modifiche nel ramo locale [Supponiamo di aver apportato alcune modifiche nel ramo locale come l'aggiunta di un nuovo file o la modifica del file esistente o l'esecuzione di un commit locale, ma non è più necessario] git clean -d -fe git reset --hard [ripulisci tutte le modifiche locali apportate al ramo locale tranne se impegno locale]

git stash -u rimuove anche tutte le modifiche

Nota: è chiaro che possiamo usare una (1) combinazione di git clean –d –fe git reset --hard OR (2) git stash -u per ottenere il risultato desiderato.

Nota 1: Stashing, poiché la parola significa "Conservare (qualcosa) in modo sicuro e segretamente in un luogo specificato". Questo può sempre essere recuperato usando git stash pop. Quindi scegliere tra le due opzioni precedenti è la chiamata dello sviluppatore.

Nota 2: git reset --hardeliminerà le modifiche alla directory di lavoro. Assicurati di riporre eventuali modifiche locali che desideri conservare prima di eseguire questo comando.

# Passa al ramo principale e assicurati di essere aggiornato.

git checkout master

git fetch [potrebbe essere necessario (a seconda della configurazione di git) per ricevere aggiornamenti su origin / master]

git pull

# Unisci il ramo della funzione nel ramo principale.

git merge feature_branch

# Ripristina il ramo principale allo stato di origine.

git reset origin/master

#Eliminato accidentalmente un file da locale, come recuperarlo? Fare un git statusper ottenere il percorso file completo della risorsa eliminata

git checkout branchname <file path name>

questo è tutto!

#Merge il ramo principale con someotherbranch

git checkout master
git merge someotherbranchname

#rename branch locale

git branch -m old-branch-name new-branch-name

#delete filiale locale

git branch -D branch-name

#delete branch remoto

git push origin --delete branchname

o

git push origin :branch-name

# ripristina un commit già trasferito in un repository remoto

git revert hgytyz4567

#branch da un precedente commit utilizzando GIT

git branch branchname <sha1-of-commit>

#Cambia il messaggio di commit dell'ultimo commit che è già stato trasferito al telecomando

git commit --amend -m "new commit message"
git push --force origin <branch-name>

# Scarto di tutti i commit locali su questo ramo [Rimozione dei commit locali]

Per scartare tutti i commit locali su questo ramo, per rendere il ramo locale identico al "monte" di questo ramo, esegui semplicemente

git reset --hard @{u}

Riferimento: http://sethrobertson.github.io/GitFixUm/fixup.html o fare git reset --hard origin/master[se il ramo locale è master]

# Ripristinare un commit già trasferito in un repository remoto?

$ git revert ab12cd15

# Elimina un precedente commit dalla filiale locale e dalla filiale remota

Caso d'uso: hai appena apportato una modifica alla tua filiale locale e hai subito spinto la filiale remota, improvvisamente realizzato, Oh no! Non ho bisogno di questo cambiamento. Adesso cosa?

git reset --hard HEAD~1[per eliminare quel commit dalla filiale locale. 1 indica il ONE commit che hai fatto]

git push origin HEAD --force[entrambi i comandi devono essere eseguiti. Per l'eliminazione dalla filiale remota]. Il ramo attualmente estratto verrà indicato come ramo in cui si sta eseguendo questa operazione.

# Elimina alcuni dei commit recenti dal repository locale e remoto e preserva il commit che desideri. (una sorta di commit di ripristino da locale e remoto)

Supponiamo che tu abbia 3 commit che hai inviato al ramo remoto chiamato ' develop'

commitid-1 done at 9am
commitid-2 done at 10am
commitid-3 done at 11am. // latest commit. HEAD is current here.

Per ripristinare il vecchio commit (per modificare lo stato del ramo)

git log --oneline --decorate --graph // per vedere tutti i tuoi commit

git clean -d -f // pulisce tutte le modifiche locali

git reset --hard commitid-1 // ripristina localmente questo commit

git push -u origin +develop// spinge questo stato in remoto. + per forzare la spinta

# Rimuovi unione git locale: Caso: sono sul ramo principale e ho unito il ramo principale con un ramo 2 di recente funzionamento

$ git status

Sul direttore di filiale

$ git merge phase2 $ git status

Sul direttore di filiale

La tua filiale è davanti a "origine / master" di 8 commit.

D: Come sbarazzarsi di questa unione git locale? Ho provato git reset --harded git clean -d -fentrambi non hanno funzionato. L'unica cosa che ha funzionato sono le seguenti:

$ git reset --hard origin / master

o

$ git reset --hard HEAD ~ 8

o

$ git reset --hard 9a88396f51e2a068bb7 [sha commit code - questo è quello che era presente prima che avvenissero tutti i tuoi commit di merge]

#creare il file gitignore

touch .gitignore // crea il file negli utenti mac o unix

contenuti di esempio .gitignore:

.project
*.py
.settings

Link di riferimento al cheat sheet GIT: https://services.github.com/on-demand/downloads/github-git-cheat-sheet.pdf


1
Il tuo comando per l'eliminazione di Remote Branch potrebbe non essere ottimale . Stai usando git push origin :branch-namecomunque ti consiglio di usaregit push origin --delete branchname
vibs2006

Accetto, ho aggiornato con il tuo suggerimento, grazie @ vibs2006
spiderman

21

Come per ogni cosa in git, ci sono molti modi per farlo. I due comandi che hai usato sono un modo per farlo. Un'altra cosa che avresti potuto fare è semplicemente nasconderli git stash -u. La -ufa in modo che i file aggiunti di recente (non monitorate) sono inclusi anche.

La cosa utile git stash -uè che

  1. è probabilmente il singolo comando (solo?) più semplice per raggiungere il tuo obiettivo
  2. se cambi idea in seguito, riprendi tutto il tuo lavoro git stash pop(è come eliminare un'e-mail in Gmail dove puoi semplicemente annullare se cambi idea in seguito)

A partire dall'altra tua domanda git reset --hardnon rimuoverai i file non tracciati, quindi avresti ancora bisogno di git clean -f. Ma git stash -upotrebbe essere il più conveniente.


git reset --hardnon rimuoverà non monitorate file anzi, ma sarà rimuovere le modifiche non monitorate, vale a dire le modifiche ai file, che sono già nell'indice. Sono sicuro che intendevi questo :)
Frederik Struck-Schøning,

Quando l'ho usato git stash -u, ho visto questa risposta da Git Bash. "La directory di lavoro salvata e lo stato dell'indice WIP su {branchname}. Può essere questo salvato quello che potremmo recuperare usando git stash pop.
Spiderman

Grazie ad entrambi. Ho riassunto la risposta e integrato nella mia domanda. Christoph fammi sapere cosa git stash -ufa e come farlo pop, ma Frederik mi fa sapere resettare duramente e usando la combinazione di git reset --harde git clean -f, e perché no, stashè preferito in alcuni scenari. Ora, per favore, aiutami a scegliere quale devo contrassegnare come Risposta :), entrambe sono le mie risposte.
Uomo

ma cosa succede se c'è un file che ho aggiunto al mio repository che non voglio monitorare? solo nel mio repository. Se lo aggiungo all'elenco ignora, ho un file .ignore da impegnare che avrà effetto anche su tutti gli altri.
user20358

7

1. Quando non si desidera mantenere affatto le modifiche locali.

git reset --hard

Questo comando rimuoverà completamente tutte le modifiche locali dal tuo repository locale. Questo è il modo migliore per evitare conflitti durante il comando pull, solo se non si desidera mantenere affatto le modifiche locali.

2. Quando si desidera mantenere le modifiche locali

Se desideri estrarre le nuove modifiche da remoto e ignorare le modifiche locali durante questo pull,

git stash

Stash tutte le modifiche locali, ora puoi estrarre le modifiche remote,

git pull

Ora puoi ripristinare le modifiche locali tramite,

git stash pop

1
git reset --hardnon rimuove tutte le modifiche locali. Rimuove solo le modifiche. Se si desidera rimuovere le aggiunte, è necessario anchegit clean -fd
John Henckel,


4

Penso che git abbia una cosa che non è chiaramente documentata. Penso che sia stato in realtà trascurato.

git checkout .

Amico, mi hai salvato la giornata. Ho sempre cose che voglio provare a usare il codice modificato. Ma le cose a volte finiscono per rovinare il codice modificato, aggiungere nuovi file non tracciati, ecc. Quindi quello che voglio fare è, mettere in scena ciò che voglio, fare le cose disordinate, quindi ripulire rapidamente e impegnarmi se sono felice.

C'è git clean -fdfunziona bene per i file non monitorate.

Quindi git resetrimuove semplicemente la messa in scena, ma git checkoutè un po 'troppo ingombrante. Specificare il file uno per uno o usare le directory non è sempre l'ideale. A volte i file modificati che voglio eliminare sono all'interno delle directory che voglio conservare. Ho desiderato questo comando che rimuove solo le modifiche non messe in scena e qui sei. Grazie.

Ma penso che dovrebbero semplicemente avere git checkoutsenza alcuna opzione, rimuovere tutte le modifiche non messe in scena e non toccare la messa in scena. È un po 'modulare e intuitivo. Più come quello che git resetfa. git cleandovrebbe anche fare lo stesso.


2

Il modo migliore è verificare le modifiche.

Cambiando il file pom.xml in un progetto chiamato project-name puoi farlo:

git status

# modified:   project-name/pom.xml

git checkout project-name/pom.xml
git checkout master

# Checking out files: 100% (491/491), done.
# Branch master set up to track remote branch master from origin.
# Switched to a new branch 'master'

2

Per scartare tutto ciò che mi piace nascondere e rilasciare quella scorta, è il modo più veloce per scartare tutto, soprattutto se lavori tra più repository.

Questo annulla tutte le modifiche apportate alla {0}chiave e la rilascia immediatamente{0}

git stash && git stash drop


1

Prima di tutto verifica che la modifica importante sia salvata o meno da:

$ git status

che provare

$ git reset --hard

ripristinerà il ramo predefinito

ma se hai solo bisogno di annullare:

$ edit (1) $ git aggiungi frotz.c filfre.c $ mailx (2) $ git reset
(3) $ git pull git: //info.example.com/ nitfol


Maggiori informazioni >> https://git-scm.com/docs/git-reset


Nota a margine: reset: il comando "hard is dangerous "eliminerà tutte le modifiche e non potrà essere annullato. L'utente deve essere consapevole quando si utilizza il reset duro.
danglingpointer
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.