Jaka jest różnica między głową, drzewem roboczym i indeksem w Git?

Może mi ktoś powiedzieć jaka jest różnica między głową, drzewem roboczym a indeksem w Git?

Z tego co rozumiem, to wszystkie nazwy dla różnych gałęzi. Czy moje założenie jest prawidłowe?


Edytuj

Znalazłem to

Pojedyncze repozytorium git może śledzić dowolną liczbę gałęzi, ale drzewo robocze jest powiązane tylko z jedną z nich (gałąź" current "lub" checked out"), a HEAD wskazuje na tę gałąź.

Robi to znaczy, że głowa i drzewo robocze są zawsze takie same?

Author: nbro, 2010-09-11

5 answers

Kilka innych dobrych odniesień na te tematy:

workflow

Używam indeksu jako punktu kontrolnego .

Kiedy mam zamiar dokonać zmiany, która może pójść na marne - kiedy chcę zbadać jakiś kierunek, w którym nie jestem pewien, czy mogę kontynuować, czy nawet czy jest to dobry pomysł, taki jak konceptualnie wymagająca refaktoryzacja lub zmiana typu reprezentacji-sprawdzam mój pracuj nad indeksem.

Jeśli jest to moja pierwsza zmiana od ostatniego commita, mogę użyć lokalnego repozytorium jako punktu kontrolnego, ale często mam jedną zmianę koncepcyjną, którą wdrażam jako zestaw małych kroków.
Chcę sprawdzić po każdym kroku, ale Zapisz commit, dopóki nie wrócę do pracy, przetestowany kod.

Uwagi:

  1. Workspace jest drzewem katalogów (źródłowych) plików, które widzisz i edycja.

  2. Indeks jest pojedynczym, dużym, binarnym plikiem w <baseOfRepo>/.git/index, który wyświetla wszystkie pliki w bieżącej gałęzi, ich sumy kontrolne sha1 , znaczniki czasu i nazwę pliku-nie jest to kolejny katalog z kopią plików w nim.

  3. Repozytorium lokalne

    jest ukrytym katalogiem (.git) zawierającym katalog objects zawierający wszystkie wersje KAŻDEGO pliku w repo (lokalne gałęzie i kopie zdalnych gałęzi) jako skompresowany plik "blob".

Nie myśl o czterech "dyskach" przedstawionych na powyższym obrazku jako oddzielnych kopiach plików repo.

3 Stany

Są one w zasadzie nazwane referencjami dla commitów Gita. Istnieją dwa główne typy refów: tagi i głowy.

  • znaczniki są stałymi odniesieniami które zaznaczają konkretny punkt w historii, na przykład v2. 6. 29.
  • [14]}wręcz przeciwnie, głowy są zawsze przesuwane, aby odzwierciedlić obecną pozycję rozwoju projektu.

committs

(Uwaga: Jak skomentował przez Timo Huovinen , te strzałki nie są tym, na co wskazują commity, jest to kolejność pracy , zasadniczo pokazując strzałki jako 1 -> 2 -> 3 -> 4 Gdzie 1 jest pierwszym commitem, a 4 ostatnim)

Teraz wiemy, co dzieje się w projekcie.
Ale aby wiedzieć, co się dzieje tutaj, w tej chwili jest specjalne odniesienie zwane głową. Służy dwóm głównym celom:

  • mówi Gitowi, który commit ma pobierać pliki z kiedy dokonujesz zakupu, oraz
  • mówi Gitowi, gdzie umieścić nowe commity podczas zatwierdzania.

Po uruchomieniu git checkout ref wskazuje HEAD na ref, który wyznaczyłeś i wyciąga z niego pliki. Po uruchomieniu git commit tworzy nowy obiekt commit, który staje się potomkiem prądu HEAD. Normalnie HEAD wskazuje na jedną z głów, więc wszystko działa dobrze.

checkout

 621
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-11-28 21:37:32

Różnica pomiędzy HEAD (bieżąca gałąź lub ostatni oddany stan na bieżącej gałęzi), index (aka. staging area) I working tree (Stan Plików w kasie) jest opisany w "the Three States" w rozdziale "1.3 Git Basics" książki Pro Git Scotta Chacona (Licencja Creative Commons).

Oto obraz ilustrujący go z tego rozdziału:

Operacje lokalne-working directory vs. staging area (index) vs Git repository (HEAD)

W powyższym obrazek "working directory" jest taki sam jak "working tree", "staging area" jest alternatywną nazwą dla git "index", a HEAD wskazuje na aktualnie sprawdzoną gałąź, która wskazuje na ostatni commit w " katalogu git (repozytorium)"

Zauważ, że git commit -a wprowadzi zmiany i zatwierdzi w jednym kroku.

 146
Author: Jakub Narębski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-02 14:01:59

Twojedrzewo robocze jest tym, co w rzeczywistości znajduje się w plikach, nad którymi aktualnie pracujesz.

