HEAD i ORIG_HEAD w Git

253

Do czego odnoszą się te symbole i co oznaczają?

(Nie mogę znaleźć żadnego wyjaśnienia w oficjalnej dokumentacji)

Collimarco
źródło
4
Uwaga: HEADjest teraz (nadchodzący git1.8.4) ' @'! Zobacz moją zredagowaną odpowiedź poniżej
VonC
Note-bis: ' @' (for HEAD) wciąż nadchodzi, ale nie dotyczy wersji 1.8.4 edytowanej i poprawionej .
VonC
1
Uwaga: „ @for” HEADpowraca do gita 1.8.5 / 1.9. odpowiedź edytowana ponownie .
VonC
21
HEADa ORIG_HEADw Git są jak $PWDiw $OLDPWDBash. :)
musiphil

Odpowiedzi:

324

HEADto (bezpośrednie lub pośrednie, tj. symboliczne) odniesienie do bieżącego zatwierdzenia. Jest to zatwierdzenie, które sprawdziłeś w katalogu roboczym (chyba, że ​​wprowadziłeś jakieś zmiany lub równoważne), i jest to zatwierdzenie, na podstawie którego „git commit” utworzyłby nowy. Zwykle HEADjest symbolicznym odniesieniem do innej nazwanej gałęzi; gałąź ta jest obecnie gałęzią wyewidencjonowaną lub gałęzią bieżącą. HEADmoże również wskazywać bezpośrednio na zatwierdzenie; ten stan nazywa się „odłączoną HEAD” i można go rozumieć jako znajdujący się w anonimowej gałęzi bez nazwy.

I @sam jest skrótem HEAD, ponieważ Git 1.8.5

ORIG_HEADjest poprzednim stanem HEAD, ustawionym za pomocą poleceń, które mogą mieć niebezpieczne zachowanie, aby można je było łatwo cofnąć. Jest mniej przydatny teraz, gdy Git ma rejestrować ponownie: HEAD@{1}jest mniej więcej równy ORIG_HEAD( HEAD@{1}zawsze jest ostatnią wartością HEAD, ORIG_HEADjest ostatnią wartościąHEAD przed niebezpieczną operacją).

Aby uzyskać więcej informacji, przeczytaj stronę git (1) , Podręcznik użytkownika Git, Podręcznik społeczności Git i Słownik Git

Jakub Narębski
źródło
2
Cześć Jakub. +1 za wyjaśnienie. Czy możesz opisać „mniej więcej równoważną” część HEAD @ {1}? W mojej odpowiedzi odsyłam do wątku thread.gmane.org/gmane.comp.version-control.git/38379 (byłeś w nim w lutym 2007 roku) i nie do końca zrozumiałem dyskusję, którą prowadziliście składnia @ {...}.
VonC,
19
ORIG_HEAD jest ustawiony (myślę) tylko przez „niebezpieczne” polecenia, które poruszają HEAD więcej niż jeden zatwierdzenie. Więc ORIG_HEAD nie zawsze jest ustawiony, a HEAD @ {1} jest zawsze ustawiony. @ {1} to $ (git symbolic-ref HEAD) @ {1}, tzn. Używa reflog dla bieżącego oddziału, a nie HEAD reflog.
Jakub Narębski
Riiight ... Rozumiem teraz :) Dziękuję za wyjaśnienie. Za to, co warto, głosowałem również za twoim komentarzem!
VonC
1
„a HEAD jest zatwierdzeniem, z którego„ git commit ”stworzyłoby nowy.” - warto pamiętać, dziękuję! Również z @VonC „To jest zatwierdzenie„ git commit ”buduje się na nim, a„ git diff --cached ”i„ git status ”porównują z”.
Minqi Pan
1
git help revisions przedstawia git-scm.com/docs/gitrevisions , który opisuje wszystkie sposoby odwoływania się do zatwierdzeń (w tym HEADi ORIG_HEAD).
dahlbyk
104

Z Git Reset

„pull” lub „merge” zawsze pozostawia oryginalny wierzchołek bieżącej gałęzi ORIG_HEAD.

git reset --hard ORIG_HEAD

Zresetowanie go ciężko przywraca plik indeksu i drzewo robocze do tego stanu i resetuje końcówkę gałęzi do tego zatwierdzenia.

git reset --merge ORIG_HEAD

Po sprawdzeniu wyniku scalenia może się okazać, że zmiana w drugim oddziale jest niezadowalająca. Uruchomienie „ git reset --hard ORIG_HEAD” pozwoli ci wrócić do miejsca, w którym byłeś, ale odrzuci twoje lokalne zmiany, których nie chcesz. „git reset --merge ” zachowuje lokalne zmiany.


Przed zastosowaniem jakichkolwiek poprawek ORIG_HEAD jest ustawiany na wierzchołek bieżącej gałęzi.
Jest to przydatne, jeśli masz problemy z wieloma zatwierdzeniami, takimi jak uruchamianie „git am niewłaściwej gałęzi lub błędem w zatwierdzeniach, który można łatwiej naprawić przez zmianę skrzynki pocztowej (np. + Błędy w wierszach „Od:”).

Ponadto scalanie zawsze ustawia „ .git/ORIG_HEAD” na pierwotny stan HEAD, więc problematyczne scalanie można usunąć za pomocą „ git reset ORIG_HEAD”.


Uwaga: od stąd

HEAD to ruchomy wskaźnik. Czasami oznacza to obecną gałąź, a czasem nie.

Więc HEAD NIE jest już synonimem „bieżącej gałęzi” już wszędzie.

