Qual è la differenza tra “git reset” e “git checkout”?

Ho sempre pensato che git reset e git checkout fossero gli stessi, nel senso che entrambi riportano il progetto a un commit specifico. Tuttavia, ritengo che non possano essere esattamente gli stessi, in quanto sarebbe ridondante. Qual è la differenza effettiva tra i due? Sono un po ‘confuso, dato che svn ha solo svn co per ripristinare il commit.

AGGIUNTO

Il diagramma seguente spiega la differenza, anche se in modo forse eccessivamente semplificato o errato. Cosa ne pensi? È sbagliato o eccessivamente semplificato?

http://a.imageshack.us/img192/5440/screenshot20100903at416.png

AGGIUNTO 2

VonC e Charles hanno spiegato molto bene le differenze tra git reset e git checkout . La mia attuale comprensione è che git reset ripristina tutte le modifiche su un commit specifico, mentre git checkout più o meno si prepara per un ramo. Ho trovato i seguenti due diagrammi molto utili per arrivare a questa comprensione:

http://a.imageshack.us/img651/1559/86421927.pnghttp://a.imageshack.us/img801/1986/resetr.png

AGGIUNTO 3

Da http://think-like-a-git.net/sections/rebase-from-the-ground-up/using-git-cherry-pick-to-simulate-git-rebase.html , il checkout e il reset possono emulare il rebase.

inserisci la descrizione dell'immagine qui

 git checkout bar git reset --hard newbar git branch -d newbar 

inserisci la descrizione dell'immagine qui

  • git reset riguarda in particolare l’ aggiornamento dell’indice , spostando l’HEAD.
  • git checkout riguarda l’ aggiornamento dell’albero di lavoro (per l’indice o l’albero specificato). Aggiorna l’HEAD solo se controlli un ramo (in caso contrario, finisci con un HEAD distaccato ).

In confronto, dato che svn non ha indice, solo un albero funzionante, svn checkout copierà una determinata revisione in una directory separata.
L’equivalente più vicino per il git checkout avrebbe:

  • svn update (se ci si trova nello stesso ramo, ovvero lo stesso URL SVN)
  • svn switch (se esegui il checkout ad esempio dello stesso ramo, ma da un altro URL repo SVN)

Tutte quelle tre modifiche dell’albero di lavoro ( svn checkout , update , switch ) hanno un solo comando in git: git checkout .
Ma dal momento che git ha anche la nozione di indice (quella “area di staging” tra il repository e l’albero di lavoro), hai anche git reset .


Thinkeye menziona nei commenti l’articolo ” Ripristina Demistificato “.

Ad esempio, se abbiamo due rami, ” master ” e ” develop ” puntano a commit diversi, e al momento siamo su ” develop ” (così HEAD lo indica) e eseguiamo git reset master , ” develop ” stesso ora lo farà puntare allo stesso commit di ” master “.

D’altra parte, se eseguiamo invece git checkout master , ‘ develop ‘ non si muoverà, HEAD stesso lo farà. HEAD ora punta a ” master “.

Quindi, in entrambi i casi, spostiamo HEAD in modo che punti A , ma il modo in cui lo facciamo è molto diverso. reset sposterà il ramo HEAD punti, il checkout sposta HEAD stesso verso un altro ramo.

http://git-scm.com/images/reset/reset-checkout.png

Nella loro forma più semplice, reset reimposta l’indice senza toccare l’albero di lavoro, mentre il checkout cambia l’albero di lavoro senza toccare l’indice.

Reimposta l’indice in modo che corrisponda a HEAD , albero di lavoro lasciato solo:

 git reset 

Concettualmente, questo controlla l’indice nell’albero di lavoro. Per farlo fare effettivamente qualcosa che dovresti usare -f per forzarlo a sovrascrivere eventuali modifiche locali. Questa è una funzione di sicurezza per assicurarsi che la forma “no argument” non sia distruttiva:

 git checkout 

Una volta che si iniziano ad aggiungere parametri, è vero che c’è qualche sovrapposizione.

checkout viene solitamente utilizzato con un branch, tag o commit. In questo caso, Reimposta HEAD e l’indice al commit specificato, oltre a eseguire il checkout dell’indice nell’albero di lavoro.

Inoltre, se fornisci --hard to reset puoi chiedere a reset di sovrascrivere l’albero di lavoro e resettare l’indice.

Se si dispone di una filiale verificata, è ansible che ci sia una differenza cruciale tra il reset e il checkout quando si fornisce un ramo alternativo o un commit. reset cambierà il ramo corrente in modo che punti al commit selezionato mentre il checkout lascerà il ramo corrente da solo, ma eseguirà il checkout del ramo o del commit fornito.

Altre forms di reset e commit implicano percorsi di fornitura.

Se fornisci percorsi da reset non puoi fornire --hard e reset cambieranno solo la versione dell’indice dei percorsi forniti alla versione nel commit fornito (o HEAD se non specifichi un commit).

Se fornisci percorsi per il checkout , come il reset aggiornerà la versione dell’indice dei percorsi forniti per abbinare il commit fornito (o HEAD ) ma eseguirà sempre il checkout della versione dell’indice dei percorsi forniti nell’albero di lavoro.

Un caso d’uso semplice quando si ripristina il cambiamento:
1. Utilizzare reset se si desidera annullare la gestione temporanea di un file modificato.
2. Utilizzare checkout se si desidera eliminare le modifiche ai file non bloccati.

Atlassian ci dà una spiegazione eccellente su git reset , git checkout e così, git revert . In questo articolo, vengono spiegati i diversi usi di questi comandi su diversi livelli: file, snapshot di staging e commit.

https://www.atlassian.com/git/tutorials/resetting-checking-out-and-reverting

La differenza chiave in poche parole è che il reset sposta il riferimento di ramo corrente , mentre il checkout non lo fa (muove HEAD).

Come il libro Pro Git spiega sotto Reset Demystified ,

Il primo reset cosa è spostare ciò a cui HEAD punta . Questo non è lo stesso di cambiare HEAD stesso (che è ciò che fa il checkout ); reset sposta il ramo su cui HEAD punta. Ciò significa che se HEAD è impostato sul ramo master (ovvero si è attualmente sul ramo master ), l’esecuzione di git reset 9e5e6a4 inizierà facendo diventare il punto master su 9e5e6a4 . [enfasi aggiunta]

Vedi anche la risposta di VonC per un testo molto utile e un estratto dello stesso articolo, che non duplicherò qui.

Naturalmente ci sono molti più dettagli su quali effetti possono avere checkout e reset sull’indice e sull’albero di lavoro, a seconda di quali parametri sono usati. Ci possono essere molte somiglianze e differenze tra i due comandi. Ma a quanto vedo, la differenza più cruciale è il loro effetto sul ramo attuale.

I due comandi (reset e checkout) sono completamente diversi.

checkout X NON è reset --hard X

Se X è un nome di ramo, il checkout X cambierà il ramo corrente durante il reset --hard X non lo farà.