Por que existem 2 maneiras de abrir um arquivo no git?

Às vezes o git sugere git rm --cached para abrir um ficheiro, às vezes git reset HEAD file. Quando devo usar o quê?

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
#
Author: Nick Volynkin, 2011-08-03

10 answers

git rm --cached <filePath> não remove um ficheiro, na verdade Escalona a remoção do(s) ficheiro (s) do repo (assumindo que já foi cometido antes), mas deixa o ficheiro na sua árvore de trabalho (deixando-o com um ficheiro sem rasto).

git reset -- <filePath> will unstage quaisquer alterações escalonadas para o(s) ficheiro (s) indicado (s).

Dito isto, se você usou git rm --cached em um novo arquivo que é encenado, basicamente pareceria que você tinha acabado de soltá-lo, uma vez que ele nunca tinha sido cometido antes.
 1454
Author: Ryan Stewart, 2018-08-06 13:45:31

git rm --cached é usado para remover um arquivo do Índice. No caso em que o arquivo já está no repo, git rm --cached irá remover o arquivo do Índice, deixando-o no diretório de trabalho e um commit irá agora removê-lo do repo também. Basicamente, após o commit, você teria desapertado o arquivo e mantido uma cópia local.

git reset HEAD file ( que por padrão está usando a bandeira --mixed é diferente no caso em que o arquivo já está no repo, ele substitui a versão de índice de o arquivo com o do repo (HEAD), efetivamente liberando as modificações para ele.

No caso de arquivo sem Versão, ele vai desatar o arquivo inteiro como o arquivo não estava lá na cabeça. Neste aspecto git reset HEAD file e git rm --cached são os mesmos, mas não são os mesmos ( como explicado no caso de arquivos já no repo)

Quanto à questão de ... nunca há realmente uma única maneira de fazer alguma coisa no git. essa é a beleza disto:)
 306
Author: manojlds, 2011-08-02 23:00:25

Muito simplesmente:

  • git rm --cached <file> faz com que o git pare de seguir o ficheiro completamente (deixando-o no sistema de Ficheiros, ao contrário do simples git rm*)
  • git reset HEAD <file> remove todas as modificações feitas no ficheiro desde o último commit (mas não as reverte no sistema de Ficheiros, ao contrário do que o nome do comando possa sugerir**). O arquivo permanece sob controle de revisão.

Se o ficheiro não estava no controlo de revisões antes (ou seja, está a desbloquear um ficheiro que você tinha apenas git add ed pela primeira vez), então os dois comandos têm o mesmo efeito, daí o aparecimento destes ser "duas maneiras de fazer algo".

* tenha em mente a caveat @DrewT menciona em sua resposta, a respeito de git rm --cached de um arquivo que foi previamente comprometido para o repositório. No contexto desta questão, de um arquivo apenas adicionado e ainda não comprometido, não há nada com que se preocupar.

** fiquei com medo durante muito tempo. o comando git reset por causa de seu nome -- e ainda hoje eu frequentemente procuro a sintaxe para me certificar de que não faço asneira. (update : finalmente tive tempo para resumir o uso de git reset numa página do tldr , por isso agora tenho um modelo mental melhor de como funciona, e uma referência rápida para quando me esqueço de algum detalhe.)

 94
Author: waldyrious, 2016-11-04 10:54:10

Este tópico é um pouco velho, mas eu ainda quero adicionar um pouco de demonstração uma vez que ainda não é um 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 (Sem -q) dá um aviso sobre o arquivo modificado e seu código de saída é 1 que será considerado como um erro em um script.

Editar: git checkout HEAD to-be-modified to-be-removed também funciona para o 'unstaging', mas remove a mudança completamente do espaço de trabalho

 38
Author: Daniel Alder, 2018-03-04 07:27:03

Se tiver encenado acidentalmente ficheiros que não gostaria de enviar, e quiser ter a certeza de que mantém as alterações, também pode usar:

git stash
git stash pop

