soft origin hard example changes git git-checkout git-reset

origin - ¿Hay alguna diferencia entre "git reset-hard hash" y "git checkout hash"?



git revert file (3)

Esta respuesta se cita principalmente en mi respuesta a una pregunta anterior: git reset en inglés simple .

Los dos son muy diferentes. Resultan en el mismo estado para su índice y árbol de trabajo, pero el historial resultante y la rama actual no son los mismos.

Supongamos que su historial se ve así, con la rama maestra actualmente seleccionada:

- A - B - C (HEAD, master)

y ejecutas git reset --hard B Obtendrás esto:

- A - B (HEAD, master) # - C is still here, but there''s no # branch pointing to it anymore

De hecho, obtendría ese efecto si usa --mixed o --soft también - la única diferencia es lo que sucede con su árbol e índice de trabajo. En el caso de - --hard , el árbol de trabajo y el índice coinciden con B

Ahora, supongamos que ejecutaría git checkout B lugar. Usted obtendría esto:

- A - B (HEAD) - C (master)

Has terminado en un estado HEAD separado. HEAD , árbol de trabajo, indexe todas las coincidencias B , igual que con el restablecimiento completo, pero la rama maestra se dejó atrás en C Si realiza una nueva confirmación D en este punto, obtendrá esto, que probablemente no sea lo que desea:

- A - B - C (master) / D (HEAD)

Entonces, usa checkout para, bueno, verifique ese compromiso. Puedes jugar con él, hacer lo que quieras, pero has dejado tu rama atrás. Si quieres mover la rama también, usa reset.

Mientras que el reset y la checkout tienen usos diferentes la mayoría del tiempo, no puedo ver qué diferencia hay entre estos dos.

Probablemente haya uno o nadie se hubiera molestado en agregar una opción --hard para hacer algo que el checkout básico puede hacer.

Tal vez hay una diferencia es la forma en que verá la historia?


Si la documentación provista con Git no le ayuda, eche un vistazo a A Visual Git Reference de Mark Lodato.

En particular, si está comparando git checkout <non-branch> con git reset --hard <non-branch> ( git reset --hard <non-branch> ):

git checkout master ~ 3 http://marklodato.github.com/visual-git-guide/checkout-detached.svg.png

git reset --hard master ~ 3 http://marklodato.github.com/visual-git-guide/reset-commit.svg.png

Tenga en cuenta que en el caso de git reset --hard master~3 , deja una parte de DAG de las revisiones: algunas de las confirmaciones no hacen referencia a ninguna de las confirmaciones. Esos están protegidos por (por defecto) 30 días por reflog ; En última instancia, serían podados (eliminados).


git-reset hash establece la referencia de la rama al hash dado, y opcionalmente lo verifica, con --hard .

git-checkout hash establece el árbol de trabajo en el hash dado; y a menos que hash sea un nombre de rama, terminarás con una cabeza separada.

En última instancia, git trata con 3 cosas:

working tree (your code) ------------------------------------------------------------------------- index/staging-area ------------------------------------------------------------------------- repository (bunch of commits, trees, branch names, etc)

git-checkout por defecto solo actualiza el índice y el árbol de trabajo, y opcionalmente puede actualizar algo en el repositorio (con la opción -b )

git-reset por defecto solo actualiza el repositorio y el índice, y opcionalmente el árbol de trabajo (con la opción --hard )

Puedes pensar en el repositorio así:

HEAD -> master refs: master -> sha_of_commit_X dev -> sha_of_commit_Y objects: (addressed by sha1) sha_of_commit_X, sha_of_commit_Y, sha_of_commit_Z, sha_of_commit_A ....

git-reset manipula a lo que apuntan las referencias de rama.

Supongamos que su historia se parece a esto:

T--S--R--Q [master][dev] / A--B--C--D--E--F--G [topic1] / Z--Y--X--W [topic2][topic3]

Tenga en cuenta que las ramas son solo nombres que avanzan automáticamente cuando se comprometen.

Así que tienes las siguientes ramas:

master -> Q dev -> Q topic1 -> G topic2 -> W topic3 -> W

Y su rama actual es topic2 , es decir, HEAD apunta al tema2.

HEAD -> topic2

Luego, git reset X restablecerá el nombre topic2 para que apunte a X; es decir, si realiza un P de compromiso en el tema de la rama2, las cosas se verán así:

T--S--R--Q [master][dev] / A--B--C--D--E--F--G [topic1] / Z--Y--X--W [topic3] / P [topic2]