Widzisz dokumentację Gita, mówiącą coś takiego
Oddział musi zostać całkowicie scalony w HEAD.
Ale czym HEADdokładnie jest Git ?
Widzisz dokumentację Gita, mówiącą coś takiego
Oddział musi zostać całkowicie scalony w HEAD.
Ale czym HEADdokładnie jest Git ?
Odpowiedzi:
Możesz myśleć o HEAD jako o „bieżącej gałęzi”. Po zmianie gałęzi za git checkoutpomocą zmiany HEAD zmienia się tak, aby wskazywała wierzchołek nowej gałęzi.
Możesz zobaczyć, na co wskazuje HEAD, wykonując:
cat .git/HEAD
W moim przypadku wynikiem jest:
$ cat .git/HEAD
ref: refs/heads/master
HEAD może odwoływać się do konkretnej wersji, która nie jest powiązana z nazwą oddziału. Ta sytuacja nazywa się odłączoną HEAD .
Aby zacytować inne osoby :
Głowa jest po prostu odniesieniem do obiektu zatwierdzenia. Każda głowa ma nazwę (nazwa oddziału lub nazwa znacznika itp.). Domyślnie w każdym repozytorium znajduje się nagłówek o nazwie master. Repozytorium może zawierać dowolną liczbę głów. W danym momencie jedna głowa jest wybierana jako „aktualna głowa”. Ta głowa jest pseudonimem HEAD, zawsze wielkimi literami ”.
Zwróć uwagę na tę różnicę: „głowa” (małe litery) oznacza dowolną z nazwanych głów w repozytorium; „HEAD” (wielkie litery) odnosi się wyłącznie do aktualnie aktywnej głowy. To rozróżnienie jest często używane w dokumentacji Git.
Kolejne dobre źródło, które szybko omawia wewnętrzne działanie git (i dla lepszego zrozumienia head / HEAD) można znaleźć tutaj . Referencje (ref :) lub głowy lub gałęzie można traktować jak notatki post-it naklejone na zatwierdzenia w historii zmian. Zazwyczaj wskazują na końcówkę serii zatwierdzeń, ale można je przenosić za pomocą git checkoutlub git resetitp.
git checkout HEAD~2), który nie jest identyfikatorem zatwierdzenia znanej głowy. Bardziej szczegółowe wyjaśnienia znajdują się w artykule na eagain.net/articles/git-for-computer-scientists .
git revertjest to jednak dobry przykład przesunięcia gałęzi, aby nie znajdowała się na końcu, ponieważ git revertpo prostu tworzy nowe zatwierdzenia i wciąż pozostawia bieżącą gałąź na (nowej) końcówce.
commitreset
Polecam tę definicję twórcy github Scottowi Chaconowi [ referencje wideo ]:
Głowa jest twoją obecną gałęzią. Jest to symboliczne odniesienie. Jest to odniesienie do oddziału. Zawsze masz HEAD, ale HEAD będzie wskazywał na jeden z tych innych wskaźników, na jedną z gałęzi, na której jesteś. Jest rodzicem twojego następnego zatwierdzenia. To powinno być to, co było ostatnio wyewidencjonowane w twoim katalogu roboczym ... To jest ostatni znany stan twojego katalogu roboczego.
Cały film będzie uczciwym wprowadzeniem do całego systemu git, więc polecam również obejrzenie go, jeśli masz na to czas.
HEAD to tylko specjalny wskaźnik, który wskazuje lokalny oddział, w którym aktualnie się znajdujesz.
Z książki Pro Git , rozdział 3.1 Git Rozgałęzienie - Oddziały w pigułce , w sekcji Tworzenie nowego oddziału :
Co się stanie, jeśli utworzysz nowy oddział? Cóż, zrobienie tego tworzy nowy wskaźnik do poruszania się. Załóżmy, że tworzysz nowy oddział o nazwie testowanie. Robisz to za pomocą polecenia git branch:
$ git branch testingSpowoduje to utworzenie nowego wskaźnika przy tym samym zatwierdzeniu, w którym aktualnie jesteś
Skąd Git wie, w której branży aktualnie jesteś? Zachowuje specjalny wskaźnik o nazwie HEAD. Zauważ, że jest to coś zupełnie innego niż koncepcja HEAD w innych VCS, do których możesz być przyzwyczajony, takich jak Subversion lub CVS. W Git jest to wskaźnik do lokalnego oddziału, w którym aktualnie się znajdujesz. W tym przypadku nadal jesteś mistrzem. Polecenie git branch utworzyło tylko nową gałąź - nie przełączyło się na tę gałąź.
34ac2w powyższym przykładzie, teraz HEAD wskazywałby na to zatwierdzenie i nazywa się HEAD odłączonym. W tym stanie możesz także wprowadzać zmiany, eksperymentować i zatwierdzać zmiany, ale po przejściu do innej gałęzi stracisz wszystkie zmiany, chyba że oczywiście utworzysz nową gałąź.
git logi dostałeś coś takiego commit ad0265... HEAD -> foo ..., oznaczałoby to, że foogałąź jest referencją do zatwierdzenia id ad0265. Wykonanie kasy odwołania do tekstu foonie jest odłączoną głową. Wykonanie kasy identyfikatora zatwierdzenia ad0265spowoduje odłączenie głowy. Być może brakuje mi subtelności tego, co komunikujesz. Mam nadzieję, że ta ściana tekstu pomoże odkryć, gdzie się zgubiłem.
Zakładając, że nie jest to szczególny przypadek zwany „odłączoną GŁOWĄ”, to, jak stwierdzono w książce O'Reilly Git, 2. wydanie, str. 69, HEADoznacza:
HEADzawsze odnosi się do ostatniego zatwierdzenia w bieżącym oddziale. Po zmianie oddziałówHEADjest aktualizowany w celu odniesienia do ostatniego zatwierdzenia nowego oddziału.
więc
HEADjest „wskazówką” bieżącej gałęzi .
Zauważ, że możemy użyć, HEADaby odwoływać się do ostatniego zatwierdzenia, i użyć HEAD~jako zatwierdzenie przed wskazówką, HEAD~~lub HEAD~2jako zatwierdzenie nawet wcześniej, i tak dalej.
Istnieje pewna subtelna, ale ważna nieporozumienie w szeregu tych odpowiedzi. Myślałem, że dodam swoją odpowiedź, aby to wyjaśnić.
Co to jest
HEAD?
HEADjest symbolicznym odniesieniem wskazującym, gdziekolwiek jesteś w swojej historii zatwierdzeń. Podąża za tobą, gdziekolwiek jesteś, cokolwiek robisz, jak cień. Jeśli dokonasz zatwierdzenia, HEADprzeniesie się. Jeśli coś kasy, HEADprzeniesie się. Cokolwiek zrobisz, jeśli przeprowadziłeś się gdzieś nowy w swojej historii zatwierdzeń, HEADposzedłeś razem z tobą. Aby rozwiązać jeden powszechny nieporozumienie: nie możesz się oderwać HEAD. Nie taki jest stan odłączonej HEAD. Jeśli kiedykolwiek pomyślisz: „och nie, jestem w stanie HEAD odłączonym! Zgubiłem HEAD!” Pamiętaj, to twoja GŁOWA. GŁOWA to ty. Nie odłączyłeś się od HEAD, ty i HEAD odłączyliście się od czegoś innego.
HEADmoże wskazywać na zatwierdzenie, tak, ale zazwyczaj nie. Pozwól mi to powtórzyć. Zazwyczaj HEADnie wskazuje na zatwierdzenie. Wskazuje odwołanie do gałęzi. Jest dołączony do tej gałęzi, a kiedy robisz pewne rzeczy (np. commitLub reset), dołączona gałąź będzie się poruszać wraz z HEAD. Możesz zobaczyć, na co to wskazuje, patrząc pod maską.
cat .git/HEAD
Zwykle otrzymasz coś takiego:
ref: refs/heads/master
Czasami otrzymasz coś takiego:
a3c485d9688e3c6bc14b06ca1529f0e78edd3f86
Tak się dzieje, gdy HEADwskazuje bezpośrednio na zatwierdzenie. Nazywa się to odłączoną HEAD, ponieważ HEADwskazuje na coś innego niż odwołanie do gałęzi. Jeśli dokonasz zatwierdzenia w tym stanie, masternie będąc już przywiązanym HEAD, nie będzie się z tobą poruszał. Nie ma znaczenia, gdzie jest to zatwierdzenie. Możesz być na tym samym zatwierdzeniu co gałąź master, ale jeśli HEADwskazuje on na zatwierdzenie, a nie na gałąź, zostanie on odłączony i nowe zatwierdzenie nie zostanie powiązane z odniesieniem do gałęzi.
Możesz spojrzeć na to graficznie, jeśli spróbujesz wykonać następujące ćwiczenie. Uruchom z repozytorium git. Dostaniesz coś nieco innego, ale będą tam bity klucza. Kiedy nadszedł czas, aby bezpośrednio sprawdzić zatwierdzenie, po prostu użyj skróconego skrótu, który otrzymujesz z pierwszego wyjścia (tutaj a3c485d).
git checkout master
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD -> master)
git checkout a3c485d -q # (-q is for dramatic effect)
git log --pretty=format:"%h: %d" -1
# a3c485d: (HEAD, master)
OK, więc tutaj jest niewielka różnica w wydajności. Bezpośrednie sprawdzenie zatwierdzenia (zamiast gałęzi) daje nam przecinek zamiast strzałki. Jak myślisz, czy jesteśmy w stanie HEAD? HEAD wciąż odnosi się do konkretnej wersji związanej z nazwą oddziału. Nadal jesteśmy w gałęzi master, prawda?
Spróbuj teraz:
git status
# HEAD detached at a3c485d
Nie. Jesteśmy w stanie „odłączonej HEAD”.
Można zobaczyć tę samą reprezentację (HEAD -> branch)vs. (HEAD, branch)z git log -1.
HEADto ty. Wskazuje na wszystko, co sprawdziłeś, gdziekolwiek jesteś. Zazwyczaj nie jest to zatwierdzenie, to gałąź. Jeśli HEAD robi wskaż polecenie commit (lub tag), nawet jeśli jest to ten sam popełnić (lub tag), że oddział wskazuje również, pan (i HEAD) zostały oderwane od tego oddziału. Ponieważ nie masz dołączonej gałęzi, gałąź nie podąży za tobą, gdy będziesz dokonywać nowych zatwierdzeń. HEADjednak będzie.
.git/HEADto, co oprogramowanie uważa za HEAD.
HEADodnosi się do bieżącego zatwierdzenia wskazywanego przez twoją kopię roboczą, tj. zatwierdzenia, które aktualnie wypisałeś. Z oficjalnej dokumentacji jądra Linux na temat określania wersji Git :
HEADnazywa zatwierdzenie, na podstawie którego dokonano zmian w działającym drzewie.
Należy jednak pamiętać, że w nadchodzącej wersji 1.8.4 Git @może być również używany jako skrót dla HEAD, jak zauważył współtwórca Git Junio C Hamano na swoim blogu Git Blame :
Zamiast wpisywać „HEAD”, możesz zamiast tego powiedzieć „@”, np. „Git log @”.
Użytkownik przepełnienia stosu VonC również znalazł kilka interesujących informacji o tym, dlaczego @został wybrany jako skrót w swojej odpowiedzi na inne pytanie .
Interesujące jest również to, że w niektórych środowiskach nie ma potrzeby HEADużywania wielkich liter, szczególnie w systemach operacyjnych wykorzystujących systemy plików bez rozróżniania wielkości liter, w szczególności Windows i OS X.
Spójrz na Tworzenie i zabawy z gałęziami
HEAD jest tak naprawdę plikiem, którego zawartość określa miejsce, do którego odnosi się zmienna HEAD:
$ cat .git/HEAD
ref: refs/heads/master
$ cat .git/refs/heads/master
35ede5c916f88d8ba5a9dd6afd69fcaf773f70ed
W tym repozytorium zawartość pliku HEAD odnosi się do drugiego pliku o nazwie refs / heads / master . Plik refs / heads / master zawiera skrót najnowszego zatwierdzenia w gałęzi master.
Wynikiem są punkty HEAD do zatwierdzenia gałęzi master z pliku .git / refs / heads / master .

