web-dev-qa-db-fra.com

Quelle quantité de git sha est * généralement * considérée comme nécessaire pour identifier de manière unique un changement dans une base de code donnée?

Si vous envisagez de créer, par exemple, une structure de répertoires dans laquelle un répertoire est nommé pour un commit dans un référentiel Git et que vous voulez qu'il soit suffisamment court pour ne pas saigner les yeux, mais suffisamment longtemps pour que le risque de collision se produise. serait négligeable, quelle quantité de la sous-chaîne SHA est généralement requise?)

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

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

Mais je sens que cela serait risqué. Mais en résumant une base de code qui, sur quelques années, pourrait avoir, disons, 30 000 modifications, quelles sont les chances de collision si j'utilise 8 caractères? 12? Existe-t-il un chiffre généralement considéré comme acceptable pour ce genre de chose?

178

Cette question a reçu une réponse dans Chapitre 7 du livre de Pro Git :

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

La valeur par défaut de Git pour un SHA court est de 7 chiffres, donc cela convient pour la plupart des projets. L’équipe du noyau a multiplié les leurs plusieurs fois, comme indiqué, car ils ont plusieurs centaines de milliers validés. Donc, pour vos ~ 30 000 commits, 8 ou 10 chiffres devraient suffire.

204
Nevik Rehnel

Remarque: vous pouvez demander git rev-parse --short pour le SHA1 le plus court et le plus unique.
Voir " git obtenir un hachage court à partir d'un hachage 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 n'est pas suffisant depuis 2010, et commit dce9648 par Linus Torvalds lui-même (git 1.7.4.4, oct. 2010):

La valeur par défaut de 7 provient d'un développement assez précoce du développement git, où sept chiffres hexadécimaux représentaient un nombre important (il couvre environ 250 millions de valeurs de hachage).
À l’époque, j’imaginais que les révisions de 65 000 $ représentaient beaucoup (c’était ce que nous allions frapper en BK), et chaque révision a tendance à représenter environ 5 à 10 nouveaux objets, un million d’objets était donc un gros nombre.

(BK = BitKeeper)

De nos jours, le noyau n'est même pas le plus gros projet git, et même le noyau a environ 220 000 révisions ( beaucoup plus grand que l'arbre BK n'a jamais été) et nous approchons de deux millions d'objets.
À 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’objets et la taille de hachage, là volonté être des collisions dans les valeurs de hachage tronquées.
Cela n’est même plus presque irréaliste - cela arrive tout le temps.

Nous devrions tous les deux augmenter l'abrév par défaut qui était trop petit, et ajouter un moyen pour les personnes de définir leur propre projet par défaut dans le fichier de configuration git .

core.abbrev

Définissez la longueur des noms d'objet sont abrégés en.
Si non spécifié, de nombreuses commandes abrégent 7 digits hexadécimaux, ce qui peut ne pas suffire pour que les noms d’objets abrégés restent uniques pendant une période suffisamment longue.

environment.c :

int minimum_abbrev = 4, default_abbrev = 7;

Remarque: Comme commenté ci-dessous par marco.m , core.abbrevLenght A été renommé dans core.abbrev Dans le même Git 1.7.4.4 dans commit a71f09f

Renommez core.abbrevlength Pour revenir à core.abbrev

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


Plus récemment, Linus a ajouté dans commit e6c587c (pour Git 2.11, Q4 2016):
(comme mentionné dans Matthieu Moy 's answer )

Au début, nous avons en quelque sorte décidé d'abréger les noms d'objet en chiffres à 7 hexadécimaux, mais à mesure que les projets se développent, il est de plus en plus probable que des noms d'objet aussi courts créés et enregistrés dans le journal ne soient plus uniques.

Actuellement, le projet du noyau 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 objets dont ils disposent, alors que de nombreux projets plus petits peuvent encore fonctionner correctement avec la valeur par défaut d'origine 7-hexdigit. La taille unique ne convient pas à tous les projets.

Introduisez un mécanisme dans lequel nous estimons le nombre d'objets dans le référentiel lors de la première demande d'abréviation d'un nom d'objet avec le paramètre par défaut et établissons une valeur par défaut raisonnable pour le référentiel. En supposant que nous verrions une collision dans un référentiel avec les objets 2^(2N) lors de l'utilisation de noms d'objet raccourcis à N premiers bits, utilisez un nombre suffisant de chiffres hexadécimaux pour couvrir le nombre d'objets du référentiel.
Chaque valeur hexadécimale (4 bits) que nous ajoutons au nom abrégé nous permet d’avoir quatre fois (2 bits) autant d’objets 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 bb188d , 3 octobre 2016)

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

121
VonC

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

Pour les probabilités inférieures à 1/2, la probabilité de collision peut être approximée par

p ~ = (n2)/(2m)

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

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

Donc pour 8 caractères et 30K commits

30K ~ = 215

p ~ = (n2)/(2m) ~ = ((215)2)/(2 * 168) = 230/ 233 =

L'augmenter à 12 caractères

p ~ = (n2)/(2m) ~ = ((215)2)/(2 * 1612) = 230/ 249 = 2-19

27
plugwash

Cette question a reçu une réponse, mais pour tous ceux qui recherchent les calculs en retard, cela s'appelle Problème d'anniversaire ( Wikipedia ).

Il s'agit de la probabilité que deux (ou plus) personnes du groupe N aient un anniversaire le même jour de l'année. Ce qui est analogique à probablement 2 (ou plus) commits git du dépôt ayant au total N commises ayant le même préfixe de hachage de longueur X.

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

11
Messa

Git version 2.11 (ou peut-être 2.12?) Contiendra une fonctionnalité qui adaptera le nombre de caractères utilisés dans les identifiants courts (par exemple, git log --oneline) à la taille du projet. Une fois que vous utilisez cette 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 l’édition 20 de Git Rev News et commit bb188d00f7 .

2
Matthieu Moy