Значение двойных дефисов Git checkout

Что означают двойные дефисы перед именем файла в этой команде git?

git checkout --ours -- path/to/file.txt
git checkout --theirs -- path/to/file.txt

Они обязательны? Это эквивалентно

git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt

person mottalrd    schedule 10.11.2012    source источник
comment
Это выражение оболочки. См. unix.stackexchange.com/questions/11376/   -  person iltempo    schedule 10.11.2012
comment
@iltempo: В Git все немного по-другому. Для Git он отделяет дерево от путей в тех случаях, когда деревья и пути могут выглядеть одинаково.   -  person Dietrich Epp    schedule 10.11.2012
comment
@Dietrich_Epp. Я понимаю. Спасибо за разъяснения.   -  person iltempo    schedule 10.11.2012
comment
Также задокументировано в stackoverflow.com/a/1192194/6309   -  person VonC    schedule 23.05.2014
comment
Дубликат Разница между git checkout ‹filename› и git checkout - ‹Filename›   -  person    schedule 24.05.2014
comment
Это дубликат, но этот дубликат, по крайней мере, можно найти в Google по запросу 'git double dash'.   -  person thorn0    schedule 19.07.2014
comment
Добавление всего одного слова к сообщению timmcliu, чтобы прояснить его или ее значение: «Двойное тире - означает конец флагов командной строки, т.е. указывает предыдущей команде не пытаться анализировать то, что идет после как параметры командной строки. '   -  person S. Taylor    schedule 04.01.2019


Ответы (3)


Предположим, у меня есть файл с именем path/to/file.txt в моем репозитории Git, и я хочу отменить изменения в нем.

git checkout path/to/file.txt

Теперь предположим, что файл называется _3 _...

git checkout master

Ой! Вместо этого изменились ветки. Знак -- отделяет дерево, которое вы хотите извлечь, от файлов, которые вы хотите извлечь.

git checkout -- master

Также нам помогает, если какой-то урод добавил в наш репозиторий файл с именем -f:

git checkout -f      # wrong
git checkout -- -f   # right

Это задокументировано в git-checkout: устранение неоднозначности аргументов.

person Dietrich Epp    schedule 10.11.2012
comment
Это верно для многих команд bash, а не только для команд git, да? - person NHDaly; 14.11.2013
comment
@NHDaly: Да, это правда. Тем не менее, примечание по терминологии: Bash имеет только несколько команд (может быть, 20 или около того), большинство команд - это отдельные программы от Bash. Фактически это часть стандарта POSIX, что -- может использоваться для отделения параметров от других аргументов, поэтому вы увидите это в таких командах, как cp и mv (которые не являются частью Bash). - person Dietrich Epp; 14.11.2013
comment
Есть идеи, почему этот синтаксис неправильно описан в документации по команде checkout? - person TanguyP; 17.03.2016
comment
@TanguyP: похоже, это описано в верхней части git-scm.com/docs/git-checkout мне. - person Dietrich Epp; 17.03.2016
comment
@DietrichEpp В нескольких местах он указан как возможный параметр для команды checkout, но нигде в документации не объясняется, что он делает или почему он используется ... что в конечном итоге привело меня сюда. - person chris; 24.05.2016
comment
@chris: На самом деле это есть в документации. В синопсисе: git checkout [-p|--patch] [<tree-ish>] [--] [<paths>…​] [--] означает, что -- можно использовать, необязательно, для отделения дерева от путей. - person Dietrich Epp; 24.05.2016
comment
@DietrichEpp Верно, но, прочитав синтаксис (и примеры) перед тем, как перейти к Stack Overflow, я все еще не понял, почему можно или не хотелось бы использовать --. Для человека, не имеющего опыта работы с Linux, не совсем понятно, что он делает. Мне показалось, что это синтаксис, специфичный для git, без описания его функционального назначения. Я думаю, было бы лучше иметь краткое описание, как и другие варианты, или хотя бы ссылку на справочную страницу linux. - person chris; 25.05.2016
comment
@chris: Вы всегда можете обратиться к справочной странице man-страниц, которая объясняет соглашения для раздела синопсиса. Все, что в синопсисе не имеет смысла, обычно является просто частью синтаксиса команды, например --. man7.org/linux/man-pages/man7/man- pages.7.html - person Dietrich Epp; 25.05.2016
comment
@NHDaly только последняя часть, касающаяся устранения неоднозначности между опциями и позиционными аргументами, которые начинаются с -, в целом истинна. Использование -- для устранения неоднозначности между различными типами позиционных аргументов (например, древовидность и пути в случае git-checkout) довольно странно. Я никогда не слышал ни о чем, кроме git, который бы это делал. - person Laurence Gonsalves; 09.01.2017
comment
IMO эта проблема существует только потому, что проверка файлов и веток - это отдельные команды. - person Bas Peeters; 27.04.2019