HEAD jest wskaźnikiem do gałęzi lub zatwierdzonego commita, który będzie rodzicem nowego zatwierdzonego commita, jeśli go utworzysz. Na przykład, jeśli znajdujesz się w gałęzi master, to HEAD wskaże master, a kiedy zatwierdzisz nowy commit będzie potomkiem rewizji, na którą wskazałeś master, A master zostanie zaktualizowany, aby wskazać na nowy / align = "left" /

Indeks jest miejscem postoju, w którym przygotowywany jest nowy commit. Zasadniczo, zawartość indeksu jest tym, co trafi do nowego commita (choć jeśli zrobisz git commit -a, automatycznie doda to wszystkie zmiany do plików, które Git wie o indeksie przed zatwierdzeniem, więc zatwierdzi bieżącą zawartość Twojego drzewa roboczego). git add doda lub zaktualizuje pliki z drzewa roboczego do indeksu.

 72
Author: Brian Campbell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-08 19:06:33

Drzewo robocze

Twoje drzewo robocze to pliki, nad którymi aktualnie pracujesz.

Indeks Git

  • Git "index" to miejsce, w którym umieszczasz pliki, które chcesz zatwierdzić w repozytorium git.

  • Indeks jest również znany jako cache, pamięć podręczna katalogu, current directory cache, miejsce postoju, pliki wystawione .

  • Zanim "zatwierdzisz" (checkin) pliki do repozytorium git, musisz najpierw umieść pliki w git "index".

  • Indeks jest , a nie katalogiem roboczym: możesz wpisać polecenie takie jak git status, a git powie Ci, które pliki w Twoim katalogu roboczym zostały dodane do indeksu git (na przykład, używając polecenia git add filename).

  • Indeks nie jest repozytorium git: pliki w indeksie git to pliki, które git zatwierdziłby do repozytorium git, jeśli użyłbyś polecenia git commit.

 52
Author: Ashraf Alam,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-06-07 08:29:07

Jest to nieuchronnie długie, ale łatwe do naśladowania Wyjaśnienie z Księgi ProGit:

Uwaga: w celach informacyjnych można przeczytać rozdział 7.7 książki, Reset Demystified

Git jako system zarządza i manipuluje trzema drzewami w swoim normalnym działaniu:]}
  • HEAD: Last commit snapshot, next parent
  • Index: Proposed next commit snapshot
  • Katalog Roboczy: Piaskownica

Głowa

HEAD jest wskaźnikiem do bieżącego odniesienia do gałęzi , który z kolei jest wskaźnikiem do ostatniego commitu dokonanego na tej gałęzi . Oznacza to, że HEAD będzie rodzicem następnego commita, który zostanie utworzony . Ogólnie najprościej jest myśleć o HEAD jako o migawce Twojego ostatniego commita na tej gałęzi .

Co zawiera?
Aby zobaczyć jak wygląda ta migawka Uruchom poniżej w katalogu głównym repozytorium:

                                 git ls-tree -r HEAD

Spowodowałoby to coś takiego:

                       $ git ls-tree -r HEAD  
                       100644 blob a906cb2a4a904a152... README  
                       100644 blob 8f94139338f9404f2... Rakefile  
                       040000 tree 99f1a6d12cb4b6f19... lib  

Indeks

Git zapełnia ten indeks listą wszystkich plików, które były ostatnio pobierane do twojego katalogu roboczego i jak wyglądały, kiedy były pobierane. Następnie zamieniasz niektóre z tych plików na nowe wersje, a git commit konwertuje je na drzewo dla nowego commita.

Co robi zawiera?
Użyj git ls-files -s , aby zobaczyć, jak to wygląda. Powinieneś zobaczyć coś takiego:

                 100644 a906cb2a4a904a152e80877d4088654daad0c859 0 README   
                 100644 8f94139338f9404f26296befa88755fc2598c289 0 Rakefile  
                 100644 47c6340d6459e05787f644c2447d2595f5d3a54b 0 lib/simplegit.rb  

Katalog Roboczy

To miejsce, w którym znajdują się Twoje pliki i gdzie możesz wypróbować zmiany przed zatwierdzeniem ich do obszaru przejściowego (indeksu), a następnie do historii.

Wizualizowana Próbka

Zobaczmy, jak te trzy drzewa (jak odnosi się do nich Księga ProGit) współpracują ze sobą?
Typowym przepływem pracy Git jest nagrywanie migawek Twój projekt w sukcesywnie lepszych Stanach, manipulując tymi trzema drzewami. Spójrz na to zdjęcie:

Tutaj wpisz opis obrazka

Aby uzyskać dobre zwizualizowane zrozumienie rozważ ten scenariusz. Powiedzmy, że wejdziesz do nowego katalogu z pojedynczym plikiem. Nazwij to v1 pliku. Jest oznaczony kolorem niebieskim. Uruchomienie git init spowoduje utworzenie repozytorium Git z referencją HEAD, która wskazuje na unborn master branch

