2011-08-30 16 views
5

abbiamo la seguente storiaSposta ramo all'altro punto della storia

start   master public 
|     | | 
v     v v 
o---o-- ... --o---o---o 

Purtroppo abbiamo fatto alcuni commit nel ramo master contenente alcuni dati sensibili. Abbiamo modificato questo in un ramo separato chiamato pubblico. Ora vogliamo "tagliare" il ramo public per ottenere uno "stato" completo e pulito in public ma senza le parti della cronologia compromettente ancora contenute tramite master. In altre parole, vogliamo che il seguente nuova storia:

start   master 
|     | 
v     v 
o---o-- ... --o---o 
\ 
    o <- public 

Ora check-out public deve portare allo stesso albero di lavoro come nella situazione originaria, ma senza i dettagli della cronologia sensibili. Successivamente disattiviamo il vecchio ramo master: lo rinominiamo in unsafe ed elaboriamo un nuovo ramo master dal nuovo ramo public. In questo modo conserviamo la vecchia storia nel unsafe e sono in grado di spingere il ramo public in pubblico senza preoccupazioni:

start   unsafe 
|     | 
v     v 
o---o-- ... --o---o 
\ 
    o---o-- ... --o <-- public 
    \   /
    o-- .. --o-- ... --o <-- master 

Quali sono i git destra comanda di raggiungere questo obiettivo?

PS: Naturalmente è possibile effettuare il checkout start, creare un nuovo ramo e impegnare l'intero albero di lavoro del ramo public. Ma deve esserci un modo diverso, più elaborato e divertente!

+0

@phlipsy questo non è in realtà fuori tema su SU, ma lo migrerò in SO come richiesto, in modo da non farlo devo ripubblicare. – DMA57361

+0

Queste informazioni possono aiutare: http://help.github.com/remove-sensitive-data/. – Barend

+0

Dai un'occhiata a http://stackoverflow.com/questions/872565/how-do-i-remove-sensitive-files-from-gits-history – Chris

risposta

3

Il modo corretto di unire tutti i commit in pubblico in un unico commit (ovvero unire più commit a uno, o rimuovere singoli commit completamente, ecc.) È utilizzare git rebase -i. Quindi, quello che si potrebbe fare è (assumendo che il primo commit ha un tag start come il grafico indica):

git checkout public 
git rebase -i start 

Una finestra di editor viene su cui è possibile modificare l'ordine di tutte le patch semplicemente utilizzare squash per tutto il vostro cerotti. Dopo aver salvato il file e chiuso l'editor, git ricombinerà la cronologia delle patch come richiesto. Ovviamente, il master non cambierà la sua storia.

per rinominare i master attuale come non sicuri e ricominciare tutto l'ulteriore sviluppo sul pubblico, lo farei:

git checkout -b unsafe master # <- creates a new branch "unsafe" 
git checkout master 
git reset --hard public # <- forces master branch to point to public 

Se non si crea il ramo unsafe, l'hard reset perderà tutti i commit nel Maestro e non sarai in grado (facilmente) di accedervi più. Quindi assicurati di aver davvero creato quel ramo.

Un'alternativa sarebbe quella di rinominare master-unsafe e quindi creare un nuovo ramo maestro:

git branch -m master unsafe # renames master to unsafe 
git checkout -b master public # creates new branch master as a copy of public 

Entrambi dovrebbero comportare la stessa struttura delle filiali. (Concesso, il secondo non ha quel pericolo di perdere la cronologia ...)

+0

Ho dovuto smanettare un po 'perché non puoi schiacciare tutti i commit (quale rimarrà?). Ma alla fine ha funzionato per me.Grazie, questa è la soluzione! – phlipsy

+0

L'ho provato nel nostro progetto di vita reale e: Wow! Questo è stato il più folle rebase che abbia mai fatto in tutta la mia vita! Siate pronti a mettervi in ​​contatto con tutti i vostri conflitti di fusione dell'intera storia del vostro progetto. – phlipsy