it-swarm.com.de

Wie viel von einem git sha wird * im Allgemeinen * als notwendig erachtet, um eine Änderung in einer bestimmten Codebasis eindeutig zu identifizieren?

Wenn Sie beispielsweise eine Verzeichnisstruktur erstellen möchten, in der ein Verzeichnis für ein Commit in einem Git-Repository benannt ist, und Sie möchten, dass es kurz genug ist, damit Ihre Augen nicht bluten, sondern lange genug, damit die Wahrscheinlichkeit einer Kollision besteht wäre vernachlässigbar, wie viel von der SHA Teilzeichenfolge wird in der Regel benötigt?

Angenommen, ich möchte diese Änderung eindeutig identifizieren: https://github.com/wycats/handlebars.js/commit/e62999f9ece7d9218b9768a908f8df9c11d7e92

Ich kann nur die ersten vier Zeichen verwenden: https://github.com/wycats/handlebars.js/commit/e629

Aber ich denke, das wäre riskant. Angenommen, es handelt sich um eine Codebasis, die sich in ein paar Jahren möglicherweise um 30.000 Zeichen geändert hat. Wie hoch ist die Wahrscheinlichkeit einer Kollision, wenn ich 8 Zeichen verwende? 12? Gibt es eine Zahl, die allgemein als akzeptabel für diese Art von Dingen angesehen wird?

Diese Frage wird tatsächlich in Kapitel 7 des Pro Git-Buches beantwortet :

In der Regel reichen acht bis zehn Zeichen aus, um innerhalb eines Projekts eindeutig zu sein. Eines der größten Git-Projekte, der Linux-Kernel, benötigt 12 der 40 möglichen Zeichen, um eindeutig zu bleiben.

7-stellig ist die Git-Standardeinstellung für eine kurze SHA, das ist also für die meisten Projekte in Ordnung. Das Kernel-Team hat, wie bereits erwähnt, seine Anzahl mehrmals erhöht, da es mehrere hunderttausend Commits gibt. Für Ihre ~ 30k-Commits sollten also 8 oder 10 Ziffern völlig in Ordnung sein.

204
Nevik Rehnel

Hinweis: Sie können git rev-parse --short nach dem kürzesten und dennoch einzigartigen SHA1 fragen.
Siehe " git get short hash from regular hash "

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

Wie Sie in meinem Beispiel sehen können, hat der SHA1 eine Länge von 5, auch wenn ich eine Länge von 4 angegeben habe.


Für große Repos ist 7 seit 2010 nicht genug, und begebe dce9648 von Linus Torvalds selbst (git 1.7.4.4, Okt 2010):

Der Standardwert von 7 stammt aus einer relativ frühen Phase der Git-Entwicklung, als sieben Hexadezimalziffern eine Menge waren (er deckt mehr als 250 Millionen Hash-Werte ab).
Damals dachte ich, dass 65.000 Revisionen eine Menge waren (es war das, was wir in BK treffen wollten), und jede Revision bestand aus ungefähr 5-10 neuen Objekten, also war eine Million Objekte groß Nummer.

(BK = BitKeeper)

Heutzutage ist der Kernel nicht einmal das größte Git-Projekt, und selbst der Kernel hat ungefähr 220.000 Revisionen ( viel größer als der BK-Baum jemals war) und wir nähern uns zwei Millionen Objekten.
Zu diesem Zeitpunkt sind für viele von ihnen noch sieben Hexadezimalziffern eindeutig, aber wenn wir nur von zwei Größenordnungen Unterschied zwischen der Anzahl der Objekte und der Hash-Größe sprechen, gibt es wird Kollisionen in abgeschnittenen Hashwerten sein.
Es ist nicht mehr annähernd unrealistisch - es passiert die ganze Zeit.

Wir sollten beide die Standardabkürzung erhöhen, die unrealistisch klein war, und eine Möglichkeit hinzufügen, dass Benutzer ihr eigenes Standardprojekt pro Git-Konfigurationsdatei festlegen .

core.abbrev

Legen Sie die Länge fest, mit der Objektnamen abgekürzt werden.
Wenn nicht angegeben, werden viele Befehle mit 7 Hexadezimalziffern abgekürzt, was möglicherweise nicht ausreicht, damit abgekürzte Objektnamen für ausreichend lange Zeit eindeutig bleiben.

environment.c :

int minimum_abbrev = 4, default_abbrev = 7;

Hinweis: Wie unten von marco.m kommentiert, wurde core.abbrevLenght In core.abbrev In umbenannt dasselbe Git 1.7.4.4 in Commit a71f09f

Benenne core.abbrevlength Zurück zu core.abbrev

Es entspricht immerhin der Befehlszeilenoption --abbrev=$n.


