J'ai fait une expérience pour savoir exactement comment Git se comporterait dans ce cas. C'est avec la version 2.7.9 ~ rc0 + next.20151210 (version Debian). J'ai simplement réduit la taille de hachage de 160 bits à 4 bits en appliquant le diff suivant et en reconstruisant 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);
}
Puis j'ai fait quelques commits et j'ai remarqué ce qui suit.
- Si un blob existe déjà avec le même hachage, vous ne recevrez aucun avertissement. Tout semble aller bien, mais lorsque vous poussez, quelqu'un clone ou que vous revenez, vous perdrez la dernière version (conformément à ce qui est expliqué ci-dessus).
- Si un objet arborescent existe déjà et que vous créez un blob avec le même hachage: tout semblera normal, jusqu'à ce que vous essayiez de pousser ou que quelqu'un clone votre référentiel. Ensuite, vous verrez que le dépôt est corrompu.
- Si un objet commit existe déjà et que vous créez un blob avec le même hachage: identique à # 2 - corrompu
- Si un blob existe déjà et que vous créez un objet commit avec le même hachage, il échouera lors de la mise à jour de la "ref".
- Si un blob existe déjà et que vous créez un objet arborescent avec le même hachage. Il échouera lors de la création du commit.
- Si un objet arborescent existe déjà et que vous créez un objet commit avec le même hachage, il échouera lors de la mise à jour de la "ref".
- Si un objet arbre existe déjà et que vous créez un objet arbre avec le même hachage, tout semblera correct. Mais lorsque vous vous engagez, tout le référentiel fera référence à la mauvaise arborescence.
- Si un objet commit existe déjà et que vous créez un objet commit avec le même hachage, tout semblera correct. Mais lorsque vous validez, la validation ne sera jamais créée et le pointeur HEAD sera déplacé vers une ancienne validation.
- Si un objet commit existe déjà et que vous créez un objet arborescent avec le même hachage, il échouera lors de la création du commit.
Pour # 2, vous obtiendrez généralement une erreur comme celle-ci lorsque vous exécutez "git push":
error: object 0400000000000000000000000000000000000000 is a tree, not a blob
fatal: bad blob object
error: failed to push some refs to origin
ou:
error: unable to read sha1 file of file.txt (0400000000000000000000000000000000000000)
si vous supprimez le fichier, puis exécutez "git checkout file.txt".
Pour # 4 et # 6, vous obtiendrez généralement une erreur comme celle-ci:
error: Trying to write non-commit object
f000000000000000000000000000000000000000 to branch refs/heads/master
fatal: cannot update HEAD ref
lors de l'exécution de "git commit". Dans ce cas, vous pouvez généralement taper à nouveau "git commit" car cela créera un nouveau hachage (en raison de l'horodatage modifié)
Pour # 5 et # 9, vous obtiendrez généralement une erreur comme celle-ci:
fatal: 1000000000000000000000000000000000000000 is not a valid 'tree' object
lors de l'exécution de "git commit"
Si quelqu'un essaie de cloner votre référentiel corrompu, il verra généralement quelque chose comme:
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'
Ce qui "m'inquiète", c'est que dans deux cas (2,3) le référentiel devient corrompu sans aucun avertissement, et dans 3 cas (1,7,8), tout semble correct, mais le contenu du référentiel est différent de ce que vous attendez être. Les personnes clonant ou tirant auront un contenu différent de ce que vous avez. Les cas 4,5,6 et 9 sont corrects, car cela s'arrêtera avec une erreur. Je suppose que ce serait mieux s'il échouait avec une erreur au moins dans tous les cas.