2009-10-27 7 views
32

Nei miei esperimenti non sono stato in grado di trovare alcuna differenza funzionale traQual è la differenza tra git resettare --hard e git resettare --merge

git reset --hard 

e

git reset --merge 

L'utilizzo le istruzioni non danno alcun accenno né

--hard    reset HEAD, index and working tree 
--merge    reset HEAD, index and working tree 

io uso regolarmente l'opzione --hard così understan come funziona Qual è la differenza tra le opzioni --merge e --hard?

Cheers, Olly

Forse un esempio potrebbe aiutare qui, usiamo la seguente sequenza:

cd git_repo 
touch file_one 
git add file_one 
git commit -m "commit one" # sha1 of 123abc 
echo "one" >> ./file_one 
git commit -a -m "commit two" # sha1 of 234bcd 
echo "two" >> ./file_one 
git add . # populate index with a change 
echo "three" >> ./file_one # populate working area with a change 

Ora, se provo

git reset --merge 123abc 

ottengo

error: Entry 'file_one' not uptodate. Cannot merge. 
fatal: Could not reset index file to revision '123abc' 

il motivo è che file_one ha cambiamenti sia nella zona di lavoro e l'indice

Per rimediare a questo faccio

git add . 
git reset --merge 123abc 

Questa volta funziona, però, ottengo lo stesso risultato di git reset --hard. L'indice è vuoto, l'area di lavoro è vuota, file_one è vuoto, come avveniva dopo il primo commit.

Qualcuno può venire con i passaggi che illustrano la differenza?

risposta

26

Da git reset manpage:

 
--hard Matches the working tree and index to that of the tree being 
       switched to. Any changes to tracked files in the working tree since 
       <commit> are lost. 

--merge 
       Resets the index to match the tree recorded by the named commit, and 
       updates the files that are different between the named commit and 
       the current commit in the working tree. 

Il git reset --merge è destinata ad essere una versione più sicura di git reset --hard, quando le modifiche e qualcun altro le modifiche sono mescolati tra loro, cercando di portare i nostri cambiamenti intorno.

+1

Ho letto quei documenti, ma devo dire che non posso dare molto senso a loro. "Reimposta l'indice in modo che corrisponda all'albero registrato dal commit denominato" La mia comprensione è che l'indice è vuoto dopo l'operazione reset --merge, questo commento sembra indicare qualcos'altro. "e aggiorna i file diversi tra il commit specificato e il commit corrente nell'albero di lavoro" dove vengono effettuati gli aggiornamenti a questi file, non vengono visualizzati nell'indice, vengono commessi automaticamente? – opsb

+1

Dopo 'git reset --merge ' hai indice == , ma aggiorna solo quei file in lavorazione che sono diversi tra HEAD (commit corrente) e (named commit), preservando (alcune delle) modifiche locali . –

+0

Nell'esempio che ho sopra ho scoperto che non potevo eseguire un reset git --merge quando avevo delle modifiche nell'area di lavoro. E 'possibile, infatti, utilizzare diversi passaggi da quelli che ho mostrato sopra? – opsb

3

pare secondo:

http://www.kernel.org/pub/software/scm/git/docs/git-reset.html

--hard - corrisponde l'albero di lavoro e l'indice a quella dell'albero essendo passato a. Qualsiasi modifica ai file tracciati nell'albero di lavoro dal <commit> viene persa.

--merge - Ripristina l'indice in modo che corrisponda l'albero registrato dal nome commit, e aggiorna i file che sono diversi tra il nome commit e la corrente commit nel albero di lavoro.

7

Questo è utile quando si esegue un pull con modifiche nell'albero di lavoro e si rileva che l'unione non è come previsto (si sarebbe potuto prevedere che il commit non avrebbe influito sui file su cui si stava lavorando). A questo punto, se fai lo git reset --hard ORIG_HEAD, fai saltare tutto, comprese le modifiche locali. Se fai git reset --merge ORIG_HEAD, manterrai le tue modifiche locali.

8

L'articolo "Git undo, reset or revert?" riassume i diversi usi, se utilizzato con ORIG_HEAD:

# Reset the latest successful pull or merge 
$ git reset --hard ORIG_HEAD 

# Reset the latest pull or merge, into a dirty working tree 
$ git reset --merge ORIG_HEAD 

Come menzionato da manojlds s' answer, e illustrato dal blog post, quest'ultimo è particolarmente utile quando si vede un errore messaggio del tipo:

fatal: You have not concluded your merge. (`MERGE_HEAD` exists) 

Il filo "[PATCH] refuse to merge during a merge" dettagli anche questo punto:

git reset --merge HEAD 

Si riempie il caso piuttosto diverso in cui avete fatto una fusione pulita con alcune non impegnati cambiamenti nel worktree, ma poi vogliono gettare ancora una volta l'unione senza perdere le modifiche non.
In assenza delle modifiche, si utilizzerà semplicemente --hard, ma qui si desidera spostare la punta della diramazione mentre le si fondono, in modo simile a ciò che fa 'git checkout -m' per in movimento HEAD.