Chciałbym opisać kilka rzeczy w zaakceptowanej odpowiedzi Grega Hewgila. Według Git Pocket Guide
Oddział:
sama gałąź jest zdefiniowana jako wszystkie punkty osiągalne na wykresie zatwierdzeń z nazwanego zatwierdzenia („końcówka” gałęzi).
GŁOWA: Specjalny rodzaj ref
Specjalny numer referencyjny HEAD określa gałąź, na której jesteś ...
Refs
Git definiuje dwa rodzaje odniesień lub nazwane wskaźniki, które nazywa „refs”:
- Prosty odnośnik, który wskazuje bezpośrednio na identyfikator obiektu (zwykle zatwierdzenie lub znacznik)
- Symboliczny symbol referencyjny (lub symref), który wskazuje na inny symbol referencyjny (prosty lub symboliczny)
Jak wspomniał Greg, HEAD może znajdować się w „odłączonym stanie”. HEAD może być więc zwykłym ref (dla odłączonej HEAD) lub symref.
jeśli HEAD jest symbolicznym oznaczeniem dla istniejącej gałęzi, oznacza to, że „włączasz” tę gałąź. Jeśli z drugiej strony HEAD jest prostym oznaczeniem bezpośrednio nadającym zatwierdzenie jego identyfikatorem SHA-1, oznacza to, że nie jesteś „włączony” w żadnej gałęzi, ale raczej w trybie „odłączonej HEAD”, co dzieje się, gdy przejrzysz niektóre wcześniej zobowiązać się do zbadania.
Wydaje mi się, że „HEAD” to aktualny zatwierdzenie transakcji. Innymi słowy, „HEAD” wskazuje aktualnie zatwierdzone zatwierdzenie.
Jeśli właśnie sklonowałeś i nie wyewidencjonowałeś, nie wiem, na co to wskazuje, prawdopodobnie jest to nieprawidłowa lokalizacja.
HEADjest to, co aktualnie zatwierdziłeś. Szczegółowe informacje można znaleźć w instrukcji (odpowiedni akapit bezpośrednio po rys. 3.4).
mastergałąź - więc HEAD wskaże na master.
master, ale nie zawsze. Zobaczremote set-head
remote set-head, które wpływa tylko na lokalny domyślny oddział i nie zmieni domyślnego na serwerze.
Kieruj się w stronę wierzchołka aktualnie sprawdzanego oddziału.
W twoim repozytorium znajduje się folder .git. Otwórz plik w tej lokalizacji: .git \ refs \ heads. Kod (hasa sha-1) w tym pliku (w większości przypadków master) będzie ostatnim zatwierdzeniem, tzn. Tym, który widnieje na wyjściu polecenia git log. Więcej informacji na temat folderu .git: http://gitready.com/advanced/2009/03/23/whats-inside-your-git-directory.html
git reset HEAD^, a następnie koniec gałęzi nie wskazuje już ostatniego zatwierdzenia (poprzednia wskazówka).
Po przeczytaniu wszystkich poprzednich odpowiedzi nadal chciałem uzyskać większą jasność. Ten blog na oficjalnej stronie git http://git-scm.com/blog dał mi to, czego szukałem:
HEAD w Git jest wskaźnikiem do bieżącego odniesienia do gałęzi, który z kolei jest wskaźnikiem do ostatniego zatwierdzenia, które wykonałeś lub ostatniego zatwierdzenia, które zostało wypisane do katalogu roboczego. Oznacza to również, że będzie rodzicem następnego zatwierdzenia. Generalnie najłatwiej jest to sobie wyobrazić, ponieważ HEAD jest migawką twojego ostatniego zatwierdzenia.
HEADnie jest zatwierdzeniem; to wskazuje na jeden.
checkout HEAD^, teraz HEAD nie wskazuje nawet ostatniej migawki zatwierdzenia w żadnej gałęzi.
commit, merge, rebase, log, itd. Ale koncepcyjnie może „(wskaźnik) aktualną pozycję” jest podsumowaniem dobre.
Wygląda na to, że HEADto tylko tag ostatniego zatwierdzenia, które sprawdziłeś.
Może to być końcówka określonej gałęzi (np. „Master”) lub pośrednia zmiana gałęzi („odłączona głowa”)
Oprócz wszystkich definicji, w mojej głowie zapadła myśl, że kiedy dokonujesz zatwierdzenia, GIT tworzy obiekt zatwierdzenia w repozytorium. Obiekty zatwierdzania powinny mieć element nadrzędny (lub wielu rodziców, jeśli jest to zatwierdzenie scalania). Skąd więc git zna element nadrzędny bieżącego zatwierdzenia? Zatem HEAD jest wskaźnikiem do (odniesienia) ostatniego zatwierdzenia, które stanie się rodzicem bieżącego zatwierdzenia.
Te dwa mogą cię mylić:
głowa
Wskazując na nazwane referencje, które niedawno przesłał oddział. O ile nie użyjesz odwołania do pakietu, głowice zwykle przechowywane są w $ GIT_DIR / refs / heads /.
GŁOWA
Bieżąca gałąź lub twoje drzewo robocze jest zwykle generowane z drzewa, na które wskazuje HEAD. HEAD musi wskazywać na głowę, chyba że używasz odłączonej HEAD.
Spójrz na http://git-scm.com/book/en/Git-Branching-What-a-Branch-Is
Rycina 3-5. Plik HEAD wskazujący gałąź, w której się znajdujesz.
HEADodnosi się do, zależy od tego, czy mówisz o repozytorium nagim czy nie-nagim. W kontekście repozytorium non-bare, efektywnie odnosi się do aktualnie wyrejestrowanego zatwierdzenia, które nie wymaga dołączenia do niego gałęzi (tj. Gdy jest w HEADstanie odłączonym ).
Oddział jest w rzeczywistości wskaźnik, który trzyma popełnić identyfikator takie jak 17a5 . HEAD jest wskaźnikiem do gałęzi, nad którą użytkownik aktualnie pracuje.
HEAD ma plik referencyjny, który wygląda następująco:
ref:
Możesz sprawdzić te pliki, uzyskując dostęp .git/HEAD .git/refsdo repozytorium, w którym pracujesz.
Gitchodzi o zobowiązania.
I Headwskazuje na zatwierdzenie, które aktualnie wypisałeś.
$ git cat-file -t HEAD
commit
Ilekroć kasujesz gałąź, HEAD wskazuje na ostatnie zatwierdzenie w tej gałęzi. Zawartość HEAD można sprawdzić jak poniżej (dla gałęzi master):
$ cat .git/refs/heads/master
b089141cc8a7d89d606b2f7c15bfdc48640a8e25
Jako koncepcja szef jest najnowszą wersją w oddziale. Jeśli masz więcej niż jedną głowę na nazwaną gałąź, prawdopodobnie utworzyłeś ją podczas wykonywania lokalnych zatwierdzeń bez łączenia, skutecznie tworząc gałąź bez nazwy.
Aby mieć „czyste” repozytorium, powinieneś mieć jedną głowę na nazwaną gałąź i zawsze łączyć się z nazwaną gałąź po pracy lokalnej.
Dotyczy to również Mercurial .