Isto efectua um reset à cabeça e volta a aplicar as suas alterações, permitindo-lhe reestabelecer os ficheiros individuais para a persistência. isto também é útil se você se esqueceu de criar um ramo de recursos para pedidos de pull (git stash ; git checkout -b <feature> ; git stash pop).

 27
Author: ives, 2015-09-17 01:26:28

Estes 2 comandos têm várias diferenças subtis se o ficheiro em questão já estiver no repo e sob controlo de versão (anteriormente comprometido, etc.):

  • git reset HEAD <file> desvia o ficheiro na persistência actual.
  • git rm --cached <file> irá abrir o ficheiro para os commits futuros também. É instável até ser adicionado novamente com git add <file>.
E há mais uma diferença importante:
  • Depois de correr {[[1] } e empurrar o seu ramo para o comando, qualquer um puxando a sua ramificação do remoto irá obter o ficheiro realmente apagado da sua pasta, mesmo que no seu conjunto de trabalho local o ficheiro fique sem rasto (ou seja, não fisicamente apagado da pasta).

Esta última diferença é importante para os projectos que incluem um ficheiro de configuração em que cada programador da equipa tem uma configuração diferente (isto é, uma configuração diferente de url de base, ip ou porto) por isso, se estiver a usar git rm --cached <file> Qualquer pessoa que puxe a sua ramificação terá de recriar manualmente a configuração, ou você pode enviar-lhes o seu e eles podem re-editá-lo de volta para suas configurações de ip (etc.), porque o delete apenas efeitos pessoas puxando seu ramo do controle remoto.

 15
Author: DrewT, 2014-08-19 04:10:06

Digamos que você stage uma pasta inteira via git add <folder>, mas você quer excluir um ficheiro da lista encenada (ou seja, a lista que gera ao executar git status) e manter as modificações dentro do ficheiro excluído (você estava a trabalhar em algo e não está pronto para cometer, mas não quer perder o seu trabalho...). Você poderia simplesmente usar:

git reset <file>

Quando você executar git status, você verá que qualquer arquivo que você reset são unstaged e o resto dos arquivos que você added ainda estão na lista.

 8
Author: jiminikiz, 2015-08-28 16:08:05

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 --Cache ..."para soltar)

  • Git é um sistema de ponteiros

  • Você não tem um commit ainda para mudar o seu ponteiro para

  • A única maneira de 'tirar os ficheiros do balde que está a ser apontado' é para remover os ficheiros que disse ao git para vigiar as alterações

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

  • tu vieste, 'salvo'

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 soltar)

  • fizeste um commit no teu código neste momento
  • Agora você pode reiniciar o seu cursor para o seu commit 'volte para a última gravação'
 7
Author: Timothy L.J. Stewart, 2016-09-08 16:26:07
Surpreende-me que ninguém tenha mencionado o Git reflog. http://git-scm.com/docs/git-reflog):
# git reflog
<find the place before your staged anything>
# git reset HEAD@{1}

O reflog é um histórico git que não só acompanha as alterações ao repo, mas também acompanha as acções do utilizador (por exemplo. pull, checkout para branch diferente, etc) e permite desfazer essas ações. Então, em vez de desamarrar o arquivo que foi mal encenado, onde você pode reverter para o ponto onde você não encenou os arquivos.

Isto é semelhante a git reset HEAD <file> mas em certos casos pode ser mais granular.

Desculpa , não estou a responder à tua pergunta, mas estou a apontar outra forma de desbloquear ficheiros que uso muitas vezes (eu gosto muito das respostas do Ryan Stewart e do waldyrious.);) Espero que ajude.
 5
Author: Alex, 2015-02-10 12:06:40

Parece-me que git rm --cached <file> remove o ficheiro do Índice sem o remover do directório onde um plain git rm <file> faria ambas as coisas, tal como um OS rm <file> removeria o ficheiro do directório sem remover a sua versionagem.

 3
Author: ernie.cordell, 2014-01-24 10:55:30