git add * (gwiazdka) vs git add. (Kropka)

131

Jestem nowy w git i mam pytanie dotyczące dodawania plików w git. Znalazłem wiele pytań stackoverflow o różnicy między git add .i git add -a, git add --all, git add -A, itd. Ale byłem w stanie znaleźć miejsce, które wyjaśnia co git add *robi. Przejrzałem nawet stronę podręcznika git add , ale to nie pomogło. Używałem go zamiast git add .i mój współpracownik zapytał mnie, dlaczego. Nie miałem odpowiedzi. Po prostu zawsze używałem git add *.

Czy git add .i git add *to samo? Czy jeden dodaje zmienione pliki tylko z bieżącego katalogu, a drugi dodaje pliki z bieżącego katalogu i podkatalogów (rekurencyjnie)?

Na jednym z pozostałych pytań dotyczących stosu znajduje się świetny wykres, który pokazuje różnicę między git add -A git add .i git add -u, ale tak nie jest git add *.

wprowadź opis obrazu tutaj

Uwaga: rozumiem, co to znaczy używać gwiazdki jako symbolu wieloznacznego (dodaj wszystkie pliki z podanym rozszerzeniem). Na przykład, git add *.htmlby dodać wszystkie pliki, które mają .htmlrozszerzenie (ale ignorują .css, .jsitp).

Dzięki za pomoc!

Tyler Youngblood
źródło
1
Skąd jest ten wykres? Po prostu spróbowałem git add .ponownie i bez problemu umieściłem usunięty plik, w przeciwieństwie do Xsugerowanego w tym wierszu.
David,
@David Ten obraz pochodzi z tej odpowiedzi i dotyczy starszych wersji gita.
Jerry
4
Zdjęcie nieaktualne! Git 2.x jest inny: i.stack.imgur.com/KwOLu.jpg
Hannes Schneidermayer

Odpowiedzi:

133

add *oznacza dodanie wszystkich plików w bieżącym katalogu, z wyjątkiem plików, których nazwa zaczyna się od kropki. To jest twoja funkcja powłoki, a Git zawsze otrzymuje listę plików.

add . nie ma specjalnego znaczenia w twojej powłoce, dlatego Git dodaje rekurencyjnie cały katalog, który jest prawie taki sam, ale obejmuje pliki, których nazwy zaczynają się od kropki.

Denis
źródło
6
więc git add .dodaje wszystkie pliki, foldery i podfoldery, w tym .gitignore i wszystko inne zaczynające się od kropki, a jednocześnie git add *dodaje pliki, foldery i podfoldery, z wyjątkiem tych zaczynających się kropką? Czy to jest dokładne?
Tyler Youngblood
9
To jest rzeczywiście poprawne. Ponadto git add *nadal będzie dodawać pliki zaczynające się od kropki, jeśli znajdują się w podkatalogu.
Denis
4
git add .szanuje również .gitignore, podczas gdy git add *zgłosi błąd, jeśli jakiekolwiek pliki inne niż kropki zostaną poddane gitignore. O wiele lepiej git add .niż git add *.
rosuav
2
Warto zauważyć: jeśli wywołujesz Git w DOS / Windows z CMD.EXE, to Git , a nie powłoka, rozwija rozszerzenie *. W tym przypadku Git znajdzie pliki z kropkami.
torek
2
@ Thor84no: Git znajdzie pliki z kropkami nawet w systemie Linux, jeśli zacytujesz znak, *aby chronić go przed powłoką. Nie jest to kwestia ukrytego fragmentu, po prostu różnią się zasady wkompilowania Gita.
torek
30

*nie jest częścią git - jest to symbol wieloznaczny interpretowany przez powłokę. *rozwija się do wszystkich plików w bieżącym katalogu i dopiero wtedy jest przekazywany do git, który addjest nimi wszystkimi. .jest samym bieżącym katalogiem i git adddoda go i wszystkie znajdujące się w nim pliki.

