2009-10-27 18 views
32

En mis experimentos no he podido encontrar ninguna diferencia funcional entre¿Cuál es la diferencia entre git reset --hard y git reset --merge

git reset --hard 

y

git reset --merge 

El uso instrucciones no dan ninguna pista ya sea

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

que suelo usar la opción de modo --hard understan d cómo eso funciona ¿Cuál es la diferencia entre las opciones --merge y --hard?

Saludos, Olly

Tal vez un ejemplo podría ayudar aquí, vamos a usar la siguiente secuencia:

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 

Ahora bien, si lo intento

git reset --merge 123abc 

consigo

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

la razón es que tiene file_one cambios tanto en el área de trabajo y el índice

Para remediar esto hago

git add . 
git reset --merge 123abc 

Esta vez funciona, sin embargo, me sale el mismo resultado que git reset --hard. El índice está vacío, el área de trabajo está vacía, file_one está vacío, como estaba después del primer commit.

¿Alguien puede encontrar los pasos que ilustran la diferencia?

Respuesta

26

De 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. 

El git reset --merge está destinado a ser una versión más segura de git reset --hard, cuando los cambios y demás cambia alguien se mezclan entre sí, tratando de llevar a nuestros cambios alrededor.

+1

He leído esos documentos, pero tengo que decir que no les puedo dar mucho sentido. "Restablece el índice para que coincida con el árbol registrado por la confirmación con nombre" Tengo entendido que el índice está vacío después del restablecimiento - operación de cambio, este comentario parece indicar algo más. "y actualiza los archivos que son diferentes entre la confirmación nombrada y la confirmación actual en el árbol de trabajo" ¿dónde están las actualizaciones que se realizan a estos archivos, no aparecen en el índice, se confirman automáticamente? – opsb

+1

Después de 'git reset --merge ' tiene índice == , pero solo actualiza esos archivos en funcionamiento que son diferentes entre HEAD (confirmación actual) y (commit nombrado), conservando (algunos de) sus cambios locales . –

+0

En el ejemplo que he descrito anteriormente, descubrí que no podía realizar un reinicio de git, sino cuando tenía cambios en el área de trabajo. ¿Esto es de hecho posible usando diferentes pasos de los que he mostrado arriba? – opsb

3

Al parecer, de acuerdo a:

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

--hard - Hace coincidir el árbol de trabajo y el índice a la del árbol se está cambiando a. Se pierden todos los cambios en los archivos rastreados en el árbol de trabajo desde <commit>.

--merge - Pone a cero el índice para que coincida con el árbol registrada por la llamada de confirmación, y actualiza los archivos que son diferentes entre el llamado cometen y la corriente se comprometen en el árbol de trabajo.

7

Esto es útil cuando realiza una extracción con cambios en el árbol de trabajo, y encuentra que la fusión no es la esperada (es posible que haya estado esperando que las confirmaciones no afecten a los archivos en los que estaba trabajando). En este punto, si lo hace git reset --hard ORIG_HEAD, se deshace de todo, incluidos los cambios locales. Si lo hace git reset --merge ORIG_HEAD, mantendrá sus cambios locales.

8

El artículo "Git undo, reset or revert?" resume los diferentes usos, cuando se utiliza 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 

Como se ha mencionado por manojlds 's answer, e ilustrado por la blog post, este último es especialmente útil cuando se ve un error mensaje como:

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

El hilo "[PATCH] refuse to merge during a merge" también detalles que punto:

git reset --merge HEAD 

Llena la bastante diferente caso en el que hizo una fusión limpia con algunos comprometidos cambios en el worktree, pero luego desea descartar la fusión de nuevo sin perder los cambios no confirmados.
En ausencia de los cambios, solo usaría --hard, pero aquí quiere mover la punta de la rama mientras se fusiona, similar a lo que hace 'git checkout -m' para moviendo HEAD.

Cuestiones relacionadas