2010-04-10 12 views
130

Pochodzący z svn, dopiero zaczynający zaznajomić się z git.Czy usunięcie gałęzi w git usuwa ją z historii?

Kiedy gałąź jest usuwana w git, jest usuwana z historii?

W svn można łatwo odzyskać oddział, przywracając operację usuwania (scalanie zwrotne). Podobnie jak wszystkie usunięcia w svn, gałąź nigdy nie jest tak naprawdę usunięta, jest po prostu usunięta z bieżącego drzewa.

Jeśli gałąź jest rzeczywiście usunięta z historii w git, co dzieje się ze zmianami, które zostały scalone z tej gałęzi? Czy są zatrzymane?

Odpowiedz

176

Odgałęzienia to tylko wskazówki do popełnienia w git. W git każdy commit ma pełne drzewo źródłowe, jest to bardzo odmienna struktura od svn, gdzie wszystkie gałęzie i znaczniki (według konwencji) żyją w oddzielnych "folderach" repozytorium obok specjalnego "trunk".

Jeśli oddział został scalony do innej gałęzi, zanim został usunięty, wszystkie zatwierdzenia będą nadal dostępne z drugiego oddziału po usunięciu pierwszego oddziału. Pozostają dokładnie takie, jakie były.

Jeśli gałąź zostanie usunięta bez połączenia z inną gałęzią, to zatwierdzenia w tej gałęzi (aż do momentu, w którym rozwidlone z zatwierdzenia, które jest jeszcze osiągalne) przestaną być widoczne.

Zatwierdzenia będą nadal przechowywane w repozytorium i można je odzyskać natychmiast po usunięciu, ale ostatecznie zostaną one usunięte.

+2

Dzięki za odpowiedź. Czy możesz wyjaśnić, co masz na myśli, mówiąc, że "każde zatwierdzenie ma pełne drzewo źródłowe"? Jak rozumiem, każde zatwierdzenie w git jest zbiorem delt, które odwołują się do zatwierdzenia nadrzędnego, a nie całego drzewa. –

+0

Nie, każde zatwierdzenie jest stanem drzewa w danym punkcie. Delty są obliczane później tylko w celu wyświetlania i zmiany nazwy, ale identyfikator zatwierdzenia jest hashem całego drzewa. – ben

+1

@Ken Liu: Zatwierdzenie zawiera wskaźniki do zera lub więcej animacji rodzicielskich, obiektu drzewa i niektórych metadanych dotyczących zatwierdzenia. Zatwierdzenie w ten sposób jednoznacznie identyfikuje zarówno drzewo źródłowe pary, jak i, w stosunku do jego rodzica (rodziców), wprowadzane przez siebie zmiany. –

62

W Git, gałęzie są tylko wskaźnikami (odnośnikami) do zatwierdzenia w skierowanym acyklicznym wykresie (DAG) zatwierdzeń. Oznacza to, że usunięcie gałęzi usuwa tylko odniesienia do zatwierdzeń, co może spowodować, że niektóre zatwierdzenia w DAG będą niedostępne, a więc niewidoczne. Ale wszystkie zatwierdzenia, które znajdowały się na usuniętej gałęzi, nadal znajdowałyby się w repozytorium, przynajmniej dopóki nieosiągalne potwierdzenia nie zostaną przycięte (np. Za pomocą git gc).

Należy pamiętać, że git branch -d odmówiłby usunięcia oddziału, jeśli nie może być pewien, że usunięcie go nie spowoduje pozostawienia nieosiągalnego zatwierdzenia. Musisz użyć silniejszego git branch -D, aby wymusić usunięcie gałęzi, jeśli może ona pozostawić nieosiągalne zatwierdzenia.

Należy również zauważyć, że nieosiągalne zatwierdzenia, jeśli są obecne, są tylko tymi zatwierdzeniami między ostatnim wierzchołkiem usuniętego oddziału i zatwierdzeniem, które zostało scalone z inną istniejącą gałęzią, dowolnym oznaczonym zatwierdzeniem lub punktem rozgałęzienia; cokolwiek nastąpi później. Na przykład w następującej sytuacji:

 
----O----*----*----/M----* <-- master <-- HEAD 
    \   /
     \--.----.--/--x---y  <-- deleted branch 

zobowiązuje „x” i „y” tylko staną się nieosiągalne po usunięciu oddział.

Jeśli operowano usuniętej gałęzi w okresie gc.reflogExpire, domyślnie 90 dni, to masz ostatnią końcówkę usuniętego oddziału zarejestrowanego w HEAD reflog (patrz git reflog show HEAD lub git log --oneline --walk-reflogs HEAD). Powinieneś być w stanie użyć refela HEAD, aby odzyskać usunięty wskaźnik. Należy również zauważyć, że w tym przypadku nieosiągalne zatwierdzenia w usuniętym oddziale będą chronione przed przycinaniem (usuwaniem) w okresie gc.reflogExpireUnreachable, który domyślnie wynosi 30 dni.

Jeśli nie można znaleźć końcówki po prostu usunięty oddział w reflog głowy, można spróbować użyć git fsck znaleźć „nieosiągalny popełnić <SHA1>” i badać (przez git show <sha1> lub git log <sha1>), aby znaleźć wskazówka usuniętego oddziału.

Niezależne od tego, jak znaleźć końcówkę usuniętej gałęzi, można cofnąć usunięcie, lub raczej ponownie utworzyć właśnie usunął gałąź używając

git branch <deleted-branch> <found-sha1-id> 

Należy jednak pamiętać, że reflog dla oddziału zostaną utracone.


Istnieje również git-resurrect.sh skrypt w contrib/ która pomaga znaleźć ślady końcówki gałęzi z podaną nazwą i wskrzesić (cofnąć) go.

+0

Awesome! 'git reflog show HEAD' wyszczególnił commit i stworzyłem nowy oddział, tak jak powiedziałeś, idealny. –

1

Jeśli martwisz się przypadkowo usuniętymi oddziałami i nie masz już lokalnej kopii repo, istnieją rozszerzenia na serwery Git firmy, takie jak Gerrit, które wykryją przepisywanie historii i usuwanie gałęzi, wykonają kopie zapasowe w specjalnej wersji. ref, aby można je było przywrócić w razie potrzeby i nie zostaną przycięte przez zbieranie śmieci. Administratorzy Gerrit mogą nadal usuwać wybrane zatwierdzenia, jeśli wymagają tego względy prawne.

Powiązane problemy