Czym jest commit?
U swoich podstaw, git przechowuje dane w konwencji klucz-wartość.
Przed rozpoczęciem
Przed rozpoczęciem tego bloku stwórz nowy katalog i utwórz w nim puste repozytorium git:
mkdir git-commit
cd git-commit
git init
Klucz-wartość
Kluczem w systemie git jest kryptograficzna funkcja hash'ująca (SHA1) - dla każdej danej przechowywanej w systemie generowany jest 40 znakowy klucz heksadecymalny. Dla dwóch identycznych danych - wygenerowany klucz będzie identyczny.
printf 'Hello, World!' > test.txt
git hash-object test.txt
hash-object jest funkcją systemu git odpowiedzialną za generowanie kluczy (SHA1).
Kiedy git zapisuje dane, tworzony jest specjalny obiekt zwany blob'em. Blob składa się z:
- identyfikatora blob
- informacji o wielkości
- specjalnego delimitera - \0
- skompresowanej zawartości
Znając strukturę bloba, powinniśmy być w stanie wygenerować jego SHA1 bez użycia polecenia git:
( perl -e '$size = (-s shift); print "blob $size\x00"' test.txt && cat test.txt ) | openssl sha1
Zapis bloba
Aby zapisać blob należy wykonać następujące polecenie:
git hash-object test.txt -w
Flaga -w oznacza zapis. Ale gdzie został zapisany blob? Do specjalnego podkatalogu .git. Aby się o tym przekonać należy wykonać polecenie:
tree .git
Ponowne wykonanie operacji zapisania bloba nie zaskutkuje powstaniem nowego pliku!
Drzewa
Sam zapis bloba to za mało, potrzebne nam są dodatkowe informacje takie jak:
- nazwy plików
- struktura katalogów
- tryb pliku (czy jest wykonywalny, czy jest linkiem symbolicznym etc.)
Git zapisuje powyższe informacje w drzewie (tree). Tree to połaczenie wskaźnika (wskazującego na SHA1) na blob lub inne drzewo oraz meta informacje takie jak:
- typ wskaźnika (blob lub tree)
- nazwa pliku lub katalogu
- tryb
Commit
Struktury takie jak blog czy też tree są fundamentalnymi składnikami commitu. Każdy commit składa się z wskaźnika na tree oraz meta informacji:
- autor
- commiter
- data
- wiadomość (message)
- przodek (parent commit) - może być jeden lub więcej
SHA1 commitu to hash powyższych informacji.
Na potrzeby tego ćwiczenia wykonaj następujące polecenia:
echo 'Hello World!' > hello.txt
git add hello.txt
git commit -m "Initial commit"
Po wykonaniu powyższych poleceń (pamiętaj aby nie zamykać terminala) sprawdź zawartość katalogi .git/objects:
tree .git/objects
Aby sprawdzić typ danego obiektu należy wydać następujące polecenie:
git cat-file -t <SHA1 obiektu>
Aby wyświetlić zawartość obiektu należy użyć flagi -p:
git cat-file -p <SHA1 obiektu>
Zadanie
Przeanalizuj powstałe obiekty (ich typ oraz zawartość).
Commit w modelu SVN-like i git-like
W modelu SVN-like:
W modelu git-like: