Applicare le modifiche con rebase

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

Visual Studio 2019 | Visual Studio 2022

Git gestisce automaticamente una cronologia di sviluppo in un ramo collegando ogni nuovo commit al relativo predecessore. Quando si unisce un ramo a un altro, la cronologia può diventare meno semplice. Ad esempio, un'unione senza avanzamento rapido combina linee di sviluppo divergenti creando un commit di merge con più predecessori. Al contrario, una rebase Git combina linee di sviluppo divergenti senza creare un commit di merge, che comporta una cronologia di commit più semplice ma perde informazioni sull'unione. La scelta del tipo di merge è probabilmente influenzata dal fatto che si voglia mantenere un record dell'unione o semplificare la cronologia dei commit.

Questo articolo illustra quando usare una rebase anziché un'unione senza inoltro rapido e fornisce le procedure per le attività seguenti:

  • Eseguire nuovamente il database del ramo locale
  • Forzare il push del ramo locale dopo una ribase
  • Rebase interattivo per eseguire il squash dei commit locali

Per una panoramica del flusso di lavoro Git, vedere Esercitazione su Git di Azure Repos.

Eseguire nuovamente il database del ramo locale

Git rebase integra i commit da un ramo di origine nel ramo locale corrente (ramo di destinazione). Il ramo di origine rimane invariato. Per il confronto, il rebase Git e altri tipi di merge sono illustrati nel diagramma seguente.

Diagramma che mostra i commit prima e dopo quando si usa la rebase Git.

Git esegue nuovamente la ribase della cronologia dei commit del ramo di destinazione in modo che contenga tutti i commit del ramo di origine, seguiti da tutti i commit del ramo di destinazione dall'ultimo commit comune. Un altro modo per visualizzare è che una ribase riproduce le modifiche nel ramo di destinazione sopra la cronologia dei rami di origine. In particolare, git rebase modifica la sequenza dei commit del ramo di destinazione esistente, che non è il caso per le altre strategie di merge. Nel diagramma precedente, commit K' contiene le stesse modifiche di K, ma ha un nuovo ID commit perché si collega di nuovo al commit E invece di C.

Durante una rebase, se una modifica del ramo di origine è in conflitto con una modifica del ramo di destinazione, Git chiederà di risolvere il conflitto di merge. È possibile risolvere i conflitti di unione durante una ribase nello stesso modo in cui si risolvono i conflitti di merge durante un'unione.

Rebase e no-fast-forward merge

Il rebasing git comporta una cronologia di commit più semplice ma meno esatta rispetto a un'unione senza avanzamento rapido, altrimenti nota come unione a tre vie o true . Quando si desidera un record di un'unione nella cronologia dei commit, usare un'unione senza avanzamento rapido.

Se si è l'unica persona che lavora su una funzionalità o un ramo di correzione di bug, è consigliabile usare una ribase per integrare periodicamente il lavoro recente main del ramo. Questa strategia consente di assicurarsi di essere consapevoli del lavoro recente da parte di altri utenti e di risolvere tempestivamente eventuali conflitti di merge che si verificano. Ribasando, si implementa la nuova funzionalità oltre al lavoro di ramo più recente main , che consente di mantenere una cronologia di commit lineare.

Per altre informazioni su Git rebase e su quando usarlo, vedere Rebase vs merge.

Rebase e linee guida per il push forzato

Se si esegue di nuovo il database di un ramo locale di cui è stato eseguito il push in precedenza e quindi si esegue di nuovo il comando push Git predefinito, il push avrà esito negativo. Il comando push Git predefinito applica un merge fast forward per integrare il ramo locale nel ramo remoto. Questo comando avrà esito negativo dopo una ribase perché la rebase modifica la sequenza di commit esistenti nel ramo di destinazione locale, quindi non corrisponde più alla cronologia della controparte remota. In questo scenario, un push forzato avrà esito positivo, sovrascrivendo il ramo remoto.

Git rebase e force push sono strumenti potenti, ma tenere presenti queste linee guida quando si decide se usarle:

  • Non basare nuovamente un ramo locale di cui è stato eseguito il push e condiviso con altri utenti, a meno che non si sia certi che nessuno stia usando il ramo condiviso. Dopo una ribase, il ramo locale non corrisponderà più alla cronologia della controparte remota.
  • Non forzare il push in un ramo remoto usato da altri utenti, poiché la versione locale del ramo remoto non corrisponderà più alla cronologia dei rami remoti aggiornata.
  • Il team deve concordare gli scenari di utilizzo per la ribase e forzare il push.

