Strategia per la revisione del codice prima di unire al master dai rami delle caratteristiche


22

Io e il mio team utilizziamo i rami delle funzionalità (con git). Mi chiedo quale sia la migliore strategia per la revisione del codice prima di unire al master.

  1. Controllo un nuovo ramo dal master, chiamiamolo fb_ # 1
  2. Mi impegno un paio di volte e che voglio ricollegarlo al maestro
  3. Prima di unire qualcuno dovrebbe fare una revisione del codice

Ora ci sono 2 possibilità:

1 °

  1. Mi fondo master per fb_ 1 # ( non fb_ # 1 al master) per renderlo il più up-to-date il più possibile
  2. Un compagno di squadra esamina le modifiche tra la testa master e la testa fb_ # 1
  3. Se fb_ # 1 è ok, uniamo fb_ # 1 al master
  4. Pro: nessun codice obsoleto in revisione
  5. Contro: se qualcun altro fonde qualcosa tra "1" e "2." le sue modifiche vengono visualizzate nella recensione, sebbene appartengano a un'altra recensione.

2 °

  1. Un compagno di squadra esamina le modifiche tra il punto di checkout (git merge-base master fb_ # 1) e fb_ # 1 head
  2. Pro: vediamo esattamente cosa è stato cambiato durante il lavoro sul ramo delle caratteristiche
  3. Contro: nella revisione potrebbe apparire del codice obsoleto.

In che modo pensi sia meglio e perché ? Forse esiste un altro approccio più adatto?

Risposte:


9

C'è una variazione della tua prima opzione:

  1. unisci master a fb_ # 1 (non fb_ # 1 a master) per renderlo il più aggiornato possibile
  2. Un compagno di squadra esamina le modifiche tra master nel punto in cui ti sei unito e testa fb_ # 1
  3. Se fb_ # 1 è ok, uniamo fb_ # 1 al master
  4. verifica rapidamente che l'unione sia corretta

per esempio.

... ma -- ... -- mm -- ... -- mf  <- master
      \            \         /
       f1 ... fn -- fm -----      <-- fb_#1

dove:

  • ma è l'antenato del maestro e fb_ # 1.
  • fn è l'ultima modifica sul tuo ramo
  • mm è il commit che era master / HEAD nel momento in cui ti sei unito al tuo ramo (dando fm ).

Quindi, si confrontano mm e fm nella revisione iniziale, quindi si verifica rapidamente dopo aver unito nuovamente mf per assicurarsi che nulla di significativo sia cambiato sul master durante i passaggi 1-3. Questo sembra avere tutti i pro e nessuno dei contro per la revisione iniziale.

Ciò presuppone che la revisione sia rapida rispetto alla normale frequenza delle modifiche inviate al master, quindi fm -> mf sarebbe spesso un avanzamento veloce.

In caso contrario , per qualsiasi motivo, i contro passeranno dalla revisione iniziale alla revisione post-unione e potrebbe essere più semplice fondersi direttamente sul master e fare un'unica recensione lì.


Come ottengo "il punto che hai unito"? "Git merge-base master head" sarà ok o mostrerà il punto di ramificazione iniziale?
Andrzej Gis,

A meno che non si aggiorni deliberatamente master dopo l'unione, sarà solo master.
Inutile il

Sì, ma come ottenere quel punto se qualcun altro lo aggiorna?
Andrzej Gis,

Quando sei sul ramo fb, usa git show HEAD. Dal momento che sarà la fusione commit fm , elencherà entrambi i genitori. Quindi, hai l'hash di mm . In alternativa, puoi vedere banalmente il genitore gitko qualsiasi altro browser git
Inutile

13

3 °

  • È rebase il ramo su master per entrambi make up-to-date e mantenere i cambiamenti separano.

    Questo crea una nuova storia del ramo. Saranno nuove revisioni con nuovi ID che avranno lo stesso contenuto, ma saranno derivate dall'ultimo master e non si collegheranno alle vecchie revisioni. Le vecchie revisioni sono ancora accessibili in "reflog" se è necessario fare riferimento ad esse, ad esempio perché si scopre di aver commesso un errore nella risoluzione dei conflitti. Inoltre sono inutili. Git di default elimina il reflog dopo 3 mesi e scarta le vecchie revisioni.

  • Si utilizza rebase interattivo ( git rebase -ie git commit --amend) per riordinare, modificare e ripulire le modifiche in modo che ognuna esegua una modifica logicamente chiusa.

    Questo crea di nuovo una nuova cronologia, questa volta con l'ulteriore vantaggio di poter ristrutturare le modifiche per avere più senso durante la revisione.

  • Professionisti:

    • nessun codice obsoleto in revisione
    • vediamo esattamente cosa è cambiato durante il lavoro sul ramo delle caratteristiche
  • Contro:
    • un po 'più di lavoro
    • devi fare attenzione a non rifare tutto ciò che è già unito o che hai condiviso e il destinatario non si aspetta che venga riavvolto.

Di solito, il lavoro extra implica di rivedere prima il codice da soli e che colpirà anche molti problemi.

Questo è ciò che fanno Linux e Git. E non è insolito vedere serie di 20-25 patch sottoposte a revisione e riscritte più volte in quei progetti.

In realtà Linux lo ha fatto fin dall'inizio del progetto quando il loro controllo di versione della scelta era tarball e patch. Quando molti anni dopo Linus decise di creare git, fu la ragione principale per implementare il rebasecomando e la sua variante interattiva. Anche per questo git ha una nozione separata di autore e committer . L'autore è il primo a creare la revisione e il committer è l'ultimo a toccarla. Poiché sia ​​in Linux che in Git le patch sono ancora inviate via e-mail, i due non sono quasi mai la stessa persona.


1
+1 anche l'OP non ha chiesto i passaggi successivi, ma per mettere la tua caratteristica in master puoi usare una merge --no-ffche mostrerà chiaramente quel ramo sul master invece della funzione che sta scomparendo nel resto degli commit
stijn

@stijn: --no-ffha i lati positivi e negativi. Personalmente trovo più rumore di ogni altra cosa. YMMV.
Jan Hudec,

sì, è una questione di preferenza. Se il master è normalmente pulito e diretto, non mi dispiace che le grandi funzionalità abbiano una 'bolla' separata. Se il master è già un disastro, la no-ff non fa che peggiorare la situazione
stijn

Vorrei poter accettare la modalità di una risposta. Una soluzione ibrida sarebbe l'ideale. Usare rebase e confrontarlo con il punto di diramazione sembra essere il modo migliore di procedere.
Andrzej Gis,

Secondo Con - Non penso che tu possa farlo se hai già condiviso la tua filiale con nessuno. Quando riscrivi la cronologia ci saranno incoerenze.
sixtyfootersdude,

4

Esiste in realtà una terza possibilità, e molto probabilmente molte altre, poiché GIT è più un'implementazione di un framework SCM che un'implementazione di una metodologia SCM. Questa terza possibilità è basata su rebase.

Il rebasesottocomando GIT accetta una serie di commit (in genere dal punto di diramazione alla punta del ramo di argomento topic) e li riproduce altrove (in genere alla punta del ramo di integrazione, ad esempio master). Il rebasesottocomando produce nuovi commit, il che offre l'opportunità di riorganizzare i commit in una forma che è più facile da rivedere. Ciò produce una nuova serie di commit, simile a quello che topicera una volta ma che appariva radicato nella parte superiore del ramo di integrazione. Questo nuovo ramo è ancora chiamato topicda GIT, quindi il vecchio riferimento viene scartato. Etichetta in modo informale topic-0lo stato originale della tua filiale topic-1e così via i suoi vari refactoring.

Ecco il mio suggerimento per il tuo topicramo:

  1. (Passaggio facoltativo) Reimpostare interattivamente il ramo dell'argomento topicsul suo punto di diramazione (vedere l' --fixupopzione per commite le opzioni -ie --autosquashsu rebase), che offre l'opportunità di riscrivere i commit in un modo che sia più facile da rivedere. Ciò si traduce in un ramo topic-1.

  2. Rifiuta il ramo tematico nella parte superiore del ramo di integrazione, è simile a un'unione, ma "non inquina" la storia con un'unione che è semplicemente un artefatto di ingegneria del software. Ciò si traduce in un ramo topic-2.

  3. Invia topic-2a un compagno di squadra che lo rivede sulla punta di master.

  4. Se topic-2va bene, quindi uniscilo al master.

