I conflitti di unione complicati frequenti sono un segno di problemi?


35

Nel nostro team, utilizziamo Git come controllo del codice sorgente. Abbiamo diverse aree di codice che sono quasi indipendenti ma presentano alcune sovrapposizioni. Ultimamente abbiamo discusso di flussi di lavoro e approcci all'utilizzo del controllo del codice sorgente. Una lamentela che emerge quando promuovo l'utilizzo di un flusso di lavoro della diramazione di funzionalità è che le persone spesso incontrano complicati conflitti di unione che risolvono in modo errato. Con complicato intendo "non ovvio su come risolvere". Alla luce di ciò, altri flussi di lavoro vengono utilizzati più attivamente, ad esempio un flusso di lavoro basato su "pull rebase".

Come sostenitore dell'approccio del ramo delle caratteristiche, non sto davvero ricevendo il reclamo. Sì, devi mantenere aggiornati i rami delle tue funzionalità locali da master o ovunque, ma questo è l'unico vero problema che vedo. Sto pensando che se le tue fusioni sono sempre complicate e possono avere effetti secondari, allora è più un problema di lavoro di squadra che un problema di Git.

Sono corretto nel pensare questo? I conflitti di unione complicati sono un segno di qualcosa di buono o cattivo?


1
Quanto durano le funzionalità? Quanto è ben modulare il codice? Potresti (ad esempio) scegliere Cherry nel commit del codice di test (prima è stato fatto e separato dal codice effettivo, giusto?) Per vedere come è cambiata la funzionalità?

@MichaelT La base di codice è per la nostra base di codice di test automatizzata. Stiamo per iniziare a lavorare su una nuova aggiunta al nostro progetto che probabilmente avrà bisogno di un po 'di sviluppo parallelo per un po'. Da qui la discussione sui rami delle funzioni rispetto ad altri.
joshin4colours,

7
Le persone incontrano davvero questo tipo di problema o temono solo che possano apparire questi problemi?
Christopher Creutzig,

2
A proposito del fantastico tutorial che hai collegato a :)
Vorac,

1
Il rifacimento del ramo della feature o la sua fusione con il trunk comporta fusioni simili. Il rifacimento in realtà fa più fusioni e come tale è più probabile che crei cattivi conflitti. Ciò che conta è quanto spesso viene fatto.
Jan Hudec,

Risposte:


23

Non è impossibile che il problema sia il tuo codice. Se la tua base di codice ha molte interrelazioni tra i moduli, allora ogni cambiamento avrà viticci dappertutto e ogni sviluppatore interagirà con il codice di qualcun altro, sarà un incubo.

Tenderei a pensare che lo noteresti prima in altri modi, ma è possibile che tu sia così abituato da non vederlo più.


9
Questo è stato il mio primo pensiero. Conflitti di unione complicati si verificano quando vengono apportate più modifiche allo stesso codice. Se hai un progetto abbastanza giovane, allora questo è comune, ma se hai una base di codice di buone dimensioni, questo potrebbe essere un segno di "oggetti divini" o che alcuni moduli / classi stanno facendo troppo e devono essere sottoposti a refactoring. Può anche derivare da committenti troppo zelanti che commettono dozzine di piccoli cambiamenti, ma è meno comune.
TMN

1
Il fatto che la nostra base di codice sia in qualche modo "giovane" (circa 6 mesi, attraversata da molti importanti refactor) potrebbe essere un indicatore di ciò.
joshin4colours,

10
@ joshin4colours Se stai eseguendo il refactoring mentre qualcuno sta scrivendo una funzione di grandi dimensioni, sei nei guai.
Sean McSomething il

17

Sono abituato al flusso di lavoro "fetch-rebase-push". Qual è in realtà il primo, più primitivo, flusso di lavoro, descritto nel tuo tutorial Qui ci sono i vantaggi:

  • Vera integrazione continua
  • Gestione precoce dei conflitti - subito dopo aver scritto e testato il codice
  • Risposta rapida - "Ehi, Bob, l'interpolazione cubica che hai scritto sta dando risultati divertenti, potresti guardarla mentre sono a pranzo?"
  • Nessun impegno di commit - linea temporale pulita come se uno sviluppatore scrivesse everithyng

Ora, riguardo a complicati conflitti di unione. Non capisco come si possano sperimentare fusioni sia frequenti che complicate. La complicazione nasce dal non rifare / raccogliere la ciliegia per molto tempo, lavorando su quella caratteristica solitaria per un mese.

Personalmente preferirei affrontare conflitti frequenti, facili da fondere (in realtà rebase), piuttosto che rari, un horror di fusione onnicomprensivo.


1
Ottima descrizione di un buon flusso di lavoro Git, ma questo non risponde alla mia domanda.
joshin4colours,

