Różnica między „git checkout <nazwa pliku>” a „git checkout - - <nazwa pliku>”

Odpowiedzi:

214

Specjalna „opcja” --oznacza „traktuj każdy argument po tym punkcie jako nazwę pliku, bez względu na to, jak to wygląda”. To nie jest specyficzne dla Gita, jest to ogólna konwencja wiersza poleceń Uniksa. Zwykle używa się go do wyjaśnienia, że ​​argument jest nazwą pliku, a nie opcją , np

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

git checkout1 wykonuje również --oznaczać, że kolejne argumenty nie są jego opcjonalny parametr „treeish” Określanie które zobowiązują chcesz.

W tym kontekście zawsze można go bezpiecznie używać --, ale potrzebujesz go, gdy plik, który chcesz przywrócić, ma nazwę rozpoczynającą się od -lub taką samą jak nazwa gałęzi. Kilka przykładów ujednoznacznienia gałęzi / pliku:

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"

i ujednoznacznienie opcji / pliku:

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"

Nie jestem pewien, co robisz, jeśli masz oddział, którego nazwa zaczyna się od -. Może w ogóle tego nie rób.


1 w tym trybie; „Kasa” może też zrobić kilka innych rzeczy. Nigdy nie rozumiałem, dlaczego git zdecydował się na zaimplementowanie „odrzucania niezatwierdzonych zmian” jako trybu podkomendy „checkout” zamiast „cofania”, jak większość innych VCS, lub „resetowania”, co moim zdaniem mogłoby mieć więcej sensu w terminach gita.

zwol
źródło
12
git checkout <nazwa> sprawdza gałąź <nazwa>. git checkout - <nazwa> sprawdza indeksową wersję pliku <nazwa>.
dunni,
3
Dzięki, niestety dokumentacja gita tak naprawdę tego nie wyjaśnia
Carlton,
1
Odnośnie „Konwencji uniksowej”: rzeczywiście, --jako separator między opcjami a argumentami jest szeroko stosowany. Działa dla każdego programu / narzędzia, które używa POSIX getopt(3)do obsługi opcji wiersza poleceń (zobacz man 3 getopt), skryptów powłoki, które używają getopt(1)i niektórych programów, które implementują go samodzielnie, ale nie ma uniwersalnej gwarancji działania.
arielf
Hah! Po prostu przeczytałem przykład dawno temu, jak odrzucić działające zmiany, zapomniawszy o tej konwencji w innych programach wiersza poleceń, założyłem, że --oznacza to „negowanie zmian” a la C / C ++ - i od tamtej pory tak myślałem. Niesamowite!
underscore_d
Dla ludzi takich jak ja: nie dajcie się zmylić przez nazwę master, ma na myśli plik o nazwie master, a nie gałąź.
HarsH
7

Wszystko następujące po znaku --jest traktowane jako nazwa pliku (nie jako argument programu). Jest to ważne, jeśli na przykład masz nazwy plików zaczynające się od myślników.

jtbandes
źródło