2013-02-22 15 views
93

Vorrei definire un nuovo ramo "root" in questo repository git. Per ramo "root" intendo un ramo che è del tutto indipendente da tutti gli altri rami nel repository .Come creare un nuovo (e vuoto!) Ramo "root"?

Sfortunatamente, anche il commit (chiamiamolo A) alla base della commit tree del repository contiene molti file (questo era un repository inizializzato su un progetto già abbastanza maturo).

Questo significa che anche se ho dato A come la nuova filiale del <start-point>, questo nuovo ramo non partiva da una "tabula rasa", ma piuttosto sarebbe contenere tutti i file che sono stati commessi in A.

C'è un modo per creare un ramo completamente nudo in questo repository, con il più vicino possibile a A?


proposito, questa è non equivale alla creazione di un nuovo repo. Repositi separati sarebbero meno convenienti per molte ragioni.


EDIT: Ok, questo è quello che ho fatto, sulla base di vcsjones 'risposta:

# save rev of the current earliest commit 
OLDBASE=$(git rev-list --max-parents=0 HEAD) 

# create a new orphan branch and switch to it 
git checkout --orphan newbranch 
# make sure it's empty 
git rm -rf . 

# create a new empty commit in the new branch, and 
# save its rev in NEWBASE 
git commit --allow-empty -m 'base commit (empty)' 
NEWBASE=$(git rev-list HEAD) 

# specify $NEWBASE as the new parent for $OLDBASE, and 
# run filter-branch on the original branch 
echo "$OLDBASE $NEWBASE" > .git/info/grafts 
git checkout master 
git filter-branch 

# NOTE: this assumes that the original repo had only one 
# branch; if not, a git-filter-branch -f <branch> command 
# need to be run for each additional branch. 

rm .git/info/grafts 

Anche se questa procedura è un po' coinvolti, il risultato finale è un vuoto commit di base che può servire come <start-point> per qualsiasi nuovo "ramo clean-slate"; tutto quello che avevo bisogno di fare è quindi

git checkout -b cleanslate $(git rev-list --max-parents=0 HEAD) 

In futuro sarò sempre creare nuovi repository così:

git init 
git commit --allow-empty -m 'base commit (empty)' 

... in modo che il primo commit è vuoto, e sempre disponibile per l'avvio di una nuova filiale indipendente. (Questo sarebbe, lo so, una struttura molto raramente necessaria, ma è abbastanza facile da rendere più facilmente accessibile.)

+0

duplicati di http://stackoverflow.com/questions/13969050/how-to-create-a-new-empty-branch-for-a-new-project – Anonymoose

+1

@ Anonymoose: solo per la cronaca (piuttosto che per la discussione): non sono d'accordo con la tua opinione. – kjo

+1

Sembra esserci una soluzione molto più semplice basata su 'git rebase --onto', vedi http://stackoverflow.com/questions/645450/insert-a-commit-before-the-root-commit-in-git –

risposta

151

Usare il --orphan durante la creazione del ramo:

git checkout --orphan YourBranchName 

questo creerà una nuova ramo con zero si impegna su di esso, tuttavia tutti i file verranno gestiti. A quel punto potresti semplicemente rimuoverli.
("rimuoverli": Un git reset --hard svuoterà l'indice, lasciando con un albero di lavoro vuoto)

Date un'occhiata alla man page per cassa per ulteriori informazioni su --orphan.

+0

Questo essenzialmente crea una lavagna vuota? Come in, da zero? O mantiene tutte le modifiche precedenti, ma non solo nella cronologia git? –

+1

@ConAntonakos Questo crea un nuovo ramo senza un genitore. Gli altri rami non sono interessati, tutti i loro cambiamenti sono mantenuti. – fuz

1

Per aggiungere alla risposta accettata - best practice per ripristinare lo stato di pulizia è creare an initial empty commit in modo da poter facilmente rebase durante l'impostazione di filiali per i posteri. Inoltre, dal momento che si desidera uno stato pulito, è probabile che si siano impegnati file che non si dovrebbero, quindi è necessario rimuoverli dall'indice.Con quelli in mente si dovrebbe:

$ git checkout --orphan dev2 
Switched to a new branch 'dev2' 
$ git reset # unstage all the files, you probably don't want to commit all of them 
$ git commit --allow-empty -m 'Initial empty commit' 
[dev2 (root-commit) a515c28] Initial empty commit 
Problemi correlati