Git: rebasing su un refactoring che interessa il ramo di rebase target

6

Diciamo che ho una funzione (argomento) ramo che tengo rebased in cima al mio ramo di sviluppo. Durante il corso del progetto (prima di unirmi al mio branch di funzionalità), decido che devo apportare un grande refactoring al mio progetto (ad esempio, dopo aver aggiornato un modulo di 3 parti).

Quindi eseguo questo grande refactoring sul mio ramo di sviluppo. Ora voglio rebase il mio branch di funzionalità in modo da poter trarre vantaggio dal mio refactoring.

Il problema

Ci sono ancora cose nel mio ramo delle funzioni che devono essere rifatte per adattarle alle modifiche apportate al mio ramo di sviluppo.

Dovrei:

  1. Torna alla cronologia del ramo di funzione cercando di modificare i commit (con rebase -i ) per far apparire il ramo come se tutto il lavoro fosse stato fatto dopo il refactoring.

    • Il vantaggio è che mantiene pulita la cronologia.
    • Lo svantaggio è che questo può richiedere molto tempo se le modifiche apportate al ramo di sviluppo causano la necessità di apportare molte modifiche nel ramo della funzione.
  2. Correggere le cose che devono essere refactored nel mio branch di funzionalità e fare un commit per questo.

    • Il vantaggio qui è che sarà molto più facile identificare e correggere le cose che devono essere riparate
    • Lo svantaggio è che ora l'albero avrà due in commit per il refactoring. Uno per il refactor fatto per l'intero ramo di sviluppo, e un commit più piccolo fatto per il ramo della funzione, una volta fuso in esso sembrerà un po 'strano.

Quale strategia devo seguire?

Un esempio

Diciamo sul ramo di sviluppo rinominare functionA in functionB .

Ora nel mio branch di funzionalità non ho mai modificato il file contenente functionA (ora functionB in sviluppo). Quindi, quando esco rebase development mentre sul mio ramo delle funzionalità, si ribalta in modo pulito.

Il problema è che se ho mai effettuato una chiamata a functionA nel mio ramo di funzione, ora non funzionerà più poiché è stato rinominato functionB .

Ora, dovrei fare una ricerca e sostituire per functionA - > functionB e crea un commit sul ramo di funzione (opzione 2). O dovrei tornare indietro nella mia cronologia, trovare dove ho introdotto la chiamata a functionA e riscrivere il commit in modo che venga introdotto come chiamata functionB (opzione 1)?

    
posta Evan Purkhiser 24.01.2013 - 00:19
fonte

4 risposte

4

Nessuno

L'opzione 1 suona come un sacco di lavoro non necessario. Perché non vuoi nascondere il fatto che questo codice è stato scritto prima del refactoring di dev ?

Un altro svantaggio con l'opzione 2: dopo il rebase avrai molti commit eventualmente non lavorativi prima del commit del 2o refactoring. Questo ti darà problemi quando bisecerai da quando quei commit potrebbero essere non testabili.

Opzione 3: Unisci dev branch in feature branch.

  • Pro: otterrai il rectoring da dev e potresti refactoring il resto del ramo feature nell'unione per ottenere un progetto funzionante.
  • Pro: nessun commit non viene verificato. (supponendo che i commit già effettuati siano stati testati).
  • Contro: non potrai continuare la rebasazione su dev branch.
risposta data 31.01.2013 - 20:40
fonte
1

Sembra che la rivoluzione del git abbia creato una nuova nevrosi chiamata ansietà della storia del commit. Nessuno oltre a te importa ciò che è nei tuoi impegni. Basta fare il lavoro nel modo più efficiente possibile. Quindi puoi utilizzare il tempo che hai salvato per correggere un bug o aggiungere una funzionalità.

    
risposta data 24.01.2013 - 04:58
fonte
0

Non sei sicuro del motivo per cui dovresti eseguire un rebase -i. Vorrei solo fare un rebase e correggere i problemi non appena entrano in funzione.

Trovo che riparare uno e uno sia più facile che correggere ogni errore dopo le parole. Puoi anche assicurarti, tra ogni commit, che i tuoi test siano ancora eseguiti (dato che hai dei test).

Infine, trovo che 2) sia problematico se prevedi di continuare a rebasing in futuro, se la tua funzione non è ancora stata eseguita. Rifondare in un'unione non è davvero qualcosa che farei se potessi evitarlo. Se la funzione è terminata e non ti interessa molto della cronologia, puoi semplicemente unire.

Conclusione: Vorrei rebase personalmente, senza il -i, e correggere ogni commit. La ragione è che trovo abbastanza utile un registro ordinato e spesso sento che è il modo più semplice per farlo.

EDIT: Con il tuo esempio, direi che dipende. Se ci sono una quantità enorme di commit, hai chiamato functionA un sacco di volte, ed è fondamentalmente un enorme problema rebase a ogni singolo commit, probabilmente ricorreremo a fare solo una search-replace in un singolo commit. Se avessi saputo che c'erano solo pochi punti e che la rifocalizzazione sarebbe stata facile, avrei rebase.

Dato che chiedi, immagino che il primo sia la situazione in cui ti trovi, e avrei comunque pensato a quanto dolore sarà per ripulire il registro.

    
risposta data 24.01.2013 - 09:19
fonte
0

Fondamentalmente, non dovresti usare i rami git per i rami di funzionalità.

link

link

In effetti vedo che questo è il motivo decisivo per cui Feature Branching è una cattiva idea. Una volta che una squadra ha paura di rifattarsi per mantenere il proprio codice in buona salute, è in una spirale discendente senza una fine carina.

Nel testo citato, Martin Fowler usa "Feature Branching" per indicare specificamente "l'uso della ramificazione di dvcs per gestire lo sviluppo di feature di grandi dimensioni in un modo in cui un ramo di dvcs esegue il mapping su una caratteristica". Che molte persone fanno. Alcune di queste persone si trovano in un ambiente in cui non hanno mai realmente bisogno di refactoring, alcune non l'hanno fatto abbastanza a lungo da colpire i problemi, alcuni hanno sviluppato strumenti o procedure su git per aggirare i problemi ( link ), mentre altri stanno semplicemente negando quanto problemi causano loro.

Il fatto è che, proprio perché un concetto astratto e una caratteristica di uno strumento hanno lo stesso nome, non li rendono una buona corrispondenza reciproca. Come stai scoprendo, non c'è davvero un buon modo per utilizzare i due insieme, solo una varietà di modi meno cattivi.

Quindi, supponendo che tu abbia davvero bisogno di branch di funzionalità, quindi guarda attraverso le funzionalità il tuo tooling e il supporto della piattaforma e trova una corrispondenza migliore.

Rimanere con git, usare le forche e le richieste di pull è una strategia sempre più comune:

link

Nel peggiore dei casi, anche l'umile dichiarazione if [config-setting] (nota come 'funzionalità di attivazione / disattivazione') è molto probabile che sia un risparmio di tempo e un aumento di qualità rispetto a dove ti trovi ora.

    
risposta data 17.02.2013 - 01:21
fonte

Leggi altre domande sui tag