Creazione del sequenziamento quando si utilizza il controllo della versione distribuita

StackOverflow https://stackoverflow.com/questions/122424

  •  02-07-2019
  •  | 
  •  

Domanda

In questo momento, stiamo usando Perforce per il controllo della versione. Ha la pratica funzionalità di un numero di modifica strettamente crescente che possiamo usare per fare riferimento a build, ad esempio " otterrai la correzione di bug se la tua build è almeno 44902 "

Vorrei passare all'uso di un sistema distribuito (probabilmente git) per semplificare la ramificazione e il lavoro da casa. (Entrambi sono perfettamente possibili con Perforce, ma il flusso di lavoro git presenta alcuni vantaggi.) Quindi anche se "sviluppo tributario" sarebbe distribuito e non si riferirebbe a un sequenziamento di revisione comune, manterremmo comunque un repository master git in cui tutte le modifiche dovrebbero essere introdotte prima che venga creata una build.

Qual è il modo migliore per preservare gli ID di build in costante aumento? Il modo più semplice a cui riesco a pensare è di avere una sorta di hook post-commit che si attiva ogni volta che il repository master viene aggiornato e registra (l'hash di) il nuovo oggetto albero (o oggetto commit? Sono nuovo a git) con un database centralizzato che distribuisce ID. (Dico "database", ma probabilmente lo farei con i tag git e cerco semplicemente il prossimo numero di tag disponibile o qualcosa del genere. Quindi il "database" sarà davvero .git / refs / tag / build-id /.)

Questo è fattibile, ma mi chiedo se ci sia una migliore pratica, o già implementata, o standard / "best practice". modo per raggiungere questo obiettivo.

È stato utile?

Soluzione

Secondo il suggerimento di usare git descrivono . A condizione che tu abbia una sana politica di controllo delle versioni e non fai cose folli con il tuo repository, git descritto sarà sempre monotonico (almeno il più monotonico possibile, quando la cronologia delle revisioni è un DAG anziché un albero) e unico.

Una piccola dimostrazione:

git init
git commit --allow-empty -m'Commit One.'
git tag -a -m'Tag One.' 1.2.3
git describe    # => 1.2.3
git commit --allow-empty -m'Commit Two.'
git describe    # => 1.2.3-1-gaac161d
git commit --allow-empty -m'Commit Three.'
git describe    # => 1.2.3-2-g462715d
git tag -a -m'Tag Two.' 2.0.0
git describe    # => 2.0.0

L'output di git descritto è costituito dai seguenti componenti:

  1. Il tag più recente raggiungibile dall'impegno che si sta chiedendo di descrivere
  2. Il numero di commit tra commit e tag (se diverso da zero)
  3. L'ID (abbreviato) del commit (se il numero 2 è diverso da zero)

# 2 è ciò che rende l'output monotonico, # 3 è ciò che lo rende unico. # 2 e # 3 vengono omessi, quando il commit è il tag, rendendo git descritto adatto anche per le versioni di produzione.

Altri suggerimenti

Il numero monotonicamente crescente corrispondente all'attuale commit potrebbe essere generato con

git log --pretty=oneline | wc -l

che restituisce un singolo numero. Puoi anche aggiungere sha1 corrente a quel numero, per aggiungere unicità.

Questo approccio è migliore di git descritto , perché non richiede l'aggiunta di tag e gestisce automaticamente le unioni.

Potrebbe avere problemi con il rebasing, ma il rebasing è "pericoloso". operazione comunque.

    git rev-list BRANCHNAME --count

questo richiede molte meno risorse rispetto a

    git log --pretty=oneline | wc -l

git tag potrebbe essere sufficiente per quello che ti serve. Scegli un formato di tag che tutti saranno d'accordo a non utilizzare altrimenti.

Nota: quando tagghi localmente, un git push non aggiorna i tag sul server. Usa git push --tags per questo.

Dovresti indagare su git descritto . Fornisce una stringa univoca che descrive il ramo corrente (o qualsiasi ID commit passato) in termini di tag annotato più recente, il numero di commit da quel tag e un ID commit abbreviato del responsabile del ramo.

Presumibilmente hai un singolo ramo in cui esegui rilasci di build controllati. In questo caso, taggerei un commit iniziale con un formato di tag noto e quindi userei git descritto con l'opzione --match per descrivere l'attuale HEAD rispetto a un tag noto. È quindi possibile utilizzare il risultato di git descritto così com'è o se si desidera davvero solo un singolo numero, è possibile utilizzare una regex per tagliare il numero dal tag.

Supponendo che non riavvolgi mai il ramo, il numero di commit seguenti identificherà sempre un punto unico nella storia del ramo.

es. (usando bash o simili)

# make an annotated tag to an early build in the repository:
git tag -a build-origin "$some_old_commitid"

# describe the current HEAD against this tag and pull out a build number
expr "$(git describe --match build-origin)" : 'build-origin-\([0-9]*\)-g'

Userei " Etichette " Crea un'etichetta ogni volta che hai una build di successo (o anche non riuscita) e sarai in grado di identificarla per sempre. Non è esattamente lo stesso, ma fornisce quei numeri di build, fornendo comunque i vantaggi dello sviluppo distribuito.

Come probabilmente saprai, git calcola un hash (un numero) che identifica in modo univoco un nodo della cronologia. L'uso di questi, sebbene non siano strettamente in aumento, sembra che sarebbe abbastanza buono. (Ancora meglio, sempre corrispondono alla fonte, quindi se hai l'hash, hai lo stesso codice.) Sono numeri grandi, ma per lo più puoi cavartela con circa 6 di cifre iniziali.

Ad esempio,

  

Quel bug è stato corretto su 064f2ea ...

Con Mercurial puoi usare il seguente comando:

# get the parents id, the local revision number and the tags
[yjost@myhost:~/my-repo]$ hg id -nibt
03b6399bc32b+ 23716+ default tip

Vedi hg ident

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top