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?
5 answers
Kilka innych dobrych odniesień na te tematy:
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:
Workspace jest drzewem katalogów (źródłowych) plików, które widzisz i edycja.
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.- Repozytorium lokalne
jest ukrytym katalogiem (
.git
) zawierającym katalogobjects
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.
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.
(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
wskazujeHEAD
na ref, który wyznaczyłeś i wyciąga z niego pliki. Po uruchomieniugit commit
tworzy nowy obiekt commit, który staje się potomkiem prąduHEAD
. NormalnieHEAD
wskazuje na jedną z głów, więc wszystko działa dobrze.
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:
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.
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.
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 poleceniagit 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.
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:
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
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.
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ę.
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:
Stan drzew jest jak na następnym zdjęciu:
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
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:
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:
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.
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