Ho appena scritto di recente su questo argomento:
Come manteniamo aggiornato questo ramo di funzionalità? Unire i commit upstream più recenti è facile, ma si desidera evitare di creare un commit di merge, poiché non sarà apprezzato quando spinto a upstream: si stanno quindi effettivamente re-commit delle modifiche a monte e quei commit upstream riceveranno un nuovo hash ( quando ottengono un nuovo genitore). Ciò è particolarmente importante, poiché quei commit uniti si rifletteranno nella tua richiesta pull GitHub quando invii quegli aggiornamenti al tuo ramo di funzionalità GitHub personale (anche se lo fai dopo aver emesso la richiesta pull).
Ecco perché abbiamo bisogno di rebase invece di unire:
git co devel #devel is ansible's HEAD aka "master" branch
git pull --rebase upstream devel
git co user-non-unique
git rebase devel
Sia l'opzione rebase che il comando rebase di git manterranno il tuo albero pulito ed eviteranno di avere commit di merge. Ma tieni presente che quelli sono i tuoi primi commit (con i quali hai emesso la tua prima richiesta pull) che vengono ribasati e che ora hanno un nuovo hash di commit, che è diverso dagli hash originali che sono ancora nel tuo ramo repository github remoto .
Ora, il trasferimento di questi aggiornamenti al tuo ramo di funzionalità di GitHub personale non funzionerà qui, poiché entrambi i rami differiscono: l'albero del ramo locale e l'albero del ramo remoto sono "fuori sincronizzazione", a causa di questi diversi hash di commit. Git ti dirà di prima git pull --rebase
, poi di spingere di nuovo, ma questa non sarà una semplice spinta in avanti veloce, poiché la tua cronologia è stata riscritta. Non farlo!
Il problema qui è che recupereresti di nuovo i tuoi primi commit modificati come erano originariamente, e quelli verranno uniti sopra il tuo ramo locale. A causa dello stato non sincronizzato, questo pull non si applica in modo pulito. Otterrai una cronologia interrotta in cui i tuoi commit compaiono due volte. Quando si invia tutto questo al ramo delle funzionalità di GitHub, tali modifiche si rifletteranno sulla richiesta pull originale, che diventerà molto, molto brutta.
AFAIK, in realtà non esiste una soluzione totalmente pulita a questo. La soluzione migliore che ho trovato è forzare il push del tuo ramo locale al tuo ramo GitHub (in realtà forzando un aggiornamento non rapido):
Come per git-push (1):
Update the origin repository’s remote branch with local branch, allowing non-fast-forward updates. This can leave unreferenced commits dangling in the origin repository.
Quindi non tirare, basta forzare la spinta in questo modo:
git push svg +user-non-unique
o:
git push svg user-non-unique --force
Questo in realtà sovrascriverà chiaramente il tuo ramo remoto, con tutto nel tuo ramo locale. I commit che si trovano nel flusso remoto (e che hanno causato l'errore) rimarranno lì, ma saranno commit pendenti, che alla fine verranno eliminati da git-gc (1). Nessun grosso problema.
Come ho detto, questa è AFAICS la soluzione più pulita. Lo svantaggio di questo è che il tuo PR verrà aggiornato con i commit più recenti, che avranno una data successiva e potrebbero apparire non sincronizzati nella cronologia dei commenti del PR. Nessun grosso problema, ma potrebbe creare confusione.