NOTA I rami — dove ramo si riferisce all'albero di commit — saranno tutti chiamati uguali da GIT, quindi, alla fine del processo, solo il ramo topic-2ha un nome in GIT.

Professionisti:

  • Nessun codice obsoleto in revisione.
  • Nessuna recensione falsa di "fusioni straniere" (il fenomeno che hai descritto al 1 °).
  • L'opportunità di riscrivere si impegna in modo pulito.

Contro:

  • Invece di un ramo topic-0, ci sono tre artefatti rami topic-0, topic-1e topic-2che vengono creati nella struttura di commit. (Anche se in qualsiasi momento, solo uno di loro ha un nome in GIT.)

Nel tuo primo scenario «se qualcuno fondesse qualcosa tra" 1 " e "2." »si riferisce al tempo che intercorre tra la creazione del punto di diramazione e il momento in cui si decide di unire. In questo scenario «se qualcuno fondesse qualcosa tra" 1 " e "2." »si riferisce al tempo che intercorre tra il rebase e l'unione, che di solito è molto breve. Pertanto, nello scenario da me fornito, è possibile «bloccare» il masterramo per il momento dell'unione senza disturbare in modo significativo il flusso di lavoro, mentre non è pratico nel 1 ° scenario.

Se stai facendo revisioni sistematiche del codice, è probabilmente una buona idea riorganizzare gli commit in modo adeguato (passaggio facoltativo).

La gestione degli artefatti del ramo intermedio presenta una difficoltà solo se li si condivide tra i repository.


Non ci dovrebbe essere nessuna topic-0, topic-1e topic-2rami. Il secondo il rebase è completo, la versione precedente è irrilevante. Quindi tutto ci sarebbe è topic@{1}, topic@{2}, topic@{yesterday}, topic@{3.days.ago}ecc per salvare il culo nel caso in cui si trova si avvitato la risoluzione dei conflitti nel rebase.
Jan Hudec,

I tre rami esistono, ma non hanno un nome (nessun riferimento). Forse dovrei sottolineare questo.
Michael Le Barbier Grünewald,

Le revisioni esistono e sono indicate da voci di reflog. Ma come rami ce n'è solo uno topic,. Perché branch in git è solo il nome.
Jan Hudec,

Come mi salva da "fusioni straniere"? Cosa succede se qualcuno si unisce al master dopo che ho inviato l'argomento 2 a un compagno di squadra e che il compagno di squadra lo rivede sulla punta del maestro?
Andrzej Gis,

@JanHudec In ogni momento, c'è solo un ramo chiamato topicin GIT, è sempre uno dei rami (un ramo come nel commettere albero, non come riferimento GIT) ho etichettato topic-0, topic-1, topic-2.
Michael Le Barbier Grünewald,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.