In jüngerer Zeit hat Linus in commit e6c587c hinzugefügt (für Git 2.11, 4. Quartal 2016):
(wie in der Antwort von Matthieu Moy erwähnt)

In relativ frühen Tagen haben wir uns irgendwie entschlossen, Objektnamen auf 7-Hex-Ziffern abzukürzen. Mit zunehmendem Projektwachstum wird es jedoch immer wahrscheinlicher, dass so kurze Objektnamen, die in früheren Tagen erstellt und in den Protokollnachrichten aufgezeichnet wurden, nicht mehr eindeutig sind.

Gegenwärtig benötigt das Linux-Kernel-Projekt 11 bis 12 Hexadigits, während Git selbst 10 Hexadigits benötigt, um die Objekte eindeutig zu identifizieren, während viele kleinere Projekte mit dem ursprünglichen 7-Hexadigit-Standard noch in Ordnung sein können. One-Size passt nicht zu allen Projekten.

Führen Sie einen Mechanismus ein, bei dem wir die Anzahl der Objekte im Repository bei der ersten Anforderung abschätzen, um einen Objektnamen mit der Standardeinstellung abzukürzen, und einen vernünftigen Standard für das Repository festlegen. Ausgehend von der Erwartung, dass in einem Repository Kollisionen mit 2^(2N) Objekten auftreten, wenn auf die ersten N Bits verkürzte Objektnamen verwendet werden, verwenden Sie eine ausreichende Anzahl von Hexadezimalziffern, um die Anzahl der Objekte im Repository abzudecken.
Jede hexadezimale Zahl (4 Bits), die wir dem verkürzten Namen hinzufügen, ermöglicht es uns, viermal so viele Objekte (2 Bits) im Repository zu haben.

Siehe commit e6c587c (01. Oktober 2016) von Linus Torvalds (torvalds) .
Siehe commit 7b5b772 , commit 65acfea (01. Oktober 2016) von Junio ​​C Hamano (gitster) .
(Zusammengeführt von Junio ​​C Hamano - gitster - in commit bb188d0 , 03. Oktober 2016)

Diese neue Eigenschaft (die einen vernünftigen Standardwert für den SHA1-Abkürzungswert errät) wirkt sich direkt darauf aus, wie Git seine eigene Versionsnummer für die Veröffentlichung berechnet .

121
VonC

Dies wird als Geburtstagsproblem bezeichnet.

Für Wahrscheinlichkeiten kleiner als 1/2 kann die Kollisionswahrscheinlichkeit angenähert werden als

p ~ = (n2)/(2 m)

Dabei ist n die Anzahl der Elemente und m die Anzahl der Möglichkeiten für jedes Element.

Die Anzahl der Möglichkeiten für einen Hex-String beträgt 16c Dabei ist c die Anzahl der Zeichen.

Also für 8 Zeichen und 30K Commits

30 K ~ = 215

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

Erhöhung auf 12 Zeichen

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

27
plugwash

Diese Frage wurde beantwortet, aber für alle, die nach Mathe suchen - es heißt Geburtstagsproblem ( Wikipedia ).

Es geht um die Wahrscheinlichkeit, dass zwei (oder mehr) Personen aus einer Gruppe von N Personen am selben Tag im Jahr Geburtstag haben. Dies ist analog zu wahrscheinlich zwei (oder mehr) Git-Commits aus dem Repository mit insgesamt N Commits mit demselben Hash-Präfix der Länge X.

Schauen Sie sich die Wahrscheinlichkeitstabelle an . Zum Beispiel für einen Hash-Hex-String mit der Länge 8 beträgt die Wahrscheinlichkeit einer Kollision 1%, wenn das Repository nur etwa 9300 Elemente enthält (git-Commits). Für 110 000 Commits beträgt die Wahrscheinlichkeit 75%. Wenn Sie jedoch eine hexadezimale Zeichenfolge mit der Länge 12 haben, liegt die Kollisionswahrscheinlichkeit in 100 000 Commits unter 0,1%.

11
Messa

Git Version 2.11 (oder vielleicht 2.12?) Enthält eine Funktion, die die Anzahl der in Kurzbezeichnern verwendeten Zeichen (z. B. git log --oneline) An die Größe des Projekts anpasst. Sobald Sie eine solche Version von Git verwenden, kann die Antwort auf Ihre Frage lauten: "Wählen Sie, welche Länge Git Ihnen mit git log --oneline Gibt, es ist sicher genug".

Weitere Informationen finden Sie unter Ändern der Standardeinstellung für "core.abbrev" - Diskussion in Git Rev News Edition 2 und commit bb188d00f7 .

2
Matthieu Moy