Pregunta ¿Por qué hay 2 formas de descomprimir un archivo en git?


A veces, Git sugiere git rm --cached para dejar de grabar un archivo, a veces git reset HEAD file. ¿Cuándo debería usar cuál?

EDITAR:

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
#

833
2017-08-02 21:50


origen


Respuestas:


git rm --cached <filePath>  no deja de funcionar un archivo, en realidad etapas de la eliminación del archivo (s) del repositorio (suponiendo que ya se haya comprometido antes) pero deja el archivo en su árbol de trabajo (dejándolo con un archivo sin seguimiento).

git reset <filePath> será unstage cualquier cambio por etapas para el (los) archivo (s) dado (s).

Dicho eso, si usaste git rm --cached en un nuevo archivo que está en etapas, básicamente se vería como si acabara de desglosarlo, ya que nunca se había cometido antes.


1361
2017-08-02 22:03



git rm --cached se usa para eliminar un archivo del índice. En el caso donde el archivo ya está en el repositorio, git rm --cached eliminará el archivo del índice, dejándolo en el directorio de trabajo y una confirmación ahora lo eliminará del repositorio también. Básicamente, después de la confirmación, habría descompuesto el archivo y conservado una copia local.

git reset HEAD file (que de forma predeterminada está usando el --mixed flag) es diferente en el caso en que el archivo ya se encuentra en el repositorio, reemplaza la versión de índice del archivo con la del repositorio (HEAD), lo que hace modificaciones lo.

En el caso de un archivo no versionado, va a desempatar el archivo completo ya que el archivo no estaba allí en HEAD. En este aspecto git reset HEAD file y git rm --cached son iguales, pero no son iguales (como se explicó 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? - Realmente, nunca hay una sola manera de hacer algo en git. esa es la belleza de eso :)


303
2017-08-02 23:00



Muy simple:

  • git rm --cached <file>  hace que git deje de seguir el archivo por completo (dejándolo en el sistema de archivos, a diferencia de git rm*)
  • git reset HEAD <file>  borra las modificaciones realizadas en el archivo desde la última confirmación (pero no los 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á desestabilizando un archivo que acaba de editar git added por primera vez), los dos comandos tienen el mismo efecto, por lo tanto, la apariencia de estos son "dos formas de hacer algo".

* Tenga en cuenta la advertencia @DrewT menciona en su respuesta, con respecto a git rm --cached de un archivo que era previamente comprometido al repositorio. En el contexto de esta pregunta, de un archivo recién agregado y aún no comprometido, no hay nada de qué preocuparse.

** Tenía miedo por un tiempo embarazosamente largo de usar el comando de reinicio de git por su nombre, y aún hoy a menudo busco la sintaxis para asegurarme de no arruinarlo. (actualizar: Finalmente 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 me olvido de algunos detalles).


86
2017-10-17 21:16



Este hilo es un poco viejo, pero aún quiero agregar una pequeña demostración ya que todavía no es un problema intuitivo:

me$ git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#   new file:   to-be-added
#   modified:   to-be-modified
#   deleted:    to-be-removed
#

me$ git reset -q HEAD to-be-added

    # ok

me$ git reset -q HEAD to-be-modified

    # ok

me$ git reset -q HEAD to-be-removed

    # ok

# or alternatively:

me$ git reset -q HEAD to-be-added to-be-removed to-be-modified

    # ok

me$ git status
# On branch master
# Changes not staged for commit:
#   (use "git add/rm <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#   modified:   to-be-modified
#   deleted:    to-be-removed
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   to-be-added
no changes added to commit (use "git add" and/or "git commit -a")

git reset HEAD(sin -q) da una advertencia sobre el archivo modificado y su código de salida es 1, que se considerará como un error en un script.

Editar: git checkout HEAD to-be-modified to-be-removed también funciona para desestabilizar, pero elimina el cambio completamente del área de trabajo


35
2018-04-16 19:00



Si ha almacenado accidentalmente archivos que no desea comprometer, y desea estar seguro de que conserva los cambios, también puede usar:

git stash
git stash pop