Двойное тире «-» означает «конец флагов командной строки», то есть указывает предыдущей команде не пытаться анализировать то, что идет после параметров командной строки.

person timmcliu    schedule 05.03.2015
comment
Для ясности, в git это означает больше, чем это, так как это также означает, что аргумент после -- не может быть именем ветки, и косвенно аргумент перед -- не может быть путем к файлу. - person Gem Taylor; 18.09.2019

Обратите внимание, что вам не понадобится, поскольку Git 2.5 (2 квартал 2015 г.) a '--', если ваш аргумент включает подстановочный знак (*)

Эвристика, помогающая соглашению командной строки «git <cmd> <revs> <pathspec>» обнаруживать ошибочные пути, заключается в том, чтобы убедиться, что все параметры, не относящиеся к rev, в более поздней части командной строки являются именами файлов в рабочем дереве, но это означает «_ 4_ "всегда следует устранять с помощью" -- ", потому что никто в здравом уме не создаст файл, имя которого буквально это звездочка-точка-см.

Git 2.5 теряет эвристику, чтобы объявить, что с подстановочной строкой пользователь, вероятно, хотел дать нам путь.

git checkout 'a*'
# same as
git checkout -- 'a*'

См. commit 28fcc0b (2 мая 2015 г.) по Дуй Нгуен (nguyenlocduy).
(Объединено Junio ​​C Hamano - gitster - в фиксации 949d167, 19 мая 2015 г.)

pathspec: избегайте необходимости использовать "--" при использовании подстановочного знака

Когда в командной строке отсутствует "--" и команда может принимать как обороты, так и пути, идея заключается в том, что если аргумент может рассматриваться как как расширенный SHA-1, так и как путь, тогда требуется "--" или git отказывается продолжить.
В настоящее время он реализован как:

  • (1) если аргумент rev, то он не должен существовать в рабочем дереве
  • (2) иначе он должен существовать в рабочем дереве
  • (3) в противном случае требуется "--".

Эти правила работают для буквальных путей, но когда используется нелитеральный pathspec, почти всегда требуется, чтобы пользователь добавлял «--», потому что он терпит неудачу (2), а (1) действительно редко встречается (возьмите, например, «*.c», ( 1) выполняется, если имеется ссылка с именем "*.c").

Этот патч немного изменяет правила, учитывая, что любой допустимый (*) путь с подстановочными знаками "существует в рабочем дереве".
Правила становятся:

  • (1) если arg является rev, то он должен либо существовать в рабочем дереве, либо не быть допустимой спецификацией пути с подстановочными знаками.
  • (2) иначе он либо существует в рабочем дереве, либо представляет собой спецификацию пути с подстановочными знаками
  • (3) в противном случае требуется "--".

С новыми правилами "--" не требуется большую часть времени, когда используется подстановочный знак pathspec.


В Git 2.26 (первый квартал 2020 г.) логика устранения неоднозначности, позволяющая различать ревизии и спецификации пути, была изменена таким образом, что специальные символы glob с экранированием обратной косой черты не учитываются в правиле «подстановочные знаки являются указанием пути».

См. фиксацию 39e21c6 (25 января 2020 г.) по Джефф Кинг (peff).
(Объединено Junio ​​C Hamano - gitster - в совершить 341f8a6, 12 фев 2020)

verify_filename(): обрабатывать обратные косые черты в правиле "подстановочные знаки - это пути"

Автор сообщения: Дэвид Бурстрём
Автор сообщения: Джефф Кинг

Зафиксируйте 28fcc0b71a (pathspec: избегайте необходимости "--" при использовании подстановочного знака, 2015 г. -05-02) разрешено:

git rev-parse '*.c'

без двойного тире.

Но правило, которое он использует для проверки подстановочных знаков, на самом деле ищет любые особые глобусы.
Это слишком либерально, так как означает, что шаблон, который на самом деле не выполняет никаких подстановочных знаков, например "a\b", будет считаться указанием пути .

Если у вас есть такой файл на диске, вероятно, это то, что вы хотели.
Но если вы этого не сделаете, результаты будут сбивать с толку: вместо того, чтобы говорить «there's no such path a\b», мы спокойно примем его как путь, который, скорее всего, ничего не соответствует (или, по крайней мере, не тому, что вы планировали).
Аналогичным образом, поиск пути "a\*b" вообще не расширяет поиск; он найдет только одну запись "a*b".

Эта фиксация переключает правило на срабатывание только тогда, когда метасимволы глобуса расширяют поиск, что означает, что оба этих случая теперь сообщают об ошибке (вы все еще можете устранить неоднозначность, используя «--», конечно, мы просто усиливаем эвристику DWIM).

(DWIM: делай то, что я имею в виду)

Обратите внимание, что мы вообще не тестировали исходную функцию в 28fcc0b71a.
Таким образом, этот патч не только проверяет эти угловые случаи, но также добавляет регрессионный тест для существующего поведения.

person VonC    schedule 13.02.2020