2015-08-31 8 views
46

Supponiamo che io ho il seguente commettere storia sul mio locale unico ramo:Come iniettare un commit tra alcuni due commit arbitrari in passato?

A -- B -- C 

Come posso inserire un nuovo commit tra A e B?

+1

commit chiamato _A_? :) – Antek

+0

Ho una domanda molto simile su [come inserire una nuova versione in passato] (https://stackoverflow.com/questions/46678238/how-to-inject-a-version-between-some-two- versioni arbitrarie-in-the-past) invece di un commit. – Pavel

risposta

52

È ancora più semplice rispetto alla risposta di OP.

  1. git rebase -i <any earlier commit>. Questo visualizza un elenco di commit nell'editor di testo configurato.
  2. Trova il commit che si desidera inserire dopo (assumiamo che sia a1b2c3d). Nel tuo editor, per quella linea, cambia pick a edit.
  3. Iniziare il rebase chiudendo l'editor di testo (salva le modifiche). Questo ti lascia al prompt dei comandi con il commit che hai scelto in precedenza (a1b2c3d) come se fosse appena stato eseguito il commit.
  4. Apportare le modifiche e git commit (NON modificando, a differenza della maggior parte edit s). Questo crea un nuovo commit dopo quello che hai scelto.
  5. git rebase --continue. Questo ripete i commit successivi, lasciando il nuovo commit inserito nella posizione corretta.

Attenzione che questo riscriverà la cronologia e interromperà chiunque altro tenti di tirare.

+0

Questo ha aggiunto il nuovo commit dopo il commit, che è successivo a quello su cui mi stavo riposizionando (anche l'ultimo commit), invece che subito dopo quello su cui mi stavo riposando. Il risultato è stato come se avessi semplicemente fatto un nuovo commit alla fine con le modifiche che volevo inserire. La mia storia è diventata 'A - B - C - D' invece di desiderata' A - D - B - C'. – XedinUnknown

+1

@XedinUnknown: quindi non hai usato correttamente Rebase. – SLaks

+0

Apparentemente. Immagino di aver letto male, e di ribadire _onto_ il commit prima di quello che mi serviva, segnando il commit che volevo aggiungere _before_ come "edit". – XedinUnknown

14

Risulta essere abbastanza semplice, la risposta ha trovato here. Supponiamo che tu sia su un ramo branch. Eseguire questi passaggi:

  • creare un ramo temporaneo dalla commit dopo che si desidera inserire il nuovo commit (in questo caso commettono A):

    git checkout -b temp A 
    
  • eseguire le modifiche e impegnarli, creando una il commit, chiamiamolo N:

    git commit -a -m "Message" 
    

    (o git add seguito da git commit)

  • rebase i commit che si desidera avere dopo il nuovo commit (in questo caso si impegna B e C) sul nuovo commit:

    git rebase temp branch 
    

(forse è necessario utilizzare -p per preservare merge, se ci fossero - grazie ad a no longer existing comment da ciekawy)

  • eliminare il ramo temporaneo:

    git branch -d temp 
    

Dopo questo, la storia appare come segue:

A -- N -- B -- C 

Naturalmente è possibile che alcuni conflitti appariranno durante rebasing.

Nel caso in cui il tuo ramo non sia locale-solo questo introdurrà la cronologia di riscrittura, quindi potrebbe causare seri problemi.

+1

Non ho potuto seguire la risposta accettata da SLaks, ma questo ha funzionato per me. Dopo aver ottenuto la cronologia dei commit che volevo, dovevo 'git push --force' per cambiare il repository remoto. – escapecharacter

3

Supponendo che la storia è commettere preA -- A -- B -- C, se si desidera inserire un commit tra A e B, i passi sono i seguenti:

  1. git rebase -i hash-of-preA

  2. Git si aprirà il vostro editor. Il contenuto può in questo modo:

    pick 8668d21 A 
    pick 650f1fc B 
    pick 74096b9 C 
    

    cambiare la prima pick a edit:

    edit 8668d21 A 
    pick 650f1fc B 
    pick 74096b9 C 
    

    Salva ed Esci.

  3. Modificare il codice e poi git add . && git commit -m "I"

  4. git rebase --continue

Ora il vostro git commit la storia è preA -- A -- I -- B -- C


Se si verifica un conflitto, Git si fermerà davanti a questo commit . È possibile utilizzare git diff per individuare i contrassegni di conflitto e risolverli. Dopo aver risolto tutti i conflitti, è necessario utilizzare git add <filename> per comunicare a Git che il conflitto è stato risolto e quindi rieseguire git rebase --continue.

Se si desidera annullare il rebase, utilizzare git rebase --abort.

3

Anche soluzione più semplice:

  1. Crea il tuo nuovo impegno alla fine, D.Ora avete:

    A -- B -- C -- D 
    
  2. Poi gestita:

    $ git rebase -i hash-of-A 
    
  3. Git si aprirà il vostro editor e sarà simile a questa:

    pick 8668d21 B 
    pick 650f1fc C 
    pick 74096b9 D 
    
  4. Basta muovere D verso l'alto come questo, quindi salvare e uscire

    pick 74096b9 D 
    pick 8668d21 B 
    pick 650f1fc C 
    
  5. Ora si avrà:

    A -- D -- B -- C 
    
+2

Bella idea, tuttavia potrebbe essere difficile introdurre D su C, quando intendi questi cambiamenti in corso. ad A. – BartoszKP

Problemi correlati