HEAD oznacza wszędzie „prąd” w git, ale niekoniecznie oznacza „prąd gałąź” (tj. Odłączony HEAD).

Ale prawie zawsze oznacza to „bieżące zatwierdzenie”.
Jest to wersja git commitkompilacji „ ” na górze, „ git diff --cached” i „ git status” w porównaniu z nią.
Oznacza to obecną gałąź tylko w bardzo ograniczonych kontekstach (dokładnie wtedy, gdy chcemy, aby nazwa gałęzi działała na --- resetując i rozwijając końcówkę gałęzi poprzez zatwierdzenie / rebase / itd.).

Reflog jest narzędziem cofania się w czasie, a wehikuły czasu mają interesującą interakcję z pojęciem „prądu”.

HEAD@{5.minutes.ago}może oznaczać „dereferencję symref HEAD, aby dowiedzieć się, na której gałęzi jesteśmy PRAWO TERAZ, a następnie dowiedzieć się, gdzie wierzchołek tej gałęzi był 5 minut temu”.
Alternatywnie może to oznaczać „co to jest zatwierdzenie, które nazwałbym HEAD 5 minut temu, np. Gdybym„ wtedy pokazał HEAD ”.


git1.8.4 (lipiec 2013) wprowadza wprowadził nowy zapis!
(w rzeczywistości będzie to 1.8.5 lub 1.9, IV kw. 2013: ponownie wprowadzone z zatwierdzeniem 9ba89f4 )

Zamiast wpisywać cztery duże litery „ HEAD”, możesz powiedzieć @„teraz”,
np. „ git log @”.

Zobacz zatwierdzenie cdfd948

Pisanie „ HEAD” jest żmudne, zwłaszcza gdy @zamiast tego możemy użyć „ ”.

Powodem wyboru „ @” jest to, że wynika to naturalnie ze ref@opskładni (np. HEAD@{u}), Z tym wyjątkiem, że nie mamy żadnego odwołania i żadnej operacji, a gdy ich nie mamy, sensownie jest założyć „ HEAD”.

Więc teraz możemy użyć ' git show @~1' i całej tej dobroci.

Do tej pory „ @” była prawidłową nazwą, ale jest sprzeczna z tym pomysłem, więc unieważnijmy go. Prawdopodobnie bardzo niewiele osób używało tego imienia.


Wpis na blogu w okresie 1.8.4-rc3 (14 sierpnia 2013 r.) Ogłosił, że ta funkcja została przywrócona i opóźniona (Dziękuję, Cupcake za heads-up ).
Ponownie wprowadzono go ponownie z zatwierdzeniem 9ba89f4 (wrzesień 2013).

Zobacz zatwierdzenie 2c2b664 :

Przywróć „Dodaj nowy @skrót do HEAD

Powoduje to cofnięcie zatwierdzenia cdfd948 , ponieważ nie dotyczy to tylko „ @” (i formularzy z modyfikatorami, które zostały @{u}zastosowane), ale także wpływa np. Na „ refs/heads/@/foo”, czego nie powinno.

Podstawowy pomysł podania krótkiej ręki może być dobry, a temat można ponowić później, ale cofnijmy się, aby na razie nie wpływać na istniejące przypadki użycia w nadchodzącym wydaniu.

VonC
źródło
Po uruchomieniu git zresetuj ORIG_HEAD i zatwierdź. ORIG_HEAD nadal znajduje się pod Referencjami obok HEAD. Dlaczego nie został usunięty z widoku?
proszek 366
@ powder366, ale git resetwygeneruje ORIG_HEAD. Musisz to rmzrobić ręcznie. Zobacz na przykład stackoverflow.com/a/12418078/6309 .
VonC
1
@VonC @alias dla HEADjest przywracany (tymczasowo?) Dla wersji Git 1.8.4 ! Zostało właśnie ogłoszone dzisiaj!
Podobał mi się komentarz „heads-up”!
Robino,
2

Rozumiem, że HEAD wskazuje bieżącą gałąź, podczas gdy ORIG_HEAD służy do przechowywania poprzedniej HEAD przed wykonaniem „niebezpiecznych” operacji.

Na przykład git-rebase i git-am zapisują oryginalną końcówkę gałęzi, zanim zastosują jakiekolwiek zmiany.

ynimous
źródło
4
HEAD nie zawsze wskazuje na bieżącą gałąź (można ją odłączyć)
VonC
1
Czym więc jest „bieżąca gałąź”, kiedy HEAD jest „odłączony”?
cjs
@ CurtJ.Sampson To jest „brak oddziału”. dlatego, gdy jesteś w oderwanej głowie, robisz to git branch foo -b, aby „utworzyć” gałąź dla tych sierot.
Royi Namir,
1

Od man 7 gitrevisions:

HEAD nazywa zatwierdzenie, na podstawie którego dokonano zmian w drzewie roboczym. FETCH_HEAD rejestruje gałąź, którą pobrałeś ze zdalnego repozytorium za pomocą ostatniego wywołania git fetch. ORIG_HEAD jest tworzony przez polecenia, które poruszają HEAD w drastyczny sposób, aby zapisać pozycję HEAD przed ich działaniem, abyś mógł łatwo zmienić końcówkę gałęzi z powrotem do stanu przed uruchomieniem. MERGE_HEAD rejestruje zatwierdzenia, które scalasz w swoim oddziale podczas uruchamiania git merge. CHERRY_PICK_HEAD rejestruje zatwierdzenie, które wybierasz podczas uruchamiania git cherry-pick.

Nathan Chappell
źródło