Perché git usa gli hash invece dei numeri di revisione?

76

Mi sono sempre chiesto perché Git preferisce gli hash rispetto ai numeri di revisione. I numeri di revisione sono molto più chiari e più facili da riferire (secondo me): c'è una differenza tra dire a qualcuno di dare un'occhiata alla revisione 1200 o commettere 92ba93e! (Solo per fare un esempio).

Quindi, c'è qualche motivo per questo design?

    
posta Max Beikirch 19.07.2013 - 16:05
fonte

6 risposte

112

Un numero di revisione singolo e monotonicamente crescente ha senso solo per un sistema di controllo della versione centralizzato, in cui tutte le revisioni fluiscono verso un singolo luogo in grado di tracciare e assegnare numeri. Una volta entrati nel mondo DVCS, in cui esistono numerose copie del repository e le modifiche vengono estratte da e inviate a loro in flussi di lavoro arbitrari, il concetto non si applica. (Ad esempio, non c'è un posto dove assegnare i numeri di revisione - se forzo il tuo repository e decidi dopo un anno di ritirare le mie modifiche, in che modo un sistema può garantire che i nostri numeri di revisione non siano in conflitto?)

    
risposta data 19.07.2013 - 16:14
fonte
40

Hai bisogno di hash in un sistema distribuito. Supponiamo che tu e un collega lavoriate entrambi sullo stesso repository e entrambi commettete una modifica localmente e poi la spingete. Chi ottiene il numero di revisione 1200 e chi è il numero di revisione 1201 dato che nessuna delle parti ha conoscenza reciproca? L'unica soluzione tecnica realistica è creare un hash delle modifiche usando un metodo conosciuto e collegare le cose in base a quello.

È interessante notare che HG supporta i numeri di versione ma sono esplicitamente una funzione solo locale: il tuo repository ha un set, il repository del tuo collega avrà un set diverso a seconda di come sono stati spinti e tirati. Tuttavia, rende l'uso della riga di comando un po 'più amichevole di Git.

    
risposta data 19.07.2013 - 16:15
fonte
34

Integrità dei dati.

Sono rispettosamente in disaccordo con le risposte attuali. Gli hash non sono necessari per un DVCS, vedi il modo Bazaar . Potresti fare altrettanto con qualsiasi altro tipo di identificatore univoco globale. Gli hash sono una misura per garantire l'integrità dei dati: rappresentano un riassunto delle informazioni contenute nell'oggetto (commit, alberi, ...) a cui fa riferimento l'hash. Modifica del contenuto senza alterare l'hash (ovvero un attacco preimage o attacco di collisione ) è ritenuto difficile, anche se non impossibile. (Se sei interessato a questo, dai un'occhiata al documento del 2011 di Marc Stevens ) .

Quindi, riferirsi agli oggetti con il loro hash SHA permette di controllare se il contenuto è stato manomesso. E, dato che sono (quasi) garantiti come unici, possono essere usati anche come identificatori di revisione, in modo conveniente.

Vedi Capitolo 9 del libro Git per maggiori dettagli.

    
risposta data 19.07.2013 - 22:08
fonte
8

In parole semplici:

  • Gli hash devono essere quasi universalmente unici. NON è garantito ma è estremamente improbabile che vengano generati gli stessi SHA per contenuti diversi. In termini pratici per un determinato progetto puoi trattarlo come unico.
  • Con i numeri di revisione dovresti usare uno spazio dei nomi per fare riferimento in modo specifico alla revisione 1200.
  • Git può funzionare sia distribuito che centralizzato. Quindi come si ottengono i numeri di revisione corretti e unici?
  • Anche l'uso dei numeri di revisione creerebbe la falsa impressione che le versioni più recenti debbano avere numeri più alti, e questo non sarebbe vero a causa di ramificazioni, fusioni, rifondazioni, ecc.
  • Hai sempre la possibilità di inserire tag in commit.
risposta data 19.07.2013 - 16:20
fonte
4

In termini matematici:

risposta data 22.07.2013 - 22:11
fonte
1

Hash non è la soluzione unica per VCS distribuiti. Ma quando si tratta di un sistema distribuito, è possibile registrare solo l'ordinamento parziale degli eventi. (Per VCS, l'evento può essere un commit.) Ecco perché è impossibile mantenere un numero di revisione monotonicamente crescente. Di solito adottiamo qualcosa come clock (o timestamp vettoriale) per registrare tale relazione parziale-ordinata . Questa è la soluzione utilizzata in Bazaar .

Ma perché Git non usa l'orologio vettoriale ma l'hash? Penso che la causa principale sia cherry-pick . Quando eseguiamo cherry-pick su un repository, l'ordinamento parziale dei commit sta cambiando. Alcuni orologi vettore di commit devono essere riassegnati per rappresentare il nuovo ordine parziale. Tuttavia, tale riassegnazione nel sistema distribuito indurrebbe orologi vettoriali inconsistenti. Questo è il vero problema con cui gli hash si confrontano.

    
risposta data 07.05.2015 - 10:31
fonte

Leggi altre domande sui tag