Strategie di fusione e merge con squash
Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019
Quando si completa una richiesta pull , si unisce il ramo dell'argomento nel ramo predefinito, in genere main
. Questa unione aggiunge i commit del ramo argomento al ramo main e crea un commit di merge per riconciliare eventuali conflitti tra il ramo predefinito e quello dell'argomento. I commenti e le discussioni nella pull request forniscono più contesto per le modifiche apportate nel topic branch.
La cronologia commit nel ramo main
(o in un altro ramo predefinito) non segue una linea retta, a causa della cronologia dei rami dell'argomento correlata. Man mano che un progetto aumenta, il numero di rami di argomento lavorato contemporaneamente aumenta, rendendo sempre più difficile seguire la cronologia dei rami predefinita.
Il ramo predefinito è una rappresentazione accurata della cronologia di ogni ramo di argomento, ma è difficile usare per rispondere a domande più ampie sullo sviluppo del progetto.
Prerequisiti
Categoria | Requisiti |
---|---|
Accesso al progetto | Membro di un progetto. |
Autorizzazioni | - Visualizzare il codice nei progetti privati: almeno livello di accesso Basic . - Clonare o contribuire al codice nei progetti privati: membro del gruppo di sicurezza Contributors o con autorizzazioni corrispondenti nel progetto. - Impostare le autorizzazioni per il ramo o il repository: Gestisci le autorizzazioni per il ramo o il repository. - Modificare il ramo predefinito: Modificare le politiche le autorizzazioni per il repository. - Importare un repository: membro del gruppo di sicurezza , amministratori del progetto, o del gruppo di sicurezza Git a livello di progetto , Crea repository impostato su Consenti. Per altre informazioni, vedere Impostare le autorizzazioni del repository Git. |
Servizi | Repos abilitato. |
Strumenti | Opzionale. Usare i comandi az repos: l'interfaccia della riga di comando di Azure DevOps. |
Nota
Nei progetti pubblici, gli utenti con accesso Stakeholder hanno pieno accesso ad Azure Repos, compresa la visualizzazione, la clonazione e il contribuire al codice.
Categoria | Requisiti |
---|---|
Accesso al progetto | Membro di un progetto. |
Autorizzazioni | - Visualizzare il codice: almeno accesso di base. - Clonare o contribuire al codice: membro del gruppo di sicurezza Contributor o autorizzazioni corrispondenti nel progetto. |
Servizi | Repos abilitato. |
Unione di squash
L'unione di squash è un'opzione di unione che consente di condensare la cronologia Git dei rami di argomento quando si completa una richiesta pull. Anziché aggiungere ogni commit nel ramo dell'argomento alla cronologia del ramo predefinito, un merge di squash aggiunge tutte le modifiche apportate al file a un singolo nuovo commit nel ramo predefinito. Il commit di merge squash non ha un riferimento al branch tematico. Genera un nuovo commit che contiene tutte le modifiche dal ramo dell'argomento. È consigliabile eliminare il ramo dell'argomento per evitare confusione.
Un modo semplice per pensare a questo è che l'unione squash offre solo le modifiche ai file e un'unione normale fornisce le modifiche ai file e la cronologia dei commit.
Come è utile un merge di squash?
La fusione squash mantiene le cronologie dei rami predefiniti pulite e facili da seguire senza richiedere modifiche al modo di lavorare del tuo team. I contributori al ramo tematico lavorano come preferiscono nel ramo tematico, mentre i rami predefiniti mantengono una cronologia lineare usando le unioni squash. La cronologia dei commit di un ramo main
, aggiornato con squash merge, ha un commit per ogni ramo unito. È possibile esaminare questa cronologia per scoprire esattamente quando è stato fatto il lavoro.
Considerazioni relative all'unione di squash
L'integrazione con squash riduce la cronologia delle modifiche nel ramo predefinito, quindi è importante collaborare con il tuo team per decidere quando eseguire l'integrazione con squash e quando mantenere l'intera cronologia dei commit di un branch tematico. Quando si esegue l'unione di squash, è consigliabile eliminare il ramo di origine. L'eliminazione del ramo di origine impedisce confusione perché il ramo dell'argomento stesso non ha un commit che lo unisce al ramo predefinito.
Completare le pull request con il merge squash
È possibile scegliere di eseguire un'unione squash quando si completa una richiesta pull in Azure Repos.
Scegliere Commit squash sotto Tipo di merge nella finestra di dialogo Richiesta pull completa per eseguire un merge squash del branch tematico.
Più basi di merge
La scheda File in una richiesta pull rileva le differenze in base a un confronto a tre lati. L'algoritmo prende in considerazione l'ultimo commit nel ramo di destinazione, l'ultimo commit nel ramo di origine e la relativa base di merge comune, ad esempio, il miglior predecessore comune. L'algoritmo è un metodo rapido, conveniente e affidabile per rilevare le modifiche. Purtroppo, in alcuni casi, c'è più di una vera base. Nella maggior parte dei repository questa situazione è rara, ma in repository di grandi dimensioni con molti utenti attivi può essere comune. È possibile controllare manualmente se esistono più basi di unione tra i rami. A tale scopo, eseguire git merge-base --all feature master
comando. Azure DevOps rileva l'esistenza di più basi di unione per ogni pull request. Quando vengono rilevati, Azure DevOps visualizza il messaggio "Sono state rilevate più basi di merge. L'elenco dei commit visualizzati potrebbe essere incompleto per la pull request. Mentre Azure DevOps esegue il rilevamento di più basi di merge, non verifica se la potenziale base di merge è già stata unita o meno. Tale controllo viene eseguito da git merge-base
. Ecco perché Azure DevOps potrebbe visualizzare il messaggio anche quando git merge-base
segnala una sola base di merge.
Nota
Nel caso in cui si siano perse le modifiche durante una revisione della pull request, assicurarsi che più basi di merge non siano la causa principale.
Gli scenari di esempio seguenti vengono rilevati da Azure DevOps come più basi, con le basi di unione indicate dai numeri uno e due:
- Unioni incrociate (note anche come intersezioni) tra rami diversi (segnalati da Azure DevOps e
git merge-base
)
---1---o---A
\ /
X
/ \
---2---o---o---B
- Fusione di un ramo con altri due (segnalato da Azure DevOps, ma non da
git merge-base
che elimina il punto di fusione 2)
---1---o---o---o---A
\ /
\-------2
\ \
\---o---o---o---B
- Gestione delle conseguenze del ripristino del ramo principale, ad esempio, modificare il commit di merge
* 42bb2d2 (HEAD, A) Amended merge commit
|\
| | * 67c9bb8 (other) Merge branch 'A' into B
| | |\
| |/ /
|/| /
| |/
| * fa78e32 add second commit
* | 15845c9 add first commit
|/
* 6a52130 add init
- Riutilizzo attivo dei rami di funzionalità
- Altre manipolazioni non intuitive e contorte con revert, cherry-pick e merge
Il rilevamento di più basi di unione è parte della consapevolezza riguardo alla sicurezza. Se sono presenti più basi di unione, l'algoritmo diff del file per l'interfaccia utente potrebbe non rilevare correttamente le modifiche ai file, a seconda della base di unione scelta. Se i file nella "richiesta pull" hanno versioni diverse tra le basi di merge, si verifica un avviso di basi di merge multiple.
Per altri dettagli, vedere la documentazione ufficiale di Git.
Potenziali rischi per la sicurezza dell'unione da più basi
- Un utente malintenzionato potrebbe abusare dell'algoritmo dell'interfaccia utente per eseguire il commit di modifiche dannose che non sono presenti nella pull request.
- Se le modifiche proposte nella pull request sono già presenti nel ramo di destinazione, vengono visualizzate nella scheda File, ma potrebbero non attivare le politiche del ramo associate ai cambiamenti nelle cartelle.
- Due set di modifiche agli stessi file da più basi di unione potrebbero non essere presenti nella pull request. Questo caso potrebbe creare lacune logiche insidiose.
Come risolvere il problema delle basi di unione multiple
La presenza di più basi di merge non è necessariamente negativa, ma è consigliabile verificare che tutto sia corretto. Per eliminare più basi di merge, collegare i rami a un singolo predecessore comune ribasando il ramo sulla destinazione o unendo la destinazione nel ramo. Queste azioni vengono eliminate dal messaggio di avviso e consentono di verificare se le modifiche effettive sono appropriate.
Un approccio consiste nel reimpostare dolcemente e accantonare i progressi prima di eseguire il rebasing o l'unione. È quindi possibile creare un nuovo ramo o ribasare uno vuoto e applicare le modifiche partendo da un punto chiaro. Questo processo potrebbe richiedere un push forzato in remoto se le modifiche sono già presenti.
Come evitare il problema di più basi di fusione
Di seguito sono riportati suggerimenti generali per evitare il problema del merge base multiplo.
- Quando si prepara una richiesta pull, creare rami di funzionalità dalle versioni più recenti del ramo principale o di rilascio.
- Evitare di creare rami che non provengono direttamente da rami stabili del repository, a meno che non sia necessario.
Operazioni da eseguire se il problema delle basi di unione multiple riappare
In repository di grandi dimensioni con molti collaboratori attivi, questo problema può essere particolarmente scomodo. Anche se si eliminano più basi tramite unione, la situazione potrebbe riapparire. Se qualcuno chiude una pull request di lunga durata, la situazione potrebbe ricrearsi. Anche se i criteri di build e i test sono in esecuzione, non hai modo di completare il pull request. La reimpostazione e l'avvio di un nuovo ramo potrebbero risultare utili. Se non viene modificato nulla, è probabile che le modifiche siano chiare, anche se la situazione si ripete.