esto realiza un reinicio en HEAD y vuelve a aplicar los cambios, lo que le permite volver a organizar los archivos individuales para la confirmación. esto también es útil si olvidó crear una rama de características para solicitudes de extracción (git stash ; git checkout -b <feature> ; git stash pop)


27
2018-02-10 17:06



Estos 2 comandos tienen varias diferencias sutiles si el archivo en cuestión ya está en el repositorio y bajo el control de la versión (previamente cometido, etc.):

  • git reset HEAD <file> Desempaqueta el archivo en la confirmación actual.
  • git rm --cached <file> también desestabilizará el archivo para futuros commits. No está en escena hasta que se agrega de nuevo con git add <file>.

Y hay una diferencia más importante:

  • despues de correr git rm --cached <file> y empuje su rama hacia el control remoto, cualquiera que saque su rama del control remoto obtendrá el archivo ACTUALMENTE borrado de su carpeta, aunque en su conjunto de trabajo local, el archivo simplemente no se rastrea (es decir, no se borra físicamente de la carpeta).

Esta última diferencia es importante para los proyectos que incluyen un archivo de configuración en el que cada desarrollador del equipo tiene una configuración diferente (es decir, diferente url base, ip o configuración de puerto) por lo que si está utilizando git rm --cached <file> cualquiera que extraiga su sucursal tendrá que volver a crear manualmente la configuración, o puede enviar la suya y puede volver a editarla a su configuración de IP (etc.), porque la eliminación solo afecta a las personas que extraen su sucursal del control remoto. .


14
2017-08-10 20:04



Digamos que stage un directorio completo a través de git add <folder>, pero desea excluir un archivo de la lista por etapas (es decir, la lista que se genera al ejecutar git status) y mantener las modificaciones dentro del archivo excluido (estaba trabajando en algo y no está listo para la confirmación, pero no quiere perder su trabajo ...). Simplemente puedes usar:

git reset <file>

Cuando corres git status, verá que sea cual sea el archivo (s) que reset son unstaged y el resto de los archivos que added todavía están en el staged lista.


8
2017-08-28 16:08



1.

D:\code\gt2>git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#       new file:   a

(use "git rm --cached ..." para abandonar la escena)

  • git es un sistema de punteros

  • usted todavía no tiene un compromiso para cambiar su puntero a

  • la única forma de 'sacar archivos de la cubeta a la que se apunta' es eliminar los archivos que le indicó a git para ver los cambios

2.

D:\code\gt2>git commit -m a
[master (root-commit) c271e05] a
0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 a

git commit -m a

  • usted se comprometió 'salvado'

3.

D:\code\gt2>git status
# On branch master
# Changes to be committed:
#   (use "git reset HEAD <file>..." to unstage)
#
#       new file:   b
#

(use "git reset HEAD ..." para salir del escenario)

  • hiciste una confirmación en tu código en este momento
  • ahora puedes restablecer tu puntero a tu compromiso 'volver al último guardado'

6
2017-09-08 16:26



Me sorprende que nadie mencionó el git reflog (http://git-scm.com/docs/git-reflog)

# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

El reflog es un historial de git que no solo hace un seguimiento de los cambios en el repositorio, sino que también rastrea las acciones del usuario (por ejemplo, extracción, pago a diferentes sucursales, etc.) y permite deshacer esas acciones. Por lo tanto, en lugar de desestabilizar el archivo que se configuró erróneamente, puede volver al punto en el que no realizó la etapa de los archivos.

Esto es similar a git reset HEAD <file> pero en ciertos casos puede ser más granular.

Lo siento, no estoy respondiendo realmente su pregunta, sino que estoy señalando otra manera de deshacer archivos que uso bastante a menudo (por ejemplo, me gustan las respuestas de Ryan Stewart y Waldyrious);) Espero que ayude.


5
2018-02-10 12:06



Me parece que git rm --cached <file> elimina el archivo del índice sin eliminarlo del directorio donde aparece un archivo git rm <file> haría las dos cosas, como un sistema operativo rm <file> eliminaría el archivo del directorio sin eliminar su versión.


3