In Git, la modifica di un commit pre-pull storico dopo il pull provoca una divergenza dall'origine

StackOverflow https://stackoverflow.com/questions/4230552

  •  26-09-2019
  •  | 
  •  

Domanda

Nel seguente scenario:

  1. Effettua i commit A, B, C
  2. Tira, ottieni i commit D, E
  3. Fai più commit F, G, H, ...
  4. Renditi conto che devi modificare B
  5. Modifica B utilizzando git rebase -i E git commit --amend

Ora git status dice:

Your branch and 'origin/master' have diverged.

Come dovrei risolvere questo problema?

Nota:Non ho spinto;questo non ha niente a che fare con la spinta.

Nota:Tirare semplicemente di nuovo non risolve il problema;semplicemente unisce nuovamente i commit D, E sopra quello che ho già (nonostante D, E sia già presente nella cronologia), il che ha anche l'effetto collaterale di produrre conflitti superflui.

Per approfondire, una risposta di seguito suggerisce che la storia ora è:

- A - B' - C' - F' - G' - H' (master)
\
 D - E (origin/master)

Questo non è del tutto corretto, in realtà è:

- A - B' - C' - D(?) - E(?) - F' - G' - H' (master)
\
 D - E (origin/master)

Quindi, il mio problema.mi piacerebbe che fosse:

- A - B' - C' - F' - G' - H' (master)
\         /
 D - E (origin/master)
È stato utile?

Soluzione 2

Nota:Non accetterò la mia risposta per un po' perché sono sinceramente curioso di conoscere altri (migliori) approcci.

Il modo in cui ne sono uscito non è stato affatto elegante:

# stash F, G, H - can't simply reorder them before D, E since they depend a lot on D, E
for i in {1..3}; do git reset HEAD^; git stash; done
# wipe out the weird non-merge D and E commits
git reset --hard HEAD~2
# pull to merge D, E again
git pull
# restore F, G, H
for i in {1..3}; do git stash pop; git commit -a; done

Altri suggerimenti

Immagino che tu non abbia usato il file -p opzione per git rebase, il che significa che il pull che hai fatto, unendo i commit D ed E, è stato cancellato.Se questo è tutto quello che è successo, è semplice:basta tirare di nuovo.Se questo è quello che è successo, la tua cronologia sarà simile a questa:

- A - B' - C' - F' - G' - H' (master)
\
 D - E (origin/master)

Ecco la tua divergenza!

Se tu fatto preservare l'unione, molto probabilmente è solo perché nel frattempo qualcosa di nuovo è stato spinto all'origine:

- A - B' - C' - X' - F' - G' - H' (master)
\              /
 D - E -------- - Z (origin/master)

e quindi la soluzione, ancora una volta, sarebbe tirare.

Se, tuttavia, hai inviato qualcosa contenente il commit B originale, non avresti dovuto eseguire il rebase.Questo sarà Sempre causare divergenze, e non è una cosa divertente.La tua cronologia sarebbe simile a questa:

    B' - C' - F' - G' - H' (master)
   /
- A - B - C - X - F - G - H (origin/master)
\            /
 D - E ------

È un fatto fondamentale della progettazione di git che lo SHA1 di un commit dipenda dallo SHA1 del suo genitore, e quindi dall'intera catena di ascendenza.Questo è il motivo per cui dopo i rebase ho messo un "prime" su tutto.Anche se non hai modificato il contenuto di C, il commit viene modificato.(L'altra possibilità, che tu abbia preservato l'unione e spinto, dovrebbe essere deducibile come una combinazione delle ultime due immagini.)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top