Значення подвійних тире в Gout checkout


274

Яке значення подвійних тире перед назвою файлу в цій команді 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

24
Це вираз оболонки. Дивіться unix.stackexchange.com/questions/11376/…
iltempo

15
@iltempo: Це трохи інше для Git. Для Git він відділяє дерево від стежок у випадках, коли дерева та доріжки можуть виглядати однаково.
Дітріх Епп

@Dietrich_Epp. Я бачу. Дякуємо за уточнення.
iltempo

Також задокументовано в stackoverflow.com/a/1192194/6309
VonC

3
Це дублікат, але цей примірник є принаймні googleable за запитом "git double cash".
thorn̈

Відповіді:


376

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

git checkout path/to/file.txt

Тепер припустимо, що файл названо master...

git checkout master

Ого! Це замість цього змінило гілки. У --роз'єднує дерево ви хочете перевірити з файлів , які ви хочете перевірити.

git checkout -- master

Це також допомагає нам, якщо якийсь freako додав файл -fдо нашого сховища:

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

Це задокументовано в git-checkout: Розбіжність аргументів .


12
Це справедливо для багатьох команд bash, а не лише git-команд, так?
NHDaly

40
@NHDaly: Так, це правда. Однак термінологічна примітка: "Bash" має лише кілька команд (можливо, 20 або більше), більшість команд - це окремі програми від Bash. Це фактично частина стандарту POSIX, яку --можна використовувати для відокремлення параметрів від інших аргументів, тому ви побачите це в таких командах, як cpі mv(які не є частиною Bash).
Дітріх Епп

6
Будь-яка ідея, чому цей синтаксис не описаний належним чином у checkoutдокументації на команду?
TanguyP

4
@DietrichEpp У кількох місцях він перераховується як можливий параметр checkoutкоманди, але ніде документація не пояснює, що вона робить або для чого вона використовується ... що саме в кінцевому рахунку привело мене сюди.
chris

7
@DietrichEpp Правильно, але прочитавши синтаксис (та приклади) перед тим, як прийти до переповнення стека, я все ще не зрозумів, чому можна чи не хотів би використовувати --. Як хтось, хто не походить з linux фону, не очевидно, що це робить. Для мене, здавалося, це синтаксис, характерний для git, без опису його функціонального призначення. Я думаю, було б краще мати короткий опис, як інші параметри, або принаймні посилання на сторінку man linux .
chris

109

Подвійний тире "-" означає "кінець прапорів командного рядка", тобто він повідомляє попередній команді не намагатися аналізувати те, що відбувається після параметрів командного рядка.


2
Для наочності gitце означає більше, ніж це, оскільки це також означає аргумент після того, як --не може бути ім'ям гілки, і, як наслідок, аргумент раніше --не може бути шлях до файлу.
Джем Тейлор

0

Зауважте, що вам це не знадобиться, оскільки Git 2.5 (Q2 2015) a ' --', якщо ваш аргумент включає підстановку ( *)

Евристика, яка допомагає git <cmd> <revs> <pathspec>конвенції командного рядка вловлювати помилково прокладені шляхи, - це переконатися, що всі незворотні параметри в пізнішій частині командного рядка є іменами файлів у робочому дереві, але це означає, що " git grep $str -- \*.c" має бути завжди розмежовано з " --", тому що ніхто здоровий не створить файл, ім'я якого буквально є зірочкою-dot-see.

Git 2.5 втрачає евристику, щоб заявити, що за допомогою рядка підстановки користувач, ймовірно, мав намір дати нам проспект шляху .

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

Див. Комісію 28fcc0b (02 травня 2015 р.) Від Duy Nguyen ( nguyenlocduy) .
(Об'єднано Хуніо С Хамано - gitster- у комітеті 949d167 , 19 травня 2015 р.)

pathspec: уникайте необхідності " --" під час використання wildcard

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

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

Ці правила працюють для буквальних шляхів, але коли задіяна нелітеральна перспектива, він майже завжди вимагає від користувача додавання " --", оскільки він не вдається (2) і (1) дійсно рідко зустрічається ( *.cнаприклад, " ", наприклад, (1) зустрічається, якщо є посилання " *.c").

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

  • (1) якщо аргумент є оборотом, то він повинен або існувати в робочому дереві, або не бути дійсним простую схему.
  • (2) в іншому випадку вона або існує в робочому дереві, або є простою схемою магістра
  • (3) інше, " --" потрібно.

З новими правилами, " --" не потрібен більшу частину часу, коли бере участь масова карта проспекту.


У Git 2.26 (Q1 2020) логіка розрізнення, що стосується перегляду змін і pathspec, була розроблена таким чином, що спеціальні символи глобусу, що вийшли з косої риски, не враховуються в правилі "макіяж символів - це шлях проспекту".

Див. Комітет 39e21c6 (25 січня 2020 р.) Джеффа Кінга ( peff) .
(Об'єднав Хуніо С Хамано - 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 .
Тож цей виправлення не тільки перевіряє ці кутові випадки, але й додає тест регресії на існуючу поведінку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.