Dans quelle mesure un git sha est-il généralement considéré comme nécessaire pour identifier de manière unique un changement dans une base de code donnée?

Si vous prévoyez de construire une structure de répertoires où un répertoire est nommé pour une validation dans un référentiel Git, et que vous voulez qu’il soit suffisamment court pour ne pas laisser échapper vos yeux, mais suffisamment longtemps pour que cela se produise, serait négligeable, quelle partie de la sous-chaîne SHA est généralement requirejse?

Disons que je veux identifier de manière unique ce changement: https://github.com/wycats/handlebars.js/commit/e62999f9ece7d9218b9768a908f8df9c11d7e920

Je peux utiliser aussi peu que les quatre premiers caractères: https://github.com/wycats/handlebars.js/commit/e629

Mais j’ai l’impression que ce serait risqué. Mais à partir d’une base de code qui, au bout de quelques années, pourrait avoir, disons, 30 000 changements, quelles sont les chances de collision si j’utilise 8 caractères? 12? Y a-t-il un nombre généralement considéré comme acceptable pour ce genre de chose?

Cette question est en fait résolue dans le chapitre 7 du livre Pro Git :

En règle générale, huit à dix caractères suffisent pour être uniques dans un projet. L’un des plus gros projets Git, le kernel Linux, commence à avoir besoin de 12 caractères sur les 40 possibles pour restr unique.

7 chiffres est la valeur par défaut de Git pour un SHA court, donc ça va pour la plupart des projets. L’équipe du kernel a augmenté le leur plusieurs fois, comme cela a été mentionné, car plusieurs centaines de milliers de commits ont été effectués. Donc, pour vos ~ 30k commits, 8 ou 10 chiffres devraient convenir parfaitement.

Note: vous pouvez demander à git rev-parse --short pour le SHA1 le plus court mais unique.
Voir ” git get court hash de hash régulier ”

 git rev-parse --short=4 921103db8259eb9de72f42db8b939895f5651489 92110 

Comme vous pouvez le voir dans mon exemple, le SHA1 a une longueur de 5, même si j’ai spécifié une longueur de 4.


Pour les grosses mises en pension , 7 ne suffit plus depuis 2010, et engage dce9648 par Linus Torvalds lui-même (git 1.7.4.4, oct. 2010):

La valeur par défaut de 7 provient assez tôt du développement de git, lorsque sept chiffres hexadécimaux étaient nombreux (cela couvre environ 250 millions de valeurs de hachage).
À l’époque, je pensais que les révisions de 65k étaient beaucoup (c’était ce que nous étions sur le sharepoint bash en BK), et chaque révision était d’environ 5-10 nouveaux objects, donc un million d’objects était un grand nombre.

(BK = BitKeeper)

De nos jours, le kernel n’est même pas le plus gros projet git, et même le kernel a environ 220 000 révisions ( bien plus que le BK) et nous approchons de deux millions d’objects.
À ce stade, sept chiffres hexadécimaux sont encore uniques pour beaucoup d’entre eux, mais lorsque nous parlons d’une différence de deux ordres de grandeur entre le nombre d’objects et la taille de hachage, il y aura des collisions dans les valeurs de hachage tronquées.
Ce n’est même plus proche de l’irréalisme – cela arrive tout le temps.

Nous devrions tous deux augmenter l’abréviation par défaut qui était irréaliste et append un moyen pour que les gens définissent leur propre projet par défaut dans le fichier de configuration git .

 core.abbrev 

Définir la longueur des noms d’object sont abrégés en.
S’il n’est pas spécifié, de nombreuses commandes abrégent à 7 hexdigits, ce qui peut ne pas être suffisant pour que les noms d’object abrégés restnt uniques pendant une période suffisamment longue.

environment.c :

 int minimum_abbrev = 4, default_abbrev = 7; 

Note: Comme indiqué ci-dessous par marco.m , core.abbrevLenght été renommé en core.abbrev dans ce même Git 1.7.4.4 dans commit a71f09f

Renommez core.abbrevlength en core.abbrev

Cela correspond à --abbrev=$n option de ligne de commande après tout.