Tutaj wpisz opis obrazka

W tym momencie, tylko drzewo katalogów roboczych zawiera dowolną zawartość. Teraz chcemy zatwierdzić Ten plik, więc używamy git add, Aby pobrać zawartość z katalogu roboczego i skopiować ją do indeksu.

Tutaj wpisz opis obrazka

Następnie uruchamiamy git commit, który pobiera zawartość indeksu i zapisuje go jako stałą migawkę, tworzy obiekt commit, który wskazuje na tę migawkę i aktualizuje master, aby wskazywał na tę zmianę.

Tutaj wpisz opis obrazka

Jeśli uruchomimy git status, zobaczymy żadnych zmian , ponieważ wszystkie trzy drzewa są takie same.

Piękny punkt

Git status pokazuje różnicę pomiędzy tymi drzewami w następujący sposób:

  • jeśli drzewo robocze różni się od indeksu, to git status pokaże istnieją pewne zmiany, które nie są wystawiane dla commit
  • jeśli drzewo robocze jest takie samo jak index, ale różni się od HEAD, to git status wyświetli niektóre pliki w sekcji zmiany do zatwierdzenia w jego wynik
  • jeśli drzewo robocze różni się od indeksu, A Indeks od nagłówka, to git status wyświetli niektóre pliki w sekcji zmiany, które nie zostały wystawione dla sekcji commit oraz inne pliki w sekcji zmiany, które mają zostać zatwierdzone.

Dla ciekawszych

Uwaga o komendzie git reset
Miejmy nadzieję, że wiedza o tym, jak działa reset Komenda, jeszcze bardziej rozjaśni przyczynę istnienie tych trzech drzew.

reset command to Twój Wehikuł czasu w git, który może z łatwością cofnąć się w czasie i przynieść kilka starych migawek do pracy. W ten sposób głowa jest tunelem czasoprzestrzennym, przez który możesz podróżować w czasie. Zobaczmy, jak to działa na przykładzie z książki:

Rozważmy następujące repozytorium, które ma jeden plik i 3 commity, które są wyświetlane w różnych kolorach i różnych wersjach liczby:

Tutaj wpisz opis obrazka

Stan drzew jest jak na następnym zdjęciu:

Tutaj wpisz opis obrazka

Krok 1: ruchoma głowa (--miękka):

Pierwszą rzeczą, jaką zrobi reset, będzie przesunięcie tego, co HEAD wskaże. To nie to samo, co sama zmiana głowicy (czyli to, co robi checkout). reset przesuwa gałąź, na którą wskazuje Głowa. Oznacza to, że jeśli HEAD jest ustawiony na gałąź master, uruchomienie git reset 9e5e6a4 rozpocznie się od wprowadzenia punktu master do 9e5e6a4. Jeśli wywołanie reset z opcją --soft zatrzyma się tutaj, bez zmiany index i working directory. Nasz repo będzie teraz wyglądał tak:
Uwaga: HEAD ~ jest rodzicem HEAD

Tutaj wpisz opis obrazka

Patrząc po raz drugi na obrazek, widzimy, że polecenie zasadniczo usunęło ostatni commit. Ponieważ drzewo robocze i indeks są takie same, ale różnią się od głowy, git status pokaże teraz zmiany w kolorze zielonym gotowe do zaangażowania.

Krok 2: Aktualizacja indeks (--mieszany):

jest to domyślna opcja polecenia

Uruchamiając reset z opcją --mixed aktualizuje Indeks z zawartością dowolnego elementu migawki, na który wskazuje aktualnie, pozostawiając katalog roboczy nienaruszony. W ten sposób twoje repozytorium będzie wyglądało tak, jak wtedy, gdy wykonałeś jakąś pracę, która nie jest wystawiona, a git status pokaże to jako zmiany nie wystawione dla commit na Czerwono. Ta opcja cofnie również ostatnią zmianę i usunie wszystkie zmiany. On tak jak zrobiłeś zmiany, ale nie wywołałeś jeszcze git add polecenia. Nasz repo wyglądałby teraz tak:

Tutaj wpisz opis obrazka

Krok 3: aktualizacja katalogu roboczego (--hard)

Jeśli wywołasz reset z opcją --hard, skopiuje ona zawartość głowicy migawki skierowanej do HEAD, index i katalogu roboczego. Po wykonaniu polecenia reset -- hard, oznaczałoby to, że wróciłeś do poprzedniego punktu w czasie i nic nie zrobiłeś po tym w ogóle. Zobacz zdjęcie poniżej:

Tutaj wpisz opis obrazka

wniosek

Mam nadzieję, że teraz masz lepsze zrozumienie tych drzew i masz świetny pomysł na moc, którą przynoszą Ci, umożliwiając zmianę plików w repozytorium, aby cofnąć lub ponowić rzeczy, które zrobiłeś błędnie.

 14
Author: Mehdi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2021-01-19 07:44:27