Разница между «git checkout <имя файла>» и «git checkout - - <имя файла>»

Ответы:

215

Специальная «опция» --означает «обрабатывать каждый аргумент после этой точки как имя файла, независимо от того, как он выглядит». Это не зависит от Git, это общее соглашение командной строки Unix. Обычно вы используете его, чтобы пояснить, что аргумент - это имя файла, а не параметр , например

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

git checkout1 также --означает, что последующие аргументы не являются его необязательным «древовидным» параметром, определяющим, какой коммит вы хотите.

Так что в этом контексте безопасно использовать --всегда, но вам это нужно, когда файл, который вы хотите восстановить, имеет имя, которое начинается с -или совпадает с именем ветки. Некоторые примеры разрешения неоднозначности ветки / файла:

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"

и значение параметра / файла:

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"

Я не знаю, что делать, если у вас есть ветка , имя которой начинается с -. Возможно, не делайте этого в первую очередь.


1 в этом режиме; "checkout" может делать и несколько других вещей. Я никогда не понимал, почему git решил реализовать «отменить незафиксированные изменения» в качестве режима подкоманды «checkout», а не «вернуться», как большинство других VCS, или «сбросить», что, как мне кажется, могло бы иметь больше смысла в терминах git.

zwol
источник
12
git checkout <name> проверяет ветку <name>. git checkout - <имя> проверяет индексную версию файла <имя>.
dunni
3
Спасибо, к сожалению, документация git этого не объясняет
Carlton
1
Что касается «соглашения Unix»: действительно, --широко применяется разделитель между параметрами и аргументами. Он работает с любой программой / утилитой, которая использует POSIX getopt(3)для обработки своих параметров командной строки (см. man 3 getopt), Сценариев оболочки, которые используют getopt(1), и некоторых программ, которые реализуют его сами, но не всегда гарантируется работа.
arielf
Хах! Я просто прочитал пример назад, когда о том, как отказаться от рабочих изменений, забыв увидеть это соглашение в других программах командной строки, предположил, что это --означает «отменить изменения» а-ля C / C ++ - и с тех пор думал об этом. С ума сойти!
underscore_d
Для людей вроде меня: не запутайтесь, называя master, он имеет в виду файл с именем master, а не ветку.
HarsH
7

Все, что следует за --символом, рассматривается как имя файла (а не как аргумент программы). Это важно, если, например, у вас есть имена файлов, начинающиеся с тире.

jtbandes
источник