¿Por qué hay dos formas de eliminar un archivo en Git?
A veces, git sugiere git rm --cached
eliminar un archivo, a veces git reset HEAD file
. ¿Cuándo debo usar cuál?
D:\code\gt2>git init
Initialized empty Git repository in D:/code/gt2/.git/
D:\code\gt2>touch a
D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# a
nothing added to commit but untracked files present (use "git add" to track)
D:\code\gt2>git add a
D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use "git rm --cached <file>..." to unstage)
#
# new file: a
#
D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-)
create mode 100644 a
D:\code\gt2>touch b
D:\code\gt2>git status
# On branch master
# Untracked files:
# (use "git add <file>..." to include in what will be committed)
#
# b
nothing added to commit but untracked files present (use "git add" to track)
D:\code\gt2>git add b
D:\code\gt2>git status
# On branch master
# Changes to be committed:
# (use "git reset HEAD <file>..." to unstage)
#
# new file: b
#
git rm --cached <filePath>
no elimina la etapa de un archivo, en realidad organiza la eliminación de los archivos del repositorio (asumiendo que ya se confirmaron antes) pero deja el archivo en su árbol de trabajo (dejándolo con un archivo sin seguimiento).
git reset -- <filePath>
eliminará cualquier cambio preparado para los archivos dados.
Dicho esto, si usó git rm --cached
un archivo nuevo preparado, básicamente parecería que lo acaba de eliminar ya que nunca antes se había confirmado.
Actualización de git 2.24
En esta versión más nueva de git puedes usar git restore --staged
en lugar de git reset
. Ver documentos de git .
git rm --cached
se utiliza para eliminar un archivo del índice. En el caso de que el archivo ya esté en el repositorio, git rm --cached
lo eliminará del índice, lo dejará en el directorio de trabajo y una confirmación ahora también lo eliminará del repositorio. Básicamente, después de la confirmación, habría desversionado el archivo y habría conservado una copia local.
git reset HEAD file
(que de forma predeterminada usa la --mixed
bandera) es diferente en el sentido de que, en el caso de que el archivo ya esté en el repositorio, reemplaza la versión de índice del archivo con la del repositorio (HEAD), eliminando efectivamente las modificaciones del mismo.
En el caso de un archivo sin versión, se eliminará todo el archivo ya que el archivo no estaba en el HEAD. En este aspecto git reset HEAD file
y git rm --cached
son iguales, pero no son iguales (como se explica en el caso de los archivos que ya están en el repositorio)
A la pregunta de Why are there 2 ways to unstage a file in git?
: en realidad, nunca existe una sola forma de hacer algo en git. esa es la belleza de esto :)
Muy simple:
git rm --cached <file>
hace que git deje de rastrear el archivo por completo (dejándolo en el sistema de archivos, a diferencia del simplegit rm
*)git reset HEAD <file>
deshace cualquier modificación realizada en el archivo desde la última confirmación (pero no las revierte en el sistema de archivos, al contrario de lo que podría sugerir el nombre del comando**). El archivo permanece bajo control de revisión.
Si el archivo no estaba en control de revisión antes (es decir, está eliminando un archivo que acababa de git add
editar por primera vez), entonces los dos comandos tienen el mismo efecto, de ahí la apariencia de que son "dos formas de hacer algo". ".
* Tenga en cuenta la advertencia que @DrewT menciona en su respuesta con respecto git rm --cached
a un archivo que se envió previamente al repositorio. En el contexto de esta pregunta, de un archivo recién agregado y aún no confirmado, no hay nada de qué preocuparse.
** Tuve miedo durante un tiempo vergonzosamente largo de usar el comando git reset debido a su nombre, y todavía hoy busco a menudo la sintaxis para asegurarme de no equivocarme. ( actualización : finalmente me tomé el tiempo para resumir el uso de git reset
en una página tldr , así que ahora tengo un mejor modelo mental de cómo funciona y una referencia rápida para cuando olvido algún detalle).