Los comandos git reset y git rm tienen utilidades muy diferentes, pero pueden confundirse fácilmente.
Git reset
El comando git reset es una herramienta poderosa que te permite deshacer o revertir cambios en tu repositorio de Git. Lo puedes ejecutar de tres maneras diferentes, con las líneas de comando --soft, --mixed y --hard.
Pero no como git checkout que nos deja ir, mirar, pasear y volver. Con git reset volvemos al pasado sin la posibilidad de volver al futuro. Borramos la historia y la debemos sobreescribir. No hay vuelta atrás.
Tres árboles en Git
Para entender lo anterior, recordemos que los "tres árboles" de Git son estructuras de datos basadas en nodos y punteros que Git utiliza para hacer seguimiento a un cronograma de ediciones, aunque no sean estructuras en forma de árbol en el sentido tradicional.
La mejor forma de entender estos mecanismos es creando un conjunto de cambios en un repositorio y siguiéndolos a través de los tres árboles. Averigüémoslo.
git reset permite moverte entre diferentes commits para deshacer o rehacer cambios. Git guarda todos lo nuevo del repositorio como commits, que son instantáneas del estado del código en un momento dado y existen variaciones de este comando.
Variaciones de Git Reset
git reset --soft: Borra el historial y los registros de Git de commits anteriores, pero guarda los cambios en Staging para aplicar las últimas actualizaciones a un nuevo commit.
git reset --hard: Deshace todo, absolutamente todo. Toda la información de los commits y del área de staging se elimina del historial.
git reset --mixed: Borra todo, exactamente todo. Toda la información de los commits y del área de staging se elimina del historial.
git reset HEAD: El comando git reset saca archivos del área de staging sin borrarlos ni realizar otras acciones. Esto impide que los últimos cambios en estos archivos se envíen al último commit. Podemos incluirlos de nuevo en staging con git add si cambiamos de opinión.
Ten en cuenta que, si deshaces commits en un repositorio compartido en GitHub, estarás cambiando su historia y esto puede causar problemas de sincronización con otros colaboradores.
¿Qué es git reset HEAD?
git reset HEAD es un comando que te permite revertir los cambios que ya habías preparado para subir, y moverlos de vuelta a tu proyecto. Con este comando puedes cancelar los cambios que ya habías agregado, para que puedas revisarlos, modificarlos o deshacerlos antes de confirmarlos con un commit.
Git rm
Por otro lado, git rm es un comando que nos ayuda a eliminar archivos de Git sin eliminar su historial del sistema de versiones. Para recuperar el archivo eliminado, necesitamos retroceder en la historia del proyecto, recuperar el último commit y obtener la última confirmación antes de la eliminación del archivo.
Es importante tener en cuenta que git rm no puede usarse sin evaluarlo antes. Debemos usar uno de los flags siguientes para indicarle a Git cómo eliminar los archivos que ya no necesitamos en la última versión del proyecto.
Variaciones de Git rm
git rm --cached: Elimina archivos del repositorio local y del área de staging, pero los mantiene en el disco duro. Deja de trackear el historial de cambios de estos archivos, por lo que quedan en estado untracked.
git rm --force: Elimina los archivos de Git y del disco duro. Git guarda todo, por lo que podemos recuperar archivos eliminados si es necesario (empleando comandos avanzados).
¡Al usar git rm lo que haremos será eliminar este archivo completamente de git!
¿Cuál es la diferencia entre git rm y git reset Head?
La diferencia principal entre git rm y git reset HEAD radica en que git rm elimina archivos del repositorio y de la historia del proyecto, mientras que git reset saca los cambios del área de preparación y los mueve del espacio de trabajo, sin afectar la historia del repositorio.
Es importante tener en cuenta el efecto que cada comando tiene en el proyecto y usarlos según tus necesidades y objetivos específicos.
¿Cuándo utilizar git reset en lugar de git revert?
Para reescribir la historia del repositorio y eliminar confirmaciones anteriores, se utiliza git reset. Para deshacer cambios de confirmaciones anteriores de forma segura sin modificar la historia del repositorio, se emplea git revert.
Resumen
Para evitar problemas en el trabajo, es valioso entender las implicaciones y riesgos de cada comando y elegir el enfoque adecuado según las necesidades y el flujo de trabajo del proyecto.
Con git rm eliminamos un archivo de Git, pero mantenemos su historial de cambios. Si no queremos borrar un archivo, sino dejarlo como está y actualizarlo después, no debemos usar este comando en este commit.
Empleando git reset HEAD, movemos los cambios de Staging a Unstaged, pero mantenemos el archivo en el repositorio con los últimos cambios en los que hicimos commit. Así, no perdemos nada relevante.
Siguientes pasos
Bueno, todos los cambios están en el área de Staging, incluido el archivo con los cambios que no están listos. Esto significa que debemos sacar ese archivo de Staging para poder hacer commit de todos los demás.
Felicitaciones te quedo demasiado bueno, muy clara la información...Good Job..!😎
en que plataforma lo hiciste
Mis notas con la información del post
estan muy cool! ¿como las realizas?
Lo realizo ya sea con photoshop o sino con canva, me ayuda mucho la información de esa manera para recordarla mejor :D
Cuando usas git reset --hard por equivocación:
O cuando haces un Merge xD
jajajajajajjjj
Hola a todos, me gustaría compartir un resumen de esta clase porque veo confusión:
Sabemos que tenemos tres zonas (Directorio, Staging y Repositorio)
Cuando editamos un archivo y salvamos los cambios solamente, Git detecta que hay una modificación y esto lo vemos con el comando git status o git diff.
Cómo ocurre esto?
Esto se logra porque cuando se ejecuta un commit, se genera un Path o ruta del archivo en las tres zonas mencionadas, el archivo queda encadenado entre el directorio y el repositorio, Git hace un tracking o rastreo por la ruta establecida para detectar los cambios. cuando ejecutamos el comando git status o git diff, GIT los refleja en pantalla.
Ahora bien, volvamos al punto donde solamente edité el archivo en la zona del directorio y salvé los cambios,
para introducirlo en la zona de staging debemos hacerlo con…git add cierto?....Bien..!
Supongamos ahora que deseamos sacar de la zona staging el archivo, tenemos dos opciones:
a) git reset head file: mueves el archivo al directorio simplemente, si ejecutas git status o git diff observarás que GIT sigue detectando cambios en el archivo, porque la ruta o path sigue rastreada o tracked, puedes aprovechar esto para devolver los cambios que editaste en el archivo, recuerda que ahora esta en el directorio, ejecutando el comando git restore file, dejarás el archivo como lo encontraste y si deseas comprobar que todo está “original” ; ejecuta el comando git status o git diff, verás que git no detecta cambios.
“git reset head file” mueve el archivo de la zona staging a la zona directorio pero queda tracked por GIT.
Qué pasa que si ejecutas “git rm --cached file”?:
Eliminas el archivo directamente de la zona staging pero a demás su path y el archivo queda “Untracked” inrastreable, No lo mueves a la zona directorio, lo eliminas por completo la memoria sin dejar rastros para GIT, por lo tanto si deseas volver a la originalidad el archivo editado en la zona directorio con el comando git restore file, “GIT no podrá restaurar los cambios”, hiciste un reset memory del archivo en la ram o zona staging dejándolo fuera o chached de la memoria, ahora espero que podramos entender que hace “git rm --cached file”.
git rm --force file: es mas potente todavía porque lo eliminas de la zona staging y de la zona directorio, dicho en otras palabras los borras de GIT y del Disco Duro.
Hay que aclarar algo que puede confundir (Importante):
Cuando ejecutamos “git rm --cached file” y luego haces “git diff” observaras que “NO hay diferencias” en el archivo que se encuentra en la zona directorio con respecto a la zona repositorio (Ultimo commit), recuerda que este contiene la ultima versión del archivo en la rama master.
Qué pasa?
Git no lo detecta porque el archivo quedó eliminado y Untracked, pero en realidad el archivo que está en el directorio está modificado y es diferente con respecto al que se encuentra en la zona repositorio. si ejecutas el comando “git restore file”, GIT no podrá Matchear el archivo con el que se encuentra en el directorio, los cambios que editaste y salvaste no podrán deshacerse para volver al archivo original.
Qué podemos hacer para volver a rastrear el archivo y sea tracked por GIT:
Luego de ejecutar “git rm --cached file” podemos deshacer o restaurar los cambios con el comando “git restore --staged file”, ahora hemos restablecido la comunicación y GIT puede ayudarnos con el archivo porque esta tracked, pero NO esta en la zona staging, no te confundas simplemente esta Tracked…ahora si podemos ejecutar el comando “git restore file” y el archivo editado volverá a ser el original, todo quedará como lo encontraste! Compruébalo con “git status”.
Finalmente quedan los comando que se ejecutan en la zona del repositorio o staging-repositorio:
git reset N#Commit --soft: borra todos los commit superiores y queda como el commit master, el commit seleccionado en el comando, no hay vuelta atrás. a diferencia de “git checkout #commit file”.
git reset N#Commit --hard: borra todos los commit superiores y queda como el commit master, el commit seleccionado en el comando y además limpia la zona staging, no hay vuelta atrás como dice la clase…borra todo todito! así que corran por sus vidas.
Creo que esta muy claro cómo trabajan estos últimos comandos y el “git checkout”, en la clase anterior Freddy lo explica magistralmente.
Saludos!
Gracias por tu resumen :D
Un muy buen resumen, muy claro y preciso, muchas gracias será de gran utilidad.
Git rm: Remover/Eliminar
Git rm --cached: Elimina los archivos que están en staging (caché) pero los deja en tu carpeta (disco duro).
Git rm --force: Elimina el archivo de git y de tu carpeta (disco duro).
_Los archivos se pueden recuperar pero con comando avanzados.
Git reset: Ir a archivos pasados.
Git resert --hard: Borra todo, del área de staging, commits e historial.
Git reset --soft: Borra el historial y los registros pero mantiene los cambios agregado a staging.
Git reset HEAD: Imagina que hiciste ++git add++ a dos archivos, un HTML y otro CSS. Sin embargo, te diste cuenta que no agregaste los estilos correctamente porque los titulos son rojos. Haces git reset HEAD, tu archivo se quita de staging, vuelve a tu carpeta, modificas el archivo css y vuelves a hacer ++git add++. Si hubieses usado git rm tu archivo se hubiese eliminado.
Diferencias:git rm solo elimina archivos (ya sea de staging o del disco duro).
git reset te envía a versiones antiguas y elimina archivos, historial y registros.
Gracias justo estaba buscando la diferencia entre rm cached y reset head
Muy bueno tu resumen bro!
git reset --hard
Por si alguien quedo con duda de que es el Staging area aqui les dejo esta imagen quita dudas:
La simplicidad es la máxima sofisticación - Da vinci.
Espectacular!
Para poder entnederle tuve que experimentar dejo mis resultados:
git rm --cached- Regresa el archivo a un punto anterior especifico: NO
Borrado de
- Work Directory: NO
- Stage Area: SI
- Git: NO
Comentario: vuelve a la normalidad con git add; el archivo ya no esta en Traking
git reset --hard- Regresa el archivo a un punto anterior especifico: SI
Borrado de
- Work Directory: NO
- Stage Area: SI
- Git: SI
Comentario: Para regresar a la "normalidad", agregas los cambios hechos, git add; **git commit **
git reset HEAD- Regresa el archivo a un punto anterior especifico: NO
Borrado de
- Work Directory: NO
- Stage Area: NO
- Git: NO
Comentario: Simplemente quita el archivo del Stage Area; el archivo sigue en Tracking
Espero haber simplificado un poco este tema
(Hice una tablita en excel, pero no se como compartir imagenes aquí; BIG CHALE u _ u)
Gracias tu comentario es muy valioso, agrega mucha claridad al resultado de los comandos. Se merece muchos mas likes. Saludos!
En el caso de que quieras compartir imagenes aqui guardalas directamente como imagen y arrastralas al cuadro de dialogo. Pero no te olvides de haber guardado la imagen, sino no vas a poder. Saludos! :)
La diferencia entre usar$ git rm --cached y $ git reset head para eliminar un archivo de Staging:
Con $ git rm --cached deja los archivos sin ser rastreados (untracked), los elimina completamente de git. Si queremos que sean rastreados de nuevo hay que agregarlos ($ git add). Si despues del $ git rm --cached vemos el status, podemos ver que efectivamente el archivo fue eliminado, y que no esta siendo rastreado.
Con $ git reset head el archivo sigue trackeado, pero los ultimos cambios no han sido añadidos a Staging. Si vemos el status despues de ejecutar el
$ git reset head vemos que el archivo sigue siendo trackeado, no ha sido elimado de Git, pero los ultimos cambios no han sido agregados a Staging.
En conclusion $ git rm --cached es más agresivo que $ git reset head , porque $ git rm --cached elimina el archivo de Git, no solamente lo que habia en Staging, sino todo el archivo. Deja de ser trackeado.
Con$ git reset head el archivo sigue siendo trackeado, solo se eliminan de Staging los ultimos cambios.
Gracias por la explicación:) es la unica que entendí
Buen aporte, gracias
les comparto el mapa mental de esta explicacion
De mucha ayuda, gracias!
Excelente, diagrama muy claro
Tengamos en cuenta momentos en donde queremos hacer git add en todos los archivos menos en uno, no nos pondríamos a hacer git add y el nombre de cada archivo obviando el que no queremos eso no es nada eficiente, en cambio lo mejor es hacer git add . y después usar un git reset HEAD de ese archivo en particular y así podemos hacer commit en todos menos en ese, y nos ahorramos mucho tiempo
Excelente definicion.
Gracias por el consejo
Pongo mis apuntes de de este bloque del curso por si a alguien le sirven :p
Excelente resumen, muy útil, gracias!
Muchas gracias por el aporte.
Entonces tenemos hasta el momento antes de llegar a esta clase los siguientes comandos.
git init => para iniciar nuestro proyecto con un repositorio nuevo
git add archivo.txt => para agregar un archivo a nuestro estado staging
git add . => para agregar todos los archivos a nuestros estado staging
git status => para verificar el estado
git commit -m "Mensaje descriptivo" => para guardar nuestros cambios al repositorio
git log => para mostrar el registro de cambios de nuestro repositorio
git log --stat => para mostrar el registro de cambios de nuestro repositorio con el detalle de cambios por cada archivo
git show => para mostrar los cambios a detalle
git diff => para mostrar los cambios realizados entre commits
Con esta lectura me queda muy claro, lo siguiente:
git rm ===> Sirve para eliminar archivos que ya no necesitemos mantener en nuestro repo.
git reset ==> Sirve viajar a un commit antiguo y sobreescribir toda la historia.
git reset HEAD ==> Sirve para mover los archivos que no quisieramos incluir en el commit que realizaremos. De esta manera mantenemos los cambios, pero no lo registramos en el commit. Hasta que estemos seguros de incluirlo.
Espero les sirva.
Muchas gracias por tu aporte!
Excelente resumen, muy claro y preciso
Reset: Volver a una version anterior
Hard: Todo vuelve al estado anterior (borra todo del stagging)
Soft: El stagin sigue ahí, disponible para el proximo commit
HEAD: Sacar archivos del area de staging, se puede reversir con un git add .
Rm: Quitar un archivo, pero matenerlo en el control de versiones
Cached: Del staggin y del proximo commit, pero los mantiene en el disco duro
Force: Del git y del disco duro. Sin embargo, se puede viajar en el tiempo y recuperarlo
Excelente aporte
Muy claro, buen aporte
Si después de leer esta explicación aún siguen con dudas, sólo les puedo decir que realicen el ejercicio tantas veces como sea necesario, es la única forma de comprender a aprender.
Pero en pocas palabras: usa el comando rm para cuando requieras eliminar un archivo, pero ten en cuenta que si usas el comando rm --cahed le estamos diciendo a git que si nuestro archivo ya está en el área de staging lo saque de ahí pero lo conserve en nuestro disco duro, pero cuando realicemos el próximo commit en el repositorio dicho archivo ya no va a existir y git ya no lo va a estar rastreando .
Debemos de usar el comando git reset HEAD <nombre_archivo> cuando necesitemos sólo sacar nuestro archivo del área de staging para que no se valla con cambios en el próximo commit.
gracias! es necesario ponerlo en practica
hola, al realizar una de estas acciones se genera una copia?
Se agradece por el dato !!👍
💚 Excelente recurso para aclarar las diferencias entre git reset y git rm.