Suggerimento

Per un processo di revisione collaborativa, usare una richiesta pull per unire un nuovo lavoro nel ramo predefinito di un repository remoto.

Come eseguire la ribase

Visual Studio 2022 offre un'esperienza di controllo della versione Git usando il menu Git, Le modifiche Git e tramite i menu di scelta rapida in Esplora soluzioni. Visual Studio 2019 versione 16.8 offre anche l'interfaccia utente Git di Team Explorer . Per altre informazioni, vedere la scheda Visual Studio 2019 - Team Explorer .

  1. Scegliere Git Manage Branch (Gestisci rami Git>) per aprire la finestra Repository Git.

    Screenshot dell'opzione Gestisci rami nel menu Git di Visual Studio.

  2. Nella finestra Repository Git fare clic con il pulsante destro del mouse sul ramo di destinazione e scegliere Checkout (Checkout).

    Screenshot dell'opzione Checkout nel menu di scelta rapida del ramo nella finestra Repository Git di Visual Studio.

  3. Fare clic con il pulsante destro del mouse sul ramo di origine e selezionare Rebase target-branch in <source-branch>>.<

    Screenshot dell'opzione Rebase nel menu di scelta rapida del ramo nella finestra Repository Git di Visual Studio.

  4. Visual Studio visualizzerà un messaggio di conferma dopo una ribase riuscita.

    Screenshot del messaggio di conferma della ribase nella finestra Repository Git di Visual Studio.

    Se la rebase viene interrotta a causa di conflitti di merge, Visual Studio invierà una notifica. È possibile risolvere i conflitti oppure annullare la ribase e tornare allo stato di pre-ribase.

    Screenshot del messaggio di conflitto di ribase nella finestra Repository Git di Visual Studio.

Forzare il push del ramo locale dopo una ribase

Se si esegue il rebase di un ramo locale di cui è stato eseguito il push in precedenza, un push Git predefinito successivo avrà esito negativo. È invece possibile forzare il push del ramo locale per sovrascrivere la controparte remota in modo che le cronologie di commit corrispondano.

Avviso

Non forzare mai il push di un ramo su cui altri stanno lavorando. Per altre informazioni, vedere Rebase and force push guidelines .For more information, see Rebase and force push guidelines.

Per forzare il push in Visual Studio, è prima necessario abilitare l'opzione force push:

  1. Passare a Strumenti>Opzioni>controllo del codice>sorgente Git Global Impostazioni.

  2. Selezionare l'opzione Abilita push --force-with-lease .

Il flag di push --force-with-lease Git è più sicuro del --force flag perché non sovrascrive un ramo remoto con commit non integrati all'interno del ramo locale di cui si forza il push.

  1. Nella finestra Modifiche Git selezionare il pulsante di push per eseguire il push del commit.

    Screenshot del pulsante di selezione freccia su nella finestra Modifiche Git di Visual Studio.

    In alternativa, è possibile selezionare Push dal menu Git .

    Screenshot dell'opzione Push dal menu Git in Visual Studio.

  2. Se l'operazione push Git predefinita ha esito negativo, Visual Studio avvia la finestra di dialogo Git-Push non riuscita . Scegliere Forza push.

    Screenshot della finestra di dialogo Git-push non riuscita in Visual Studio.

  3. Visual Studio visualizzerà un messaggio di conferma dopo un push riuscito.

    Screenshot del messaggio di conferma push in Visual Studio.

Rebase interattivo per eseguire il squash dei commit locali

In genere, mentre si lavora su una nuova funzionalità nel ramo di funzionalità locale, si creeranno più commit. Quando si è pronti per pubblicare la nuova funzionalità, è possibile consolidare tali commit in un unico commit per semplificare la cronologia dei commit. È possibile usare una rebase interattiva per schiacciare più commit in un singolo commit.

Visual Studio 2022 non supporta il rebasing interattivo. Usare invece la riga di comando Git.

Nota

Gli utenti di Azure DevOps possono eseguire il merge per condensare la cronologia dei commit di un ramo di argomento durante una richiesta pull.

Passaggi successivi