2015-03-17 14 views
12

W jaki sposób generowane są identyfikatory zatwierdzania git, aby jednoznacznie identyfikować zatwierdzenia?Git - Co to jest identyfikator zatwierdzenia git?

Przykład: 521747298a3790fde1710f3aa2d03b55020575aa

Jak to działa? Czy są one unikalne dla każdego projektu? lub dla repozytoriów git na całym świecie?

+0

Zobacz http://git-scm.com/book/en/v2/Getting-Started-Git-Basics#Git-Has-Integrity – Jubobs

+4

Nie wiesz, dlaczego otrzymujesz obniżone oceny. Uważam ten temat za bardzo interesujący. –

Odpowiedz

16

Identyfikator zatwierdzenia Git to SHA-1 hash każdej ważnej rzeczy związanej z zatwierdzeniem. Nie będę ich wszystkich wymieniał, ale tutaj są ważne ...

  • Treść, wszystko to, nie tylko różnica.
  • Data zatwierdzenia.
  • Nazwa i adres e-mail kontrolera.
  • Komunikat dziennika.
  • Identyfikator poprzedniego zatwierdzenia.

Zmień dowolne z tych zmian i identyfikator ID zatwierdzenia. I tak, to samo zatwierdzenie z tymi samymi właściwościami będzie miało ten sam identyfikator na innej maszynie. Służy to trzem celom. Po pierwsze oznacza to, że system może stwierdzić, czy zostało naruszone zatwierdzenie. Jest zapiekany wprost w architekturze.

Po drugie, można szybko porównać zobowiązania, patrząc tylko na ich identyfikatory. Dzięki temu protokoły sieciowe Git są bardzo wydajne. Chcesz porównać dwa zatwierdzenia, aby sprawdzić, czy są one takie same? Nie musisz wysyłać całego pliku diff, po prostu wyślij identyfikatory.

Po trzecie, a to jest geniusz, dwa zatwierdzenia z tymi samymi identyfikatorami mają tę samą historię:. Dlatego identyfikator poprzednich commitów jest częścią hasha. Jeśli treść zatwierdzenia jest taka sama, ale rodzice są inni, identyfikator zatwierdzenia musi być inny. Oznacza to, że podczas porównywania repozytoriów (takich jak push lub pull), gdy Git znajdzie wspólne zatwierdzenie między dwoma repozytoriami, może przestać sprawdzać. Dzięki temu pchanie i ciągnięcie jest niezwykle wydajne. Na przykład ...

origin 
A - B - C - D - E [master] 

A - B [origin/master] 

Rozmowa sieciowa dla git fetch origin idzie coś takiego ...

  • local Hej pochodzenie, jakie gałęzie masz?
  • origin mam pana na E.
  • local nie mam E, mam swoją mistrzem B.
  • origin B mówisz? Mam B i jest to przodek E. To się sprawdza. Pozwolę sobie wysłać C, D i E.

To również dlatego, gdy przepisujesz commit z rebase, wszystko po nim musi się zmienić. Oto przykład.

A - B - C - D - E - F - G [master] 

Załóżmy, że przepisujesz D, aby zmienić nieco komunikat w dzienniku. Teraz D nie może już być D, musi być skopiowane do nowego zatwierdzenia, które nazwiemy D1.

A - B - C - D - E - F - G [master] 
     \ 
      D1 

Podczas D1 może mieć C jako jego rodzica (C jest nienaruszone, popełnia nie wiem swoje dzieci) jest odłączony od E, F i G.Jeśli zmienimy rodzica E na D1, E nie może już być. Musi zostać skopiowany do nowego zatwierdzenia E1.

A - B - C - D - E - F - G [master] 
     \ 
      D1 - E1 

I tak dalej z F do F1 i G do G1.

A - B - C - D - E - F - G 
     \ 
      D1 - E1 - F1 - G1 [master] 

Wszystkie mają ten sam kod, tylko różni rodzice (lub w przypadku D1, inny komunikat zatwierdzenia).

11

można zobaczyć dokładnie to, co idzie do dokonywania id popełnienia przez uruchomienie

git cat-file commit HEAD 

To daje coś

tree 07e239f2f3d8adc12566eaf66e0ad670f36202b5 
parent 543a4849f7201da7bed297b279b7b1e9a086a255 
author Justin Howard <[email protected]> 1426631449 -0700 
committer Justin Howard <[email protected]> 1426631471 -0700 

My commit message 

Daje:

  1. A kontrolną zawartość drzewa
  2. Identyfikator nadrzędnego zatwierdzenia (jeśli jest to scalenie, t tutaj będzie więcej rodziców)
  3. autor popełnić z datownika
  4. committer z popełnienia ze znacznikiem czasu
  5. popełnić wiadomości

Git bierze to wszystko i robi hash SHA1 go. Można odtworzyć id popełnienia przez uruchomienie

(printf "commit %s\0" $(git cat-file commit HEAD | wc -c); git cat-file commit HEAD) | sha1sum 

ten rozpoczyna się od drukowania ciąg commit następnie spację i liczby bajt blob cat-file tekstowym. Następnie dodaje kropelkę cat-file do tej, po której następuje bajt zerowy. Wszystko to następnie przechodzi przez sha1sum.

Jak widać, nic nie wskazuje na projekt lub repozytorium w tej informacji. Powodem, dla którego nie powoduje to problemów, jest fakt, że astronomicznie jest mało prawdopodobne, aby zderzyły się dwa różne haśle zatwierdzające.

+0

To naprawdę dobrze uzupełnia wybraną odpowiedź, sprawdziłem ją, skrypt powłoki naprawdę działa, myślę, że to jest skopiowane z rzeczywistego kodu, prawda? –

+1

@ JeanVincent: Nie bierze się dokładnie z kodu. Wyobrażam sobie, że jest napisane w C. Ale dokładnie odtwarza algorytm (od tej chwili, ale współpracownicy pracują nad zastąpieniem SHA1). –

+0

Czy to jest to, skąd masz informacje? https://gist.github.com/masak/2415865 –

Powiązane problemy