Diferencia entre "git checkout <nombre de archivo>" y "git checkout - - <nombre de archivo>"

Respuestas:

214

La "opción" especial --significa "tratar cada argumento después de este punto como un nombre de archivo, sin importar cómo se vea". Esto no es específico de Git, es una convención general de línea de comandos de Unix. Normalmente lo usa para aclarar que un argumento es un nombre de archivo en lugar de una opción , por ejemplo

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

git checkout1 también --significa que los argumentos subsiguientes no son su parámetro opcional "en árbol" que especifica qué confirmación desea.

Entonces, en este contexto, es seguro usarlo --siempre, pero lo necesita cuando el archivo que desea revertir tiene un nombre que comienza con -, o es el mismo que el nombre de una rama. Algunos ejemplos de desambiguación de rama / archivo:

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"

y desambiguación de opciones / archivos:

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"

No estoy seguro de lo que debe hacer si tiene una sucursal cuyo nombre comienza con -. Quizás no hagas eso en primer lugar.


1 en este modo; "Checkout" también puede hacer varias otras cosas. Nunca he entendido por qué git eligió implementar "descartar cambios no confirmados" como un modo del subcomando "checkout", en lugar de "revertir" como la mayoría de los otros VCS, o "restablecer", que creo que podría tener más sentido en los propios términos de git.

zwol
fuente
12
git checkout <nombre> comprueba la rama <nombre>. git checkout - <nombre> busca la versión de índice del archivo <nombre>.
Dunni
3
Gracias, desafortunadamente la documentación de git realmente no explica esto
Carlton
1
Respecto a la "convención Unix": de hecho, --como separador entre opciones y argumentos está ampliamente implementado. Funciona para cualquier programa / utilidad que use POSIX getopt(3)para manejar sus opciones de línea de comando, (ver man 3 getopt), scripts de shell que usan getopt(1)y algunos programas que lo implementan ellos mismos, pero no está garantizado universalmente que funcione.
arielf
¡Ja! Simplemente leí un ejemplo de cómo descartar cambios de trabajo, habiendo olvidado ver esta convención en otros programas de línea de comandos, asumí que --significaba 'negar cambios' a la C / C ++, y lo he estado pensando desde entonces. ¡Alucinante!
underscore_d
Para personas como yo: no se confundan con el nombre maestro, se refiere al archivo llamado maestro y no a la rama.
HarsH
7

Todo lo que siga a --se trata como un nombre de archivo (no como un argumento de programa). Esto es importante si, por ejemplo, tiene nombres de archivo que comienzan con guiones.

jtbandes
fuente