Le richieste pull di compressione interrompono l'algoritmo di fusione di git?

8

Attualmente sto lavorando per una società che utilizza VSTS per la gestione del codice git. Il metodo "consigliato" di Microsoft di unire un ramo è di fare un "squash merge", il che significa che tutti i commit per quel ramo vengono schiacciati in un nuovo commit che incorpora tutte le modifiche.

Il problema è che cosa succede se eseguo alcune modifiche in un ramo per un elemento di backlog, quindi immediatamente voglio iniziare a fare cambiamenti in un altro ramo per un altro elemento del backlog, e tali cambiamenti dipendono dal set di modifiche del primo ramo?

Posso creare un ramo per quell'elemento del backlog e basarlo sul primo ramo. Fin qui tutto bene. Tuttavia, quando arriva il momento di creare una richiesta di pull per il secondo ramo, il primo ramo è già stato fuso in master e poiché è stato eseguito come fusione di squash, git segnala una serie di conflitti. Questo perché git non vede l'originale commette che il secondo ramo era basato su, si vede solo l'unificazione di una grande zucca e così, per unire il secondo ramo nel master, tenta di riprodurre tutti i commit del primo ramo in parte superiore della fusione di squash, causando molti conflitti.

Quindi la mia domanda è, c'è un modo per aggirare questo (oltre a non basare mai un ramo di funzione su un altro, che limita il mio flusso di lavoro) o squash unire basta interrompere l'algoritmo di fusione di git?

    
posta Jez 09.02.2018 - 16:49
fonte

2 risposte

10

Con Git, conferma

  • sono immutabili,
  • e forma un grafico aciclico diretto.

Lo squashing non combina i commit. Invece, registra un nuovo commit con le modifiche da più altri commit. La ridefinizione è simile, ma non combina i commit. La registrazione di un nuovo commit con le stesse modifiche di un commit esistente viene chiamata riscrittura della cronologia . Ma poiché i commit esistenti sono immutabili, questo dovrebbe essere inteso come "scrivere una storia alternativa".

L'unione tenta di combinare le modifiche delle due cronologie del commit (diramazioni) a partire da un commit antenato comune.

Quindi esaminiamo la cronologia:

                                 F  feature2
                                /
               1---2---3---4---5    feature1 (old)
              /
-o---o---o---A---o---o---S          master

A è l'antenato comune, 1-5 il ramo della caratteristica originale, F il nuovo ramo della funzione e S il commit schiacciato che contiene le stesse modifiche di 1-5. Come potete vedere, l'antenato comune di F e S è A. Per quanto riguarda git, non vi è alcuna relazione tra S e 1-5. Quindi il mastering con S su un lato e feature2 con 1-5 sull'altro sarà in conflitto. Risolvere questi conflitti non è difficile, ma è un lavoro noioso e non necessario.

A causa di questi vincoli, ci sono due approcci per affrontare la fusione / lo schiacciamento:

  • O si utilizza la riscrittura della cronologia, nel qual caso si otterranno più commit che rappresentano le stesse modifiche. Quindi rebase il secondo ramo della funzione sul commit schiacciato:

                                     F  feature2 (old)
                                    /
                   1---2---3---4---5    feature1 (old)
                  /
    -o---o---o---A---o---o---S          master
                              \
                               F'       feature2
    
  • O non usi la riscrittura della cronologia, nel qual caso potresti ottenere ulteriori commit di fusione:

                                     F  feature2
                                    /
                   1---2---3---4---5    feature1 (old)
                  /                 \
    -o---o---o---A---o---o-----------M  master
    

    Quando feature2 e master vengono uniti, l'antenato comune sarà commit 5.

In entrambi i casi avrai qualche sforzo di fusione. Questo sforzo non dipende molto da quale delle due strategie sopra indicate scegliate. Ma assicurati che

    I rami
  • hanno vita breve, per limitare la distanza che possono derivare dal ramo principale e che
  • fondi regolarmente il master nel tuo branch di funzionalità o rebase il branch di funzionalità su master per mantenere sincronizzati i rami.

Quando lavori in una squadra, è utile coordinare chi sta attualmente lavorando su cosa. Ciò aiuta a mantenere basso il numero di funzionalità in fase di sviluppo e può ridurre il numero di conflitti di unione.

    
risposta data 09.02.2018 - 17:15
fonte
6

La fusione di Squash interrompe l'algoritmo di fusione per tutti i rami che contengono commit che sono stati rimossi dallo squash. In altre parole, i rebases sono virali. Se si esegue il rebase di un ramo, è necessario rebase di qualsiasi altro ramo che dipendesse da quel ramo. Se utilizzi rerere , i conflitti di unione che hai risolto manualmente nel repository locale non saranno è necessario risolverlo manualmente, ma ciò non aiuta a risolvere i conflitti risolti da altre persone.

Ecco perché la nostra regola non scritta qui è che va bene schiacciare fino a quando nessun altro è mai dipeso dal tuo ramo delle funzionalità, che è forse il 90% delle volte. Altrimenti, una fusione diretta aiuta tutti a evitare problemi.

    
risposta data 09.02.2018 - 19:58
fonte

Leggi altre domande sui tag