Znaczenie podwójnych kresek w kasie Git

274

Co oznaczają podwójne myślniki przed nazwą pliku w tym poleceniu git?

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

Czy są obowiązkowe? Czy to jest równoważne z

git checkout --ours path/to/file.txt
git checkout --theirs path/to/file.txt
mottalrd
źródło
24
To wyrażenie powłoki. Zobacz unix.stackexchange.com/questions/11376/…
iltempo,
15
@iltempo: W Git jest nieco inaczej. W przypadku Git oddziela drzewo od ścieżek, w przypadku gdy drzewa i ścieżki mogą wyglądać tak samo.
Dietrich Epp,
@Dietrich_Epp. Widzę. Dzięki za wytłumaczenie.
iltempo
Udokumentowane również w stackoverflow.com/a/1192194/6309
VonC
3
Jest to duplikat, ale ten duplikat jest przynajmniej googleable przez zapytanie „git double dash”.
thorn̈

Odpowiedzi:

376

Załóżmy, że mam plik o nazwie path/to/file.txtw moim repozytorium Git i chcę przywrócić w nim zmiany.

git checkout path/to/file.txt

Załóżmy teraz, że plik ma nazwę master...

git checkout master

Ups! To zamiast tego zmieniło gałęzie. W --oddziela drzewo chcesz sprawdzić z plików, które chcesz sprawdzić.

git checkout -- master

Pomaga nam również, jeśli jakiś dziwak dodał plik o nazwie -fdo naszego repozytorium:

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

Jest to udokumentowane w git-checkout: Argument Disambiguation .

Dietrich Epp
źródło
12
Dotyczy to wielu poleceń bash, nie tylko poleceń git, tak?
NHDaly,
40
@NHDaly: Tak, to prawda. Jednak uwaga terminologiczna: „Bash” ma tylko kilka poleceń (może około 20), większość poleceń to programy inne niż Bash. Jest to właściwie część standardu POSIX, którego --można użyć do oddzielenia opcji od innych argumentów, więc zobaczysz to w poleceniach takich jak cpi mv(które nie są częścią Bash).
Dietrich Epp
6
Masz pojęcie, dlaczego ta składnia nie jest poprawnie opisana w checkoutdokumentacji polecenia?
TanguyP,
4
@DietrichEpp W kilku miejscach jest wymieniony jako możliwy parametr do checkoutpolecenia, ale dokumentacja nigdzie nie wyjaśnia, co robi ani dlaczego jest używany ... co ostatecznie mnie tu sprowadziło.
Chris
7
@DietrichEpp Prawidłowo, ale po przeczytaniu składni (i przykładów) przed przyjściem do przepełnienia stosu, nadal nie rozumiem, dlaczego ktoś chce lub nie chce używać --. Jako ktoś, kto nie pochodzi z Linuksa, nie jest oczywiste, co to robi. Wydawało mi się, że jest to składnia specyficzna dla git, bez opisu jego funkcjonalnego celu. Myślę, że lepiej byłoby mieć krótki opis, podobnie jak inne opcje, lub przynajmniej link do strony podręcznika systemu Linux .
Chris
109

Podwójny myślnik „-” oznacza „flagi końca wiersza poleceń”, tzn. Informuje poprzednie polecenie, aby nie próbowało analizować tego, co następuje po opcjach wiersza poleceń.

timmcliu
źródło
2
Dla jasności gitoznacza to więcej niż to, ponieważ oznacza również argument po nazwie --nie może być nazwą gałęzi, a przez to argument przedtem --nie może być ścieżką do pliku.
Gem Taylor,
0

Zauważ, że nie byłbyś potrzebny, ponieważ Git 2.5 (Q2 2015) a ' --', jeśli twój argument zawiera znak wieloznaczny ( *)

Heurystyką, która pomaga git <cmd> <revs> <pathspec>konwencji wiersza poleceń w przechwytywaniu źle wpisanych ścieżek, jest upewnienie się, że wszystkie parametry non-rev w dalszej części wiersza poleceń to nazwy plików w działającym drzewie, ale to oznacza, że git grep $str -- \*.czawsze musi być „ ” niejednoznaczny z „ --”, ponieważ nikt rozsądny nie utworzy pliku, którego nazwa dosłownie brzmi gwiazdka-kropka-zobacz.

Git 2.5 traci heurystykę, aby zadeklarować, że za pomocą łańcucha wieloznacznego użytkownik prawdopodobnie chciałby podać nam ścieżkę .

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

