¿“Git rm - x en caché” frente a “git reset head - x”?

163

GitRef.org - Básico :

git rmeliminará las entradas del área de preparación. Esto es un poco diferente de lo git reset HEADque "desestabiliza" archivos. Al decir "unstage" quiero decir que revierte el área de preparación a lo que estaba allí antes de comenzar a modificar las cosas. git rmpor otro lado, simplemente saca el archivo del escenario por completo, de modo que no se incluye en la siguiente instantánea de confirmación, por lo que se elimina de manera efectiva.

Por defecto, a git rm fileeliminará el archivo del área de preparación por completo y también de su disco> (el directorio de trabajo). Para dejar el archivo en el directorio de trabajo, puede usar git rm --cached.

Pero, ¿cuál es exactamente la diferencia entre git rm --cached asdy git reset head -- asd?

Pacerier
fuente

Respuestas:

219

Hay tres lugares donde puede estar un archivo, por ejemplo, el árbol, el índice y la copia de trabajo. Cuando solo agrega un archivo a una carpeta, lo agrega a la copia de trabajo.

Cuando haces algo como git add filelo agregas al índice. Y cuando lo comprometes, también lo agregas al árbol.

Probablemente te ayudará a conocer las tres banderas más comunes en git reset:

git reset [- <mode>] [ <commit>]

Este formulario restablece el encabezado de la rama actual <commit>y posiblemente actualiza el índice (restableciéndolo al árbol de <commit>) y el árbol de trabajo según <mode>, que debe ser uno de los siguientes:
--soft

No toca el archivo de índice ni el árbol de trabajo en absoluto (pero reinicia la cabeza <commit>, al igual que todos los modos). Esto deja todos los archivos modificados "Cambios a confirmar", como lo indicaría el estado de git.

--mezclado

Restablece el índice pero no el árbol de trabajo (es decir, los archivos modificados se conservan pero no se marcan para confirmar) e informa lo que no se ha actualizado. Esta es la acción por defecto.

--difícil

Restablece el índice y el árbol de trabajo. Cualquier cambio en los archivos rastreados en el árbol de trabajo desde entonces <commit>se descarta.

Ahora, cuando hace algo como git reset HEAD: lo que realmente está haciendo es git reset HEAD --mixedy "restablecerá" el índice al estado que tenía antes de comenzar a agregar archivos / agregar modificaciones al índice (vía git add) En este caso, la copia de trabajo y el El índice (o la puesta en escena) estaban sincronizados, pero hizo que HEAD y el índice estuvieran sincronizados después del restablecimiento.

git rmpor otro lado, elimina un archivo del directorio de trabajo y del índice, y cuando confirma, el archivo también se elimina del árbol. git rm --cachedsin embargo, elimina el archivo solo del índice y lo mantiene en su copia de trabajo. Esto es exactamente lo contrario de git add file En este caso, hizo que el índice fuera diferente del HEAD y del trabajo, ya que HEAD tiene la versión previamente comprometida del archivo, la copia de trabajo tuvo la última modificación, si la hubo, o el contenido del HEAD de el archivo y eliminó el archivo del índice. Una confirmación ahora sincronizará el índice y el árbol y se eliminará el archivo.

manojlds
fuente
Noto que después git rm --cacheddel git diffcomando no muestra ningún diff, pero git diff --cachedmuestra el diff, como si todavía estuviera en caché. Sin git statusembargo, muestra el archivo como siendo Untracked. Parece un poco inconsistente.
haridsv
77
No importa ... debería haberlo usado git reset --mixed. Estaba un poco confundido por la afirmación que git rm --cachedes lo contrario de git add. Tomado literalmente, es incorrecto y podría causar daños. En mi caso, solía git addagregar un archivo modificado al área de preparación y quería lo opuesto a "ese agregado", no el agregado inicial del archivo. La respuesta de Greg Hewgill me ayudó a obtener una imagen más clara.
haridsv
12
Encuentro el uso de copia de trabajo, árbol y árbol de trabajo un poco confuso. ¿Es el árbol de trabajo la copia de trabajo o el árbol?
Nealv
3
Como @haridsv mencionó, decir git rm --cached'es exactamente lo contrario de git add file' es engañoso. git reset fileestá más cerca de ser lo contrario de git add file.
Matt Browne
@Nealv tardío, pero para otros que encuentran este hilo: la copia de trabajo, el árbol y el árbol de trabajo se refieren a lo mismo (en el contexto de git).
De Novo
83

Quizás un ejemplo ayude:

git rm --cached asd
git commit -m "the file asd is gone from the repository"

versus

git reset HEAD -- asd
git commit -m "the file asd remains in the repository"

Tenga en cuenta que si no ha cambiado nada más , la segunda confirmación en realidad no hará nada.

Greg Hewgill
fuente
3
¿Puedes decirme qué significa ese guión doble, después de que HEAD realmente significa?
Yuva
30
@yuva: --se utiliza para separar las opciones de comando de los nombres de archivo. Si hubiera una rama y un archivo con nombre asd, entonces git reset HEAD asdsería ambiguo. El --dice "todo lo que sigue a esto es un nombre de archivo".
Greg Hewgill
¿Es git reset HEAD <file>exactamente lo mismo que git rm --cached <file>y luego git add --intent-to-add <file>?
alcohol es malo
1
@alcoholisevil no, excepto en un caso especial. Vea esta excelente y sucinta respuesta.
De Novo
45

git rm --cached filese quite el archivo desde el escenario. Es decir, cuando confirme el archivo será eliminado. git reset HEAD -- filesimplemente restablecerá el archivo en el área de preparación al estado donde estaba en la confirmación HEAD, es decir, deshacerá cualquier cambio que haya realizado desde la última confirmación. Si ese cambio sucede al agregar nuevamente el archivo, entonces serán equivalentes.

yuriks
fuente
77
En conjunción con la noción (como se menciona en otras respuestas) que git rm --cached filees más o menos lo contrario git add, esta respuesta tenía mucho sentido para mí, y fue bastante sucinta. Casi tan corto como este comentario;)
rbatt
2
@rbatt solo para poner el comentario aquí también, y aclarar, git rm --cached fileno es lo contrario degit add file . El comportamiento es el opuesto git add fileal caso específico en el que ha agregado un archivo nuevo, previamente no rastreado. En cualquier otro caso, lo contrario de git add filees git reset HEAD file. git reset HEAD filetambién se invierte git add fileen el primer caso (agregar un archivo no rastreado), y en todos los casos, por eso es lo que git sugiere hacer si desea revertir un complemento de git.
De Novo