2012-02-27 21 views
7

Come si rimuovono i commit con diramazione master?Rimozione di commit Git su un ramo

Ho aggiunto una libreria di grandi dimensioni, insieme a una cronologia di commit molto ricca (e che precede il mio codice) in una sottodirectory tramite Git subtree. Mi piacerebbe rompere retroattivamente l'intera cronologia, ma essere ancora in grado di unire nuovi commit alla libreria.

Ho provato varie combinazioni di git rebase ma non ho mai ottenuto il risultato previsto [*].

mio repository sembra qualcosa di simile:

A---B-----------F---G master 
      /
    ... C---D---E 

e mi piacerebbe per farlo sembrare qualcosa di simile:

A---B-----------F'--G' master 
      /
       E' 

o:

A---B-------E'--F'--G' master 

[*]:

  • git rebase --onto C E master
  • git checkout F; git rebase --onto C E master
+0

L'unione sarà compromessa da tale schiacciamento. Perché vuoi schiacciarlo? Solo per ripulire l'output di gitk/git log? –

+0

Sì, questo e il fatto che tutti i commit precedenti ammontano a diverse centinaia di megabyte. – Gingi

+0

La tua decisione di importare una libreria integrando la sua cronologia di sviluppo nel repository del progetto è strana. – Deestan

risposta

1
  1. Si tratta di editing storia. Si finisce in qualcosa come

    A---B-----------F'---G' master 
          /
           E' 
    
  2. La fusione sarà un problema dopo questo, a causa di Git non sarà in grado di trovare i genitori in comune tra la vostra storia e la storia delle biblioteche.

  3. farlo davvero è necessario

    1. Reset per B (la creazione di tag o un ramo di G di tenerlo in giro)
    2. Eseguire fondersi con --no-commit.
    3. Rebase o cherry-pick G qui (sarà G ')

    La storia sarà simile

    A---B-----------F'---G' 
    

Per rendere il clone superficiale della biblioteca, devi fare qualcosa del genere (Attenzione: non testata):

  1. Salva impegna da F (esclusa) a G (compreso) a un patch (git format-patch F --stdout > ~/saved_commits.patch)
  2. Reset per B. Assicurarsi ci sono rami che poiting a F, E o G
  3. Rimuovere il telecomando insieme con il suo ref namespace git remote rm
  4. reflogs Cancellazione: git reflog expire --expire=now --all
  5. rimuova In realtà le cose da git: git gc --prune=now.Ora dovresti vedere il repository ridursi.
  6. Ri-aggiungere il telecomando per la libreria.
  7. git fetch --depth=10 libraryremote
  8. Ripetere l'unione (come di consueto)
  9. Applicare commit salvati (git am ~/saved_commits.patch).

migrare nella soluzione di sottomoduli (l'opzione migliore probabilmente), è necessario eseguire il rollback allo stato precedente unione e creare moduli, quindi sostituire ogni fondono con cambiata id commit-per modulo. A differenza di case of splitting out project directory to submodule non conosco la soluzione automatizzata per questo (ma può essere implementata in modo simile).

+0

Perché "E" non può avere "F", non "F", come suo genitore (lo stesso vale per "F" e "G")? – Gingi

+1

s/parent/child/ –

+0

Numero commit == commit hash. Cambiare genitore significa cambiare questo impegno significa cambiare l'hash di questo commit significa cambiare il numero di questo commit. La modifica della cronologia rende il ripple che cambia tutto il commit più recente. –

Problemi correlati