Zrobiłem eksperyment, aby dowiedzieć się, jak Git zachowałby się w tym przypadku. Dotyczy to wersji 2.7.9 ~ rc0 + next.20151210 (wersja Debian). Zasadniczo właśnie zmniejszyłem rozmiar skrótu ze 160-bitowego do 4-bitowego, stosując następujący diff i przebudowując git:
--- git-2.7.0~rc0+next.20151210.orig/block-sha1/sha1.c
+++ git-2.7.0~rc0+next.20151210/block-sha1/sha1.c
@@ -246,6 +246,8 @@ void blk_SHA1_Final(unsigned char hashou
blk_SHA1_Update(ctx, padlen, 8);
/* Output hash */
- for (i = 0; i < 5; i++)
- put_be32(hashout + i * 4, ctx->H[i]);
+ for (i = 0; i < 1; i++)
+ put_be32(hashout + i * 4, (ctx->H[i] & 0xf000000));
+ for (i = 1; i < 5; i++)
+ put_be32(hashout + i * 4, 0);
}
Potem zrobiłem kilka zmian i zauważyłem następujące.
- Jeśli obiekt blob już istnieje z tym samym hashem, nie otrzymasz żadnych ostrzeżeń. Wszystko wydaje się być w porządku, ale kiedy naciskasz, ktoś klonuje lub cofasz się, stracisz najnowszą wersję (zgodnie z tym, co wyjaśniono powyżej).
- Jeśli obiekt drzewa już istnieje i utworzysz obiekt blob z tym samym hashem: wszystko będzie wydawać się normalne, dopóki nie spróbujesz pchnąć lub ktoś nie sklonuje twojego repozytorium. Wtedy zobaczysz, że repozytorium jest uszkodzone.
- Jeśli obiekt zatwierdzenia już istnieje i utworzysz obiekt blob z tym samym hashem: taki sam jak # 2 - uszkodzony
- Jeśli obiekt blob już istnieje i utworzysz obiekt zatwierdzenia z tym samym hashem, zakończy się niepowodzeniem podczas aktualizacji „ref”.
- Jeśli obiekt blob już istnieje i utworzysz obiekt drzewa z tym samym hashem. Nie powiedzie się podczas tworzenia zatwierdzenia.
- Jeśli obiekt drzewa już istnieje i utworzysz obiekt zatwierdzenia z tym samym hashem, zakończy się niepowodzeniem podczas aktualizacji „ref”.
- Jeśli obiekt drzewa już istnieje i utworzysz obiekt drzewa z tym samym hashem, wszystko będzie wyglądało dobrze. Ale po zatwierdzeniu całe repozytorium będzie odnosić się do niewłaściwego drzewa.
- Jeśli obiekt zatwierdzenia już istnieje i utworzysz obiekt zatwierdzenia z tym samym hashem, wszystko będzie wyglądało dobrze. Ale kiedy zatwierdzasz, zatwierdzenie nigdy nie zostanie utworzone, a wskaźnik HEAD zostanie przeniesiony do starego zatwierdzenia.
- Jeśli obiekt zatwierdzenia już istnieje i utworzysz obiekt drzewa z tym samym hashem, zakończy się niepowodzeniem podczas tworzenia zatwierdzenia.
W przypadku nr 2 zazwyczaj pojawia się taki błąd, gdy uruchomisz polecenie „git push”:
error: object 0400000000000000000000000000000000000000 is a tree, not a blob
fatal: bad blob object
error: failed to push some refs to origin
lub:
error: unable to read sha1 file of file.txt (0400000000000000000000000000000000000000)
jeśli usuniesz plik, a następnie uruchom „git checkout file.txt”.
W przypadku # 4 i # 6 zazwyczaj pojawia się taki błąd:
error: Trying to write non-commit object
f000000000000000000000000000000000000000 to branch refs/heads/master
fatal: cannot update HEAD ref
podczas uruchamiania „git commit”. W takim przypadku zazwyczaj możesz po prostu ponownie wpisać „git commit”, ponieważ spowoduje to utworzenie nowego skrótu (z powodu zmienionego znacznika czasu)
W przypadku nr 5 i nr 9 zazwyczaj występuje taki błąd:
fatal: 1000000000000000000000000000000000000000 is not a valid 'tree' object
podczas uruchamiania „git commit”
Jeśli ktoś spróbuje sklonować twoje uszkodzone repozytorium, zwykle zobaczy coś takiego:
git clone (one repo with collided blob,
d000000000000000000000000000000000000000 is commit,
f000000000000000000000000000000000000000 is tree)
Cloning into 'clonedversion'...
done.
error: unable to read sha1 file of s (d000000000000000000000000000000000000000)
error: unable to read sha1 file of tullebukk
(f000000000000000000000000000000000000000)
fatal: unable to checkout working tree
warning: Clone succeeded, but checkout failed.
You can inspect what was checked out with 'git status'
and retry the checkout with 'git checkout -f HEAD'
Martwi mnie to, że w dwóch przypadkach (2,3) repozytorium ulega uszkodzeniu bez ostrzeżeń, aw 3 przypadkach (1,7,8) wszystko wydaje się w porządku, ale zawartość repozytorium jest inna niż się tego spodziewasz być. Ludzie klonujący lub ciągnący będą mieć inną zawartość niż to, co masz. Przypadki 4,5,6 i 9 są w porządku, ponieważ zatrzyma się z błędem. Przypuszczam, że lepiej by było, gdyby błąd zawiódł co najmniej we wszystkich przypadkach.