Plus récemment, Linus a ajouté dans commit e6c587c (pour Git 2.11, 4e sortingmestre 2016):
(comme mentionné dans la réponse de Matthieu Moy )

Assez tôt, nous avons en quelque sorte décidé d’abréger les noms d’object à 7-hexdigits, mais à mesure que les projets se développent, il devient de plus en plus probable que des noms d’object aussi courts soient enregistrés dans les journaux.

Actuellement, le projet du kernel Linux a besoin de 11 à 12 hexdigits, alors que Git lui-même a besoin de 10 hexdigits pour identifier de manière unique les objects dont ils disposent, tandis que de nombreux projets plus petits peuvent encore être compatibles avec les 7 hexdigits par défaut. Taille unique ne correspond pas à tous les projets.

Introduire un mécanisme dans lequel nous estimons le nombre d’objects dans le référentiel lors de la première demande pour abréger un nom d’object avec le paramètre par défaut et proposer une définition par défaut pour le référentiel. En supposant que l’on puisse voir une collision dans un référentiel avec 2^(2N) objects lors de l’utilisation de noms d’object raccourcis en N premiers bits, utiliser un nombre suffisant de chiffres hexadécimaux pour couvrir le nombre d’objects dans le référentiel.
Chaque hexdigit (4 bits) que nous ajoutons au nom abrégé nous permet d’avoir quatre fois (2 bits) autant d’objects dans le référentiel.

Voir commit e6c587c (01 oct 2016) par Linus Torvalds ( torvalds ) .
Voir commit 7b5b772 , commit 65acfea (01 oct 2016) par Junio ​​C Hamano ( gitster ) .
(Fusion par Junio ​​C Hamano – gitster – dans commit bb188d0 , 03 oct. 2016)

Cette nouvelle propriété (deviner une valeur par défaut raisonnable pour la valeur abréviée SHA1) a un effet direct sur la façon dont Git calcule son propre numéro de version pour la publication .

Ceci est connu comme le problème de l’anniversaire.

Pour les probabilités, moins de la moitié de la probabilité d’une collision peut être approximée comme

p ~ = (n 2 ) / (2m)

Où n est le nombre d’éléments et m le nombre de possibilités pour chaque article.

Le nombre de possibilités pour une chaîne hexadécimale est de 16 c où c est le nombre de caractères.

Donc pour 8 caractères et 30K commits

30K ~ = 2 15

p ~ = (n 2 ) / (2m) ~ = ((2 15 ) 2 ) / (2 * 16 8 ) = 2 30/2 33 = ⅛

L’augmenter à 12 caractères

p ~ = (n 2 ) / (2m) ~ = ((2 15 ) 2 ) / (2 * 16 12 ) = 2 30/2 49 = 2 -19

On a répondu à cette question, mais pour quiconque cherche les maths derrière, cela s’appelle le problème de l’anniversaire ( Wikipedia ).

Il s’agit de la probabilité d’avoir 2 (ou plus) personnes du groupe de personnes N ayant un anniversaire le même jour de l’année. Ce qui est analogue à probabilement de 2 (ou plus) git valide depuis le repository avec N commits au total ayant le même préfixe de hachage de longueur X.

Regardez le tableau des probabilités . Par exemple, pour une chaîne hexadécimale de longueur 8, la probabilité d’avoir une collision atteint 1% lorsque le référentiel contient environ 9300 éléments (git commits). Pour 110 000 commits, la probabilité est de 75%. Mais si vous avez une chaîne de hachage de longueur 12, la probabilité de collision dans 100 000 commits est inférieure à 0,1%.

La version 2.11 de Git (ou peut-être 2.12?) Contiendra une fonctionnalité qui adapte le nombre de caractères utilisés dans les identificateurs courts (par exemple, git log --oneline ) à la taille du projet. Une fois que vous utilisez une telle version de Git, la réponse à votre question peut être “choisissez la longueur que Git vous donne avec git log --oneline , c’est assez sûr”.

Pour plus de détails, voir Modification de la valeur par défaut pour «core.abbrev»? discussion dans Git Rev News edition 20 et commit bb188d00f7 .