2015-09-04 29 views
7

Il flag --abbrev-commit può essere utilizzato insieme a git log e git rev-list per mostrare prefissi parziali invece degli hash SHA-1 di 40 caratteri di oggetti commit. Secondo i Pro Git book,Nel mio repository, per quanto tempo deve essere il prefisso hash più lungo per evitare qualsiasi sovrapposizione?

il valore di default di utilizzare sette personaggi, ma li rende più a lungo se necessario per mantenere l'SHA-1 non ambigua [...]

Inoltre, brevi SHAs sono almeno 4- personaggio lungo Sempre secondo il libro Pro Git,

In genere, da otto a dieci caratteri sono più che sufficienti per essere unici all'interno di un progetto.

Ad esempio, il kernel Linux, che è un progetto piuttosto grande con oltre 450k commit e 3,6 milioni di oggetti, non ha due oggetti i cui SHA-1 si sovrappongono più dei primi 11 caratteri.

Dal momento che la lunghezza del prefisso più lungo necessario evitare ogni sovrapposizione tra tutti gli hash prefisso di oggetti commit (11, nel caso del kernel di Linux) è un indicatore grezzo delle dimensioni di un pronti contro termine, mi piacerebbe determinare a livello di codice la quantità corrispondente nel mio repository locale. Come lo posso fare?

+0

Intendi http://stackoverflow.com/a/21015031/3691891? –

+0

@ArkadiuszDrabczyk Non esattamente. Il tuo link fornisce solo un metodo per determinare quanto può essere breve il prefisso di un dato hash di commit per evitare sovrapposizioni con altri hash. Sto chiedendo il massimo della quantità su tutti gli hash di commit nel repository. – Jubobs

+1

Non è * possibile * rigorosamente * determinare la lunghezza del prefisso richiesta senza esaminare tutti i commit in un repository. In linea di principio, un repository potrebbe avere solo due commit identici nei primi 39 caratteri. E la lunghezza richiesta effettiva potrebbe cambiare con il prossimo commit. –

risposta

14

Il seguente script di shell, eseguito in un repository locale, stampa la lunghezza del prefisso più lungo richiesto per impedire qualsiasi sovrapposizione tra tutti gli hash di prefisso degli oggetti commit di quel repository.

MAX_LENGTH=4; 

git rev-list --abbrev=4 --abbrev-commit --all | \ 
    (while read -r line; do 
     if [ ${#line} -gt $MAX_LENGTH ]; then 
     MAX_LENGTH=${#line}; 
     fi 
    done && printf %s\\n "$MAX_LENGTH" 
) 

L'ultima volta che ho curato questa risposta, lo script stampato

6

La sceneggiatura di Jubob è fantastica, con le migliori prestazioni.

Se si vuole avere un'idea della distribuzione di minima-commit-hash di lunghezza, è possibile eseguire questo one-liner:

git rev-list --abbrev=4 --abbrev-commit --all | (while read -r line; do echo ${#line}; done;) | sort -n | uniq -c 

Per la git project sé oggi (git-on-git) , questo produce qualcosa come:

1788 4 
35086 5 
7881 6 
    533 7 
    39 8 
    4 9 

... cedendo commit che possono essere rappresentati in modo unico con un hash -char (o più basso, questo è abbrev minimo di Git), e commit che richiedono -of-40 caratteri dell'hash in ordine per selezionarli in modo univoco.

A titolo di confronto, un progetto molto più grande come il Linux kernel, ha questa distribuzione oggi:

6179 5 
446463 6 
139247 7 
10018 8 
655 9 
41 10 
3  11 

Quindi, con un database di quasi 5 milioni di oggetti e 600k commette, c'è impegna attualmente richiede 11 del 40 cifre esadecimali per distinguerle da tutti gli altri commit.