Strategie per unire 1 anno di sviluppo in Visual Studio

32

Ho un cliente che ha insistito per mantenere separato il nostro nuovo sviluppo dalle filiali principali per l'intero 2016. Avevano 3-4 altri team che lavoravano sull'applicazione a varie capacità. Sono state apportate numerose modifiche di grandi dimensioni (cambiando il modo in cui viene eseguita l'iniezione di dipendenza, la pulizia del codice con ReSharper, ecc.). Ora mi è caduto addosso unire main nella nostra nuova filiale dev per prepararci a spingere i nostri cambiamenti lungo la catena.

Nel mio iniziale pull di unione, TFS ha riportato ~ 6500 file con risoluzione dei conflitti. Alcuni di questi saranno facili, ma alcuni di essi saranno molto più difficili (in particolare alcuni dei javascript, controller API e servizi che supportano questi controller).

C'è un approccio che posso prendere per renderti tutto più facile?

Per chiarire, ho espresso molte preoccupazioni su questo approccio più volte lungo la strada. Il cliente era ed è consapevole delle difficoltà con questo. Poiché hanno scelto di abbreviare il personale del QA (1 tester per 4 sviluppatori, nessun test automatizzato, pochi test di regressione), hanno insistito sul fatto che tenessimo il nostro ramo isolato dai cambiamenti nel ramo principale con la pretesa che ciò ridurrebbe la necessità del nostro tester per conoscere le modifiche apportate altrove.

Uno dei problemi più importanti qui è un aggiornamento alla versione angolare e ad alcuni degli altri software di terze parti - purtroppo non abbiamo trovato un buon modo per costruire questa soluzione finché tutti i pezzi non saranno rimessi a posto.

    
posta user258451 03.01.2017 - 18:31
fonte

4 risposte

37

Ci sarebbe stato un modo semplice che avrebbe tenuto il tuo nuovo sviluppo separato dal ramo principale senza portandoti in questa sfortunata situazione: qualsiasi cambiamento dal tronco avrebbe dovuto essere unito al tuo ramo dev < strong> su base giornaliera . (Il tuo cliente è stato davvero così miope da non riuscire a prevedere che il tuo ramo debba essere nuovamente reimmesso nella linea principale un giorno?)

In ogni caso, l'approccio migliore è IMHO che sta tentando di ripetere ciò che avrebbe dovuto accadere in prima persona:

  • identifica la semantica delle modifiche sulla riga principale per giorno 1 dopo la creazione del ramo. Applicali al tuo codice attuale come meglio puoi. Se si trattasse di un "cambiamento locale", dovrebbe essere semplice, se si trattasse di un "refactoring cross-through" come la rinomina di una classe ampiamente utilizzata, applicarla in modo semanticamente equivalente al codice attuale. Speriamo che durante quell'anno non siano state apportate modifiche trasversali contraddittorie nella base del codice sul "tuo" ramo, altrimenti questo può diventare un vero rompicapo
  • verifica il risultato (ho già detto che hai bisogno di una buona suite di test per questa attività)? Correggi tutti i bug rivelati dal test
  • ora ripeti questa procedura per le modifiche sulla linea principale per il giorno 2, quindi il giorno 3 e così via.

Questo potrebbe funzionare quando i team obbediscono rigorosamente alle regole classiche del controllo della versione ("solo impegni compilabili, stati testati" e "check-in anticipato e spesso").

Dopo 365 ripetizioni (o 250, se sei fortunato e puoi raggruppare il lavoro per le modifiche del fine settimana), sarai quasi finito (quasi, perché devi aggiungere il numero di modifiche che avverranno alla linea principale durante il periodo di integrazione). Il passo finale sarà quello di unire nuovamente il ramo dev aggiornato nel bagagliaio (in modo da non perdere la cronologia del tronco). Questo dovrebbe essere facile, perché tecnicamente dovrebbe essere solo una sostituzione dei file interessati.

E sì, sono serio, probabilmente non c'è una scorciatoia per questo. Potrebbe risultare che "porzioni giornaliere" potrebbero essere a volte troppo piccole, ma non mi aspetterei questo, suppongo che sia più probabile che le porzioni giornaliere possano risultare troppo grandi. Spero che il tuo cliente ti paghi molto bene per questo, e che per lui è così costoso che imparerà dal suo fallimento.

Devo aggiungere che puoi provare anche con i lati invertiti, reintegrando le modifiche dal tuo ramo in piccole porzioni alla linea principale. Questo potrebbe essere più semplice quando sul tuo ramo di sviluppo ci sono state molte meno modifiche rispetto al trunk, o la maggior parte delle modifiche è avvenuta nei nuovi file di origine che attualmente non fanno parte del trunk. Si può vedere questo come "porting" di una caratteristica da un prodotto A (il ramo di sviluppo) a un prodotto leggermente diverso da B (stato attuale del tronco). Ma se la maggior parte dei rifattori incrociati sono fatti sulla linea principale, e influenzano il tuo nuovo codice (le collisioni di fusione 6500 sembrano essere una prova per questo), potrebbe essere più facile il modo in cui l'ho descritto per primo.

    
risposta data 03.01.2017 - 21:38
fonte
15

In questa fase di fusione direi che la fusione automatizzata può solo complicare il processo. Ho avuto problemi simili con rami che si sono separati per oltre un anno e il metodo più efficace che ho è quello di fare quanto segue:

  • Copia una copia dello stato originale non interrato
  • Diff tra il non sommerso e l'ultimo
  • Analizza tutti gli elementi comuni
    • Ad esempio, esegui tutte le modifiche al nome della funzione, quindi le modifiche ai parametri, ecc.
    • Ignora lo spazio bianco su diff se gli standard sono cambiati, altrimenti perderai molto tempo contando gli spazi
  • Concentrati innanzitutto sulle funzionalità principali

Eventuali avvisi del compilatore e i diff saranno i tuoi migliori amici, continuerai a usare il diff non sommerso per vedere esattamente cosa era diverso e continuare ad andare avanti. Potrebbero esserci vari strumenti che potresti usare per aiutarti, ma spetterà a te scoprire quale sia il migliore.

Il segreto è continuare.

Modifica

Una parola di avvertimento, questo approccio significherà che la cronologia del controllo della versione diventerebbe "corrotta", in quanto si perderebbe la prova della fusione da ramo a ramo, così come la storia del ramo non diviso.

Grazie ai commenti di "Jack Aidley" e "17 di 26"

    
risposta data 03.01.2017 - 18:57
fonte
8

Alcuni anni fa avevamo un cliente con gli stessi requisiti per tenere separati i rami. Così abbiamo fatto.

Non abbiamo mai unito le loro filiali. Loro avevano la propria versione unica. Li abbiamo addebitati in più per i cambiamenti poiché essenzialmente avevamo due tronchi principali invece di 1 tronco principale e rami.

Abbiamo tentato di unire nuovamente il tronco ma dopo 2 settimane abbiamo deciso di abbandonare lo sforzo poiché bruciava ore di tempo senza vantaggi tangibili.

Quindi, non unire di nuovo. Andando avanti, unisci le correzioni critiche a quel ramo del cliente secondo necessità e ogni miglioramento sarebbe uno specifico addebitato a quel cliente.

    
risposta data 04.01.2017 - 16:19
fonte
1

Non sarà divertente, ma quanto sarà doloroso dipenderà dalla natura dei cambiamenti e da quanto essi siano isolati.

Ti suggerisco di provare a far convergere i rami attraverso il refactoring il più possibile prima che tu faccia un'effettiva unione.

Lo strumento di fusione è un po 'stupido perché considera solo le differenze testuali e non capisce il codice in alcun modo. Se il ramo principale ha cambiato il nome di una classe utilizzata in tutta l'applicazione e il ramo della funzione usa il vecchio nome in qualche nuovo codice, lo strumento di fusione non capirà che il nome della classe dovrebbe essere cambiato nel nuovo codice. Ma se esegui un refactoring nel ramo B per rinominare la classe come nel ramo A, funzionerà sia nel vecchio che nel nuovo codice e l'unione procederà senza intoppi.

In secondo luogo, dovresti controllare quanto localizzati sono i cambiamenti nel ramo di sviluppo. Se le modifiche nel ramo di funzione sono localizzate in poche aree, non è necessario convergere il codice non affetto, è sufficiente copiare e sovrascrivere dal ramo principale.

Nelle aree di codice in cui sono state apportate modifiche non banali su entrambe le diramazioni, è necessario esaminare attentamente il codice e decidere come riscrivere.

    
risposta data 05.01.2017 - 08:41
fonte

Leggi altre domande sui tag