2
@joshy questo è vero. Solo il secondo paragrafo tratta la tua domanda. Ma ecco una risposta diretta. Se l'unione è frequente e difficile, allora questo è certamente un'indicazione del flusso di lavoro problematico / problema di comunicazione / problema di architettura / divisione o problema dei ruoli.
Vorac,

7

Fusioni e rinunce dovrebbero causare gli stessi identici conflitti, per quei conflitti intrinseci che un essere umano deve risolvere (cioè due sviluppatori che cambiano la stessa linea di codice). Per altri conflitti, le fusioni in realtà tendono ad essere più pulite, perché non stai cambiando lo SHA-1 di commit in tutto il luogo. Non sono sicuro di come tu riesca a entrare in uno stato in cui le fusioni causano più conflitti che ribelli, ma è certamente un segno che il flusso di lavoro di alcune persone è incasinato e probabilmente hanno bisogno di più formazione su come funziona Git. Stanno rimuovendo gli impegni di unione di altre persone quando fanno le loro riduzioni locali o qualcosa del genere?

Il vantaggio e lo svantaggio del metodo pull-rebase è che è molto simile ai flussi di lavoro centralizzati a cui sono abituate molte persone. Non è necessario comprendere la ramificazione per poterla utilizzare.

Ad ogni modo, è perfettamente fattibile eseguire un flusso di lavoro della diramazione delle funzionalità solo localmente, se non riesci a convincere altre persone ad accedervi.


5

Il progetto a cui sto lavorando presenta questo tipo di problema di volta in volta e sembra derivare da un paio di fattori:

  • Stiamo usando Visual Studio e file come Visual Studio .sln sono solo documenti XML (che non rispondono bene alle fusioni testuali) pieni di Guide (che Git non può capire meglio del resto di noi) e possono essere facilmente fusa male e causa la perdita dei file.
  • Alcune persone stanno lavorando su aree simili del codice, in modo che i cambiamenti che vengono spinti possano essere uno accanto all'altro nelle classi. Sebbene inevitabile in questa situazione, questo tipo di configurazione sarà un duro lavoro per qualsiasi sistema di controllo del codice sorgente. Anche se hai una grande comunicazione nella tua squadra, a volte le persone non si rendono conto che si stanno imbattendo nel codice reciproco e sorgono conflitti.

Sono interessato dal potenziale per Semantic Merge di aiutare con alcuni di questi problemi, ma ovviamente è utile solo se stai lavorando in una lingua che può analizzare e non ho ancora incontrato sfide significative quando Lo sto usando, quindi non posso garantire la sua efficacia.


4

A meno che gli sviluppatori non stiano modificando i commit storici (anziché le pure fusioni), i conflitti in un modello git del tipo di flusso di lavoro delle caratteristiche sono un segno di una base di codice strettamente accoppiata (/ base di codice brandnew) o assegnazione di funzioni sovrapposte.


0

Hai un ramo principale (principale) e tutti lavorano nei loro rami funzione.

Il lavoro nei rami delle funzionalità può richiedere da poche ore a pochi mesi.

Ogni tanto qualcuno invertirà nuovamente il loro changeset nel ramo principale. Il capo della tua squadra deve assicurarsi che solo una persona faccia una fusione inversa alla volta. Al termine, è necessario inoltrare l'unione dal ramo principale al ramo delle caratteristiche. Una volta che tutti eseguono una fusione in avanti, un'altra persona può essere autorizzata a invertire l'unione nel ramo principale. Altrimenti troppe modifiche verranno unite al contrario e avrai tonnellate di conflitti di unione sulla tua unione diretta.

Giusto per chiarire la terminologia, per "unione inversa" intendo la fusione dal ramo della funzione nel ramo principale, e per "unione in avanti" intendo la fusione dal ramo principale al ramo della funzione. Sulla base di ciò che ho sperimentato in precedenza, è probabile che vengano visualizzati più conflitti di unione in unione inversa, anziché in unione diretta.


1
La fusione nel ramo principale non deve mai avere conflitti. Unisci sempre principale per primo, quindi la funzione per principale è quindi libera da conflitti.
gnasher729,

@ gnasher729 - Penso che sia quello che sta dicendo questa risposta - il suggerimento, come vedo, è che ogni sviluppatore si unisce ai rami delle funzionalità ogni volta che qualcuno commette qualcosa a main, in modo che tutti i conflitti vengano immediatamente risolti sui rami delle funzionalità.
Periata Breatta,

Ha detto "è più probabile che si verifichino conflitti che si fondono dalla funzionalità al master"
gnasher729,

0

Due cose che possono aiutare: Uno, evitare qualsiasi strumento che apporti modifiche da solo. Due sviluppatori che utilizzano impostazioni di scheda diverse sono una ricetta per il disastro. Due, apportare modifiche in diverse posizioni. Si ottiene un problema, ad esempio, se tre sviluppatori aggiungono codice alla fine dello stesso file, molto meglio se aggiungono codice in luoghi diversi.

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.