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

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 per padroneggiare.

  1. Controllo un nuovo ramo dal master, chiamiamolo fb_ # 1
  2. Mi impegno alcune volte e poi voglio unirle nuovamente al master
  3. Prima di unire qualcuno, si suppone che effettui una revisione del codice

Ora ci sono 2 possibilità:

prima

  1. Unisco master in fb_ # 1 ( not fb_ # 1 in master) per renderlo il più aggiornato possibile
  2. Un compagno di squadra rivede le modifiche tra master head e fb_ # 1 head
  3. Se fb_ # 1 è ok, uniamo fb_ # 1 a master
  4. Pro: nessun codice obsoleto in revisione
  5. Contro: se qualcun altro unisce qualcosa tra "1." e "2." le sue modifiche appaiono nella recensione, sebbene appartengano a un'altra recensione.

secondo

  1. Un compagno di squadra rivede le modifiche tra il punto di pagamento (git merge-base master fb_ # 1) e fb_ # 1 testa
  2. Pro: vediamo esattamente cosa è stato cambiato durante il funzionamento del ramo di funzione
  3. Contro: alcuni codici obsoleti potrebbero apparire nella recensione.

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

    
posta Andrzej Gis 15.10.2013 - 11:47
fonte

3 risposte

9

C'è una variante della tua prima opzione:

  1. Unisci master a fb_ # 1 (non fb_ # 1 a master) per renderlo il più aggiornato possibile
  2. Un commento di un compagno di squadra cambia tra master nel punto in cui sei fuso e fb_ # 1 testa
  3. Se fb_ # 1 è ok, uniamo fb_ # 1 a master
  4. verifica rapidamente che l'unione sia corretta

ad es.

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

dove:

  • ma è l'antenato di master e fb_ # 1.
  • fn è l'ultima modifica sul tuo ramo
  • mm è il commit che era master / HEAD al momento della fusione nel tuo ramo (dando fm ).

Quindi, confronta mm e fm nella tua recensione iniziale, e poi controlla rapidamente dopo aver unito mf per assicurarti che nulla di significativo cambi su master durante i passaggi 1-3. Questo sembra avere tutti i pro e nessuno dei contro per la revisione iniziale.

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

Se questo è non il caso, per qualsiasi motivo, i contro passeranno dalla revisione iniziale alla revisione post-merge, e potrebbe essere più semplice fondersi direttamente sul master e fare una recensione unica lì.

    
risposta data 15.10.2013 - 12:50
fonte
13

3

  • Hai rebase il ramo sul master per renderlo aggiornato e mantenere separate le modifiche.

    Questo crea una nuova cronologia del ramo. Saranno nuove revisioni con nuovi ID che avranno lo stesso contenuto, ma saranno derivati dall'ultimo master e non saranno collegati alle vecchie revisioni. Le vecchie revisioni sono ancora accessibili in "reflog" se è necessario farvi riferimento ad es. perché trovi che hai fatto errori nella risoluzione dei conflitti. Oltre a questo sono inutili. Git di default elimina il reflog dopo 3 mesi e scarta le vecchie revisioni.

  • Utilizza rebase interattivo ( git rebase -i e git commit --amend ) per riordinare, modificare e ripulire le modifiche in modo che ciascuna di esse esegua un cambiamento logicamente chiuso.

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

  • Pro:

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

Solitamente il lavoro extra significa che prima riesci a rivedere il codice da solo e che anche questo accetterà molti problemi.

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

In realtà Linux lo ha fatto sin dall'inizio del progetto quando il loro controllo di versione era tarball e patch. Quando molti anni dopo Linus decise di creare git, fu la ragione principale per implementare il comando rebase e la sua variante interattiva. Anche per questo git ha una nozione separata di author e committer . L'autore è chi per primo ha creato la revisione e il committer è chi l'ha toccato per l'ultima volta. Dato che sia in Linux che in Git le patch vengono ancora inviate per e-mail, i due non sono quasi mai la stessa persona.

    
risposta data 15.10.2013 - 13:14
fonte
4

In realtà esiste una terza possibilità, e molto probabilmente molte altre, dal momento che GIT è più un'implementazione di un framework SCM che un'implementazione di una metodologia SCM. Questa terza possibilità è basata su rebase .

Il sottocomando rebase GIT prende una serie di commit (in genere dal punto di diramazione alla punta del ramo dell'argomento topic ) e li ripete da qualche altra parte (tipicamente sulla punta del tuo ramo di integrazione, ad esempio master ). Il sottocomando rebase produce nuovi commit, che danno l'opportunità di riorganizzare i commit in una forma che è più facile da recensire. Questo produce una nuova serie di commit, simile a ciò che topic era, ma che appariva radicata nella parte superiore del ramo di integrazione. Questo nuovo ramo è ancora chiamato topic da GIT, quindi il vecchio riferimento viene scartato. Etichetta in modo informale topic-0 lo stato originale del tuo ramo e topic-1 e così via nei vari refactoring.

Ecco il mio suggerimento per il tuo ramo topic :

  1. (Passaggio facoltativo) Rebase in modo interattivo il tuo ramo dell'argomento topic sul suo punto di diramazione (vedi l'opzione --fixup per commit e -i e --autosquash opzioni su rebase ), che ti dà l'opportunità di riscrivere i tuoi commit in un modo che è più facile da recensire. Ciò si traduce in un ramo topic-1 .

  2. È possibile rebase il ramo dell'argomento nella parte superiore del ramo di integrazione, è simile a fare un'unione, ma la cronologia "non inquina" con un'unione che è semplicemente un artefatto di ingegneria del software. Ciò si traduce in un ramo topic-2 .

  3. Invia topic-2 a un compagno di squadra che lo rivede in base al suggerimento di master .

  4. Se topic-2 va bene, uniscilo in master.

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

Pro:

  • Nessun codice obsoleto in revisione.
  • Nessuna falsa "straniera fonde" recensioni (il fenomeno che hai descritto in 1a).
  • Opportunità di riscrivere i commit in modo pulito.

Contro:

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

Nel tuo primo scenario «se qualcuno ha unito qualcosa tra" 1. " e "2." »si riferisce al tempo che passa tra la creazione del punto di diramazione e il momento in cui si decide di unire. In questo scenario «se qualcuno ha unito qualcosa tra" 1. " e "2." »si riferisce al tempo che si estende tra il rebase e l'unione, che di solito è molto breve. Pertanto, nello scenario che fornisco, puoi «bloccare» il ramo master per il tempo dell'unione senza disturbare in modo significativo il tuo flusso di lavoro, mentre non è pratico nel primo scenario.

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

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

    
risposta data 15.10.2013 - 13:15
fonte

Leggi altre domande sui tag