Diferença entre “git checkout <filename>” e “git checkout - - <filename>”


Respostas:


214

A "opção" especial --significa "tratar cada argumento após este ponto como um nome de arquivo, não importa sua aparência." Isso não é específico do Git, é uma convenção geral de linha de comando do Unix. Normalmente você o usa para esclarecer que um argumento é um nome de arquivo em vez de uma opção , por exemplo

rm -f      # does nothing
rm -- -f   # deletes a file named "-f"

git checkout1 também --significa que os argumentos subsequentes não são seu parâmetro opcional "em árvore" especificando qual commit você deseja.

Portanto, neste contexto, é seguro usar --sempre, mas você precisa dele quando o arquivo que deseja reverter tem um nome que começa com -, ou é igual ao nome de um branch. Alguns exemplos para desambiguação de branch / arquivo:

git checkout README     # would normally discard uncommitted changes
                        # to the _file_ "README"

git checkout master     # would normally switch the working copy to
                        # the _branch_ "master"

git checkout -- master  # discard uncommitted changes to the _file_ "master"

e desambiguação de opção / arquivo:

git checkout -p -- README  # interactively discard uncommitted changes
                           # to the file "README"

git checkout -- -p README  # unconditionally discard all uncommitted
                           # changes to the files "-p" and "README"

Não tenho certeza do que você faz se tiver uma filial cujo nome começa com -. Talvez não faça isso em primeiro lugar.


1 neste modo; "checkout" pode fazer várias outras coisas também. Eu nunca entendi por que o git escolheu implementar "descartar alterações não confirmadas" como um modo do subcomando "checkout", em vez de "reverter" como a maioria dos outros VCSes, ou "redefinir", o que acho que pode fazer mais sentido nos termos do próprio git.


12
git checkout <name> verifica o branch <name>. git checkout - <name> verifica a versão do índice do arquivo <name>.
— Dunni

3
Obrigado, infelizmente a documentação do git não explica isso
— Carlton

1
Em relação à "convenção Unix": na verdade, --como um separador entre opções e argumentos é amplamente implementado. Ele funciona para qualquer programa / utilitário que use POSIX getopt(3)para lidar com suas opções de linha de comando (consulte man 3 getoptRecursos), scripts de shell que usam getopt(1)e alguns programas que os implementam, mas não é universalmente garantido que funcione.
— arielf

Hah! Eu simplesmente li um exemplo de como descartar as alterações de trabalho, tendo esquecido de ver essa convenção em outros programas de linha de comando, assumido que --significava 'negar alterações' a la C / C ++ - e tenho pensado nisso desde então. Mente estourada!
— sublinhado_d

Para pessoas como eu: não se confunda com o nome master, ele significa arquivo denominado master e não o branch.
— HarsH

7

Qualquer coisa após o --é tratada como um nome de arquivo (não como um argumento de programa). Isso é importante se, por exemplo, você tiver nomes de arquivo que começam com travessões.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.