Unisci correzioni di bug dal tronco nei vecchi rami

7

Ora stiamo passando da svn a git (dopo un anno passato a convincere le persone, yay!) nella mia azienda.

Finora, questo è tutto per il meglio, ma c'è una piccola cosa che abbiamo attualmente nel nostro flusso di lavoro che non riesco a trovare un buon equivalente.

Attualmente, tutti i nostri sviluppatori lavorano nel master. Una volta ogni trimestre, si dirama il master nel ramo X.x, che in seguito diventerà la nostra ultima versione. Ciò significa che il nostro repository SVN si presenta così:

  • tronco
  • rami
    • 3.8
    • 4.1
    • 4.2
    • ...

In realtà non usiamo i tag.

Di tanto in tanto, è stata rilevata una correzione rapida dei problemi.

Il modo attuale per farlo è:

  • Risolvilo nel master
  • SVN unisci l'intervallo di commit pertinente ai rami pertinenti (forse la nostra ultima versione, forse di più).

Siamo nel settore spaziale, quindi le nostre filiali sono longeve e il processo di aggiornamento dei clienti è piuttosto lungo, motivo per cui fino ad ora abbiamo lavorato così.

Ora, come sarebbe un buon equivalente in git?

Finora, ho cercato di correggere il bug in un ramo generato dal master, e quindi unire questo ramo nuovamente in master e in 4.3 (ad esempio). Il risultato è che il ramo dell'aggiornamento rapido contiene la cronologia principale e tutti i commit tra master e 4.3 vengono uniti, cosa che non vogliamo.

Cose a cui potrei pensare finora:

  • Ho esaminato il riuscito metodo Git Workflow e la loro soluzione è quella di correggere il bug nel ramo di rilascio e unirlo indietro invece del contrario. Questo potrebbe funzionare nel nostro caso, ma sarebbe piuttosto ingombrante perché ci richiederebbe di conoscere già il ramo più vecchio in cui vogliamo correggere il bug prima di correggere effettivamente il bug.
  • Un'altra soluzione è quella di correggere in master, quindi selezionare cherry commit the commit (come facciamo oggi per svn merge). La cosa fastidiosa qui è che in questo caso perdiamo la storia di ciò che è stato fuso là dove, dal momento che i picchi di ciliegie sembrano nuovi commit e perdiamo la relazione.

Quindi qual è il modo "buono" per farlo? Dovremmo correggere i commit nella cronologia o selezionare in modo manuale e tenere traccia manualmente di ciò che è stato unito o anche di qualcos'altro?

Se hai poca esperienza di produzione con git, quindi sono sicuro che mi sia sfuggito qualcosa.

    
posta jlengrand 15.12.2015 - 12:46
fonte

1 risposta

7

Git Flow presuppone che tu abbia un'unica versione supportata, con il ramo master che punta sempre all'ultima versione. Dal momento che supporti più versioni contemporaneamente, non puoi copiare quel flusso di lavoro 1: 1. Nvie's Git Flow è un ottimo esempio di strategia di ramificazione, ma devi adattarlo alle tue esigenze. Ancora più importante, avrai più rami di rilascio attivi.

Quando identificherai un bug, dovrai eseguire alcuni test per determinare tutte le versioni interessate. Non è sufficiente scrivere prima la correzione, quindi unirla nuovamente ai rami di rilascio come aggiornamento rapido. Di solito, ti ritroverai con una serie continua di versioni interessate. Versioni molto vecchie potrebbero non contenere il bug, le versioni più recenti potrebbero aver risolto il problema per errore. Dovrai verificare il bug su ciascuna versione in modo da poter verificare che sia effettivamente andato dopo la correzione. Se riesci a esprimere il bug come un banco di prova automatizzato, è piuttosto semplice trovare il commit problematico tramite git bisect o eseguire il test per ogni versione:

for release in 3.8 4.1 4.2
do
  git checkout $release
  if ./testcase >release-$release.log
  then echo "$release ok"
  else echo "$release AFFECTED"
  fi
done

Ora, hai scritto la correzione su trunk / master . Questo è problematico perché la parte buggy può essere cambiata tra le versioni, quindi una patch non si applica di solito a una versione precedente. In particolare, il codice in master potrebbe dipendere da qualsiasi funzionalità disponibile in master, che potrebbe non essere presente nelle versioni precedenti. Ha quindi molto senso che un commit Git rimandi alla sua intera storia, non solo al set di modifiche. Quando si fonde, verrà inserita tutta la cronologia da cui dipende.

L'utilizzo di cherry-pick o rebase ignora questa cronologia e registra un nuovo commit con lo stesso changeset, ma una cronologia diversa. Come sottolineato, questo non funzionerà se il tuo codebase è divergente.

La soluzione "corretta" è scrivere la correzione come aggiornamento rapido sulla release meno recente. Quindi, unisci la versione meno recente nella seconda versione meno recente. Di solito, una versione più recente contiene tutti i commit di una versione precedente, quindi questo è OK. Se le cose sono cambiate, ora hai la possibilità di risolvere manualmente il conflitto di fusione. Quindi continui a unire ogni versione nel rilascio successivo fino a quando non hai terminato. Ciò mantiene la storia corretta ed evita un sacco di lavoro non necessario, mentre richiede solo uno sforzo che deve essere comunque speso. In particolare, questa unione incrementale ti avvicina allo stato di sviluppo attuale a piccoli passi.

Come diagramma:

| o normal commit |
| x hotfix        |
| ⇘ merging       |

3.8 --o-----------------x
       \                 ⇘
4.1     o--o--o-----------x'
               \           ⇘
4.2             o--o--o-----x''
                       \     ⇘
develop                 o--o--x'''--o--o
    
risposta data 15.12.2015 - 13:35
fonte

Leggi altre domande sui tag