Mureinik
źródło
1
Czy byłby więc każdy powód, aby użyć gwiazdki? Czy jest jakaś korzyść z używania go zamiast kropki? Lub odwrotnie? Jestem pewien, że widziałem to w samouczku. W przeciwnym razie nie wiedziałbym, jak go używać. Nie jestem zbyt dobrym facetem z linii poleceń (jak niewątpliwie się domyślasz).
Tyler Youngblood
5
*unika ukrytych plików (tj. plików, których nazwa zaczyna się od a .). W każdym razie, jeśli nie dodajesz określonych plików, po prostu użyję git add -u(lub git add -Ajeśli tworzysz nowe pliki).
Mureinik
3
Ponieważ oboje odpowiedzieliście na moje pytanie, miałem problem z podjęciem decyzji, komu dać kredyt. Wybrałem Denisa poniżej, ponieważ ma mniejszą reputację niż ty. Więc pomyślałem, że danie mu zielonego czeku przyniesie mu więcej korzyści niż ciebie. Mam nadzieję, że to ma sens? Ale naprawdę doceniam oba wyjaśnienia. Dzięki!
Tyler Youngblood
7

Użycie kropki . w powłoce zwykle oznacza „bieżący katalog”.

Gdy używasz gwiazdki *na powłoce, file-globbingużywana jest funkcja o nazwie . Np. Na bash funkcja właśnie glob()to robi. Strona podręcznika dla glob ( man 7 glob) stwierdza:

OPIS

Long ago, in UNIX V6, there was a program /etc/glob that would expand 
wildcard patterns.  Soon afterward this became a shell built-in.
These days there is also a library routine glob(3) that will perform this 
function for a user program.

Dopasowywanie symboli wieloznacznych

A string is a wildcard pattern  if it contains one of the characters '?', '*' or '['. 

Globbing

Globbing is the operation that expands a wildcard pattern 
into the list of pathnames matching the pattern.

To znaczy, kiedy przekazywać argumenty do dowolnego programu w linii poleceń, które zawierają '?', '*'lub '['najpierw masek rozszerza wieloznaczny wzór na liście plików, a następnie daje te pliki jako argument do samego programu.

Różnica w znaczeniu między 'git add .'i 'git add *'jest wyraźnie opisana przez Denisa :

git addoczekuje listy plików do dodania. W powyższym przykładzie powłoka rozwija się odpowiednio *lub .i podaje wynik jako parametr do dodania git. Teraz różnica polega na tym, że z git add .git rozwija się do bieżącego katalogu, podczas gdy git add *wyzwala globowanie plików i takie rozwija się do wszystkich plików i katalogów, które nie zaczynają się kropką.

codingdave
źródło
5

Dla jasności umieściłem odpowiedź w poniższej tabeli:

wprowadź opis obrazu tutaj

Dodatkowe uwagi (inspirowane komentarzem @ reka18):

Uwaga 1. git add -A a git add -ukomendy wykonywane bez dodatkowych parametrów byłyby dodatkowym uściśleniem (wskazaniem podkatalogu lub maski dla nazwy pliku) działającym w zakresie całego katalogu roboczego (także jeśli wykonamy polecenie w podkatalogu roboczym katalogu).

Uwaga 2.. i *są odpowiednio ścieżkę katalogu (katalog bieżący) i wieloznaczny, który wyjaśnienia ścieżkę polecenia. Na przykład, jeśli polecenie git add .lub git add *jest wykonywane w jakimś podkatalogu katalogu roboczego, ich akcja jest używana tylko w tym podkatalogu, a nie w całym katalogu roboczym.

Uwaga 3.git add -A i git add -upolecenia mogą być dalej udoskonalane przez dodanie ścieżki lub maski plików, na przykład, git add -A app/controllersalbo git add -u app\styles\*.

simhumileco
źródło
3
A więc od wersji Git v2.x git add -Ai git add .są identyczne?
reka18
Dziękuję @ reka18 za bardzo dobre pytanie. Zainspirowało mnie to do dokończenia mojej odpowiedzi ... Odpowiedź na twoje pytanie: jeśli wywołasz to w katalogu roboczym, nie, ale jeśli w podkatalogu, to tak ( git add -Adotyczy całego katalogu roboczego i git add .zawsze katalogu bieżącego).
simhumileco
2
  • git add -A (--all) Dodaje wszystko, dzięki czemu wszystko w twoim folderze na dysku jest reprezentowane w obszarze przemieszczania

  • git add . Przechowuje wszystko, ale nie usuwa plików, które zostały usunięte z dysku

  • git add * Etapuje wszystko, ale nie pliki zaczynające się od kropki i nie usuwa plików, które zostały usunięte z dysku

  • git add -u (--update) Przechowuje tylko zmodyfikowane pliki, usuwa pliki, które zostały usunięte z dysku, nie dodaje nowych

  • git add <file name 1> <file name 2> Dodaje tylko określone pliki

Steffen
źródło