Zobacz commit 28fcc0b (02 maja 2015) autorstwa Duy Nguyen ( nguyenlocduy) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 949d167 , 19 maja 2015)

pathspec: unikaj potrzeby używania „ --”, gdy używany jest symbol wieloznaczny

Gdy --brakuje wiersza „ ” z wiersza poleceń, a polecenie może pobierać zarówno obroty, jak i ścieżki, chodzi o to, że jeśli argument może być postrzegany zarówno jako rozszerzony SHA-1, jak i ścieżka, wówczas --wymagane jest „ ” lub git odmawia kontynuowania.
Obecnie jest wdrażany jako:

  • (1) jeśli argumentem jest rev, to nie może istnieć w drzewie roboczym
  • (2) w przeciwnym razie musi istnieć w drzewie roboczym
  • (3) w przeciwnym --razie wymagane jest „ ”.

Reguły te działają w przypadku ścieżek dosłownych, ale gdy w grę wchodzi niematerialna specyfikacja ścieżki, prawie zawsze wymaga dodania przez użytkownika „ --”, ponieważ zawodzi (2) i (1) jest naprawdę rzadko spotykane (weź „ *.c”, na przykład (1) jest spełnione, jeśli istnieje odwołanie o nazwie „ *.c”).

Ta poprawka nieco modyfikuje reguły, biorąc pod uwagę, że dowolny prawidłowy ( *) symbol ścieżki zastępczej „istnieje w drzewie roboczym”.
Reguły stają się:

  • (1) jeśli arg jest wersją, to musi albo istnieć w drzewie roboczym, albo nie może być poprawnym typem ścieżki wieloznacznej.
  • (2) w przeciwnym razie istnieje on w drzewie roboczym lub jest ścieżką określającą symbol wieloznaczny
  • (3) w przeciwnym --razie wymagane jest „ ”.

Dzięki nowym regułom „ --” nie jest potrzebne przez większość czasu, gdy w grę wchodzi ścieżka wieloznaczna.


W Git 2.26 (Q1 2020) logika ujednoznacznienia odróżniająca wersje i rozróżnienie ścieżek została zmieniona, tak aby globalne znaki specjalne, które uniknęły odwrotnego ukośnika, nie były uwzględniane w regule „symbole wieloznaczne są ścieżkami”.

Zobacz zatwierdzenie 39e21c6 (25 stycznia 2020 r.) Przez Jeff King ( peff) .
(Połączone przez Junio ​​C Hamano - gitster- w commit 341f8a6 , 12 lutego 2020)

verify_filename(): obsłużyć ukośniki odwrotne w regule „symbole wieloznaczne są ścieżkami”

Zgłoszony przez: David Burström
Podpisany przez: Jeff King

Zatwierdź 28fcc0b71a ( pathspec: unikaj potrzeby używania „ --”, gdy używana jest symbol wieloznaczny, 02.05.2015) dozwolone:

git rev-parse '*.c'

bez podwójnej kreski.

Ale reguła, której używa do sprawdzania symboli wieloznacznych, faktycznie szuka jakiejś specjalnej oferty globalnej.
Jest to zbyt liberalne, ponieważ oznacza, że ​​wzorzec, który w rzeczywistości nie dopasowuje symboli wieloznacznych, taki jak „ a\b”, będzie uważany za rodzaj ścieżki.

Jeśli masz taki plik na dysku, prawdopodobnie tego właśnie chciałeś.
Ale jeśli tego nie zrobisz, wyniki są mylące: zamiast powiedzieć „ there's no such path a\b”, spokojnie zaakceptujemy go jako ścieżkę, która najprawdopodobniej nie pasuje do niczego (a przynajmniej nie do tego, co zamierzałeś).
Podobnie szukanie ścieżki „ a\*b” wcale nie rozszerza wyszukiwania; znalazłby tylko jeden wpis „ a*b”.

To zatwierdzenie przełącza regułę tak, aby wyzwalała się tylko wtedy, gdy globalne metaznaki rozszerzyłyby wyszukiwanie, co oznacza, że ​​oba te przypadki będą teraz zgłaszać błąd (nadal możesz jednoznacznie za pomocą „ --”, oczywiście; po prostu zaostrzamy heurystykę DWIM).

( DWIM: Rób, co mam na myśli )

Pamiętaj, że w ogóle nie testowaliśmy oryginalnej funkcji w 28fcc0b71a .
Ta poprawka nie tylko testuje te narożne przypadki, ale także dodaje test regresji dla istniejącego zachowania.

VonC
źródło