2009-08-20 20 views
200

Ho alcune vecchie filiali nel mio repository git che non sono più in fase di sviluppo attivo. Vorrei archiviare i rami in modo che non vengano visualizzati per impostazione predefinita quando si esegue git branch -l -r. Non voglio cancellarli, perché voglio mantenere la cronologia. Come posso fare questo?Come posso archiviare i rami git?

So che è possibile creare un ref al di fuori di refs/teste. Ad esempio, ref/archive/old_branch. Ci sono delle conseguenze nel farlo?

+0

git-rm non elimina le risorse dal repository, le rimuove solo dall'indice http://www.kernel.org/pub/software/scm/git/docs/git-rm.html Puoi facilmente ripristinare queste risorse usano 'git checkout [rev] file' –

+1

Non che io sappia. Io uso 'Attic/' tag leggeri per archiviare i rami, però. I tag –

+0

sono la scelta rapida, sicura e sana. – kch

risposta

259

Credo che il modo corretto per farlo è quello di taggare il ramo. Se elimini il ramo dopo averlo taggato, hai effettivamente mantenuto il ramo ma non ingombrerà la tua lista di filiali.

Se è necessario tornare al ramo basta controllare l'etichetta. Ripristinerà efficacemente il ramo dal tag.

Per archiviare ed eliminare il ramo:

git tag archive/<branchname> <branchname> 
git branch -d <branchname> 

Per ripristinare il ramo qualche tempo dopo:

git checkout -b <branchname> archive/<branchname> 

La storia del ramo sarà conservato esattamente come lo era quando si classificarla come tale.

+8

Sono un principiante Git, ma nel provare questo, penso che il comando corretto per il ripristino del ramo è: 'git checkout -b archivio/' – Steve

+5

C'è qualche ragione per non usare un tag oggetto in questo caso ? Essere in grado di vedere chi ha archiviato il ramo e quando potrebbe essere interessante. –

+0

@ GrégoryJoseph che cos'è? –

13

Si potrebbe archiviare i rami in un altro repository. Non abbastanza elegante, ma direi che è un'alternativa valida.

git push git://yourthing.com/myproject-archive-branches.git yourbranch 
git branch -d yourbranch 
+4

È possibile creare 'git-bundle' invece di un repository separato. –

87

risposta di Jeremy è corretta in linea di principio, ma secondo me i comandi che specifica non sono abbastanza di destra.

Ecco come archiviare un ramo a un tag senza dover checkout il ramo (e, quindi, senza la necessità di cassa ad un altro ramo prima di poter eliminare quel ramo):

> git tag archive/<branchname> <branchname> 
> git branch -D <branchname> 

Ed ecco come ripristinare un ramo:

> git checkout -b <branchname> archive/<branchname> 
+11

Immagino che non avessi ancora abbastanza punti ma sarebbe meglio quando modifichi la risposta esistente - +1 comunque :) :) – jkp

5

sto usando seguenti alias per nascondere rami archiviati:

[alias] 
    br = branch --no-merge master # show only branches not merged into master 
    bra = branch     # show all branches 
.210

Così git br per mostrare i rami sviluppati attivamente e git bra per mostrare tutte le filiali comprese "archiviati" quelli.

+1

Se un ramo è stato fuso in master non ha nulla a che fare con il suo stato di archivio. Ad esempio, nel mio team di sviluppo abbiamo alcune filiali create appositamente per testare le cose. Vogliamo mantenere quei rami nel nostro archivio, ma sicuramente non vogliamo unirli in master. – Bart

0

È possibile utilizzare uno script che archiviare il ramo per voi

archbranch

Si crea un nome per voi con l'archivio prefisso/e quindi elimina il ramo. Ma controlla il codice prima di usarlo.


Utilizzo - $/your/location/of/script/archbranch [branchname] [defaultbranch]

Se si desidera eseguire lo script senza scrivere la posizione in cui si aggiungere al vostro percorso

Poi si può chiamare da

$ archbranch [branchname] [defaultbranch] 

Il [defaultbranch] è il ramo a cui andrà quando l'archiviazione è terminata. Ci sono alcuni problemi con la codifica a colori, ma altri poi che dovrebbe funzionare. L'ho usato nei progetti da molto tempo, ma è ancora in fase di sviluppo.

+1

Per overflow dello stack [Guida] (http://stackoverflow.com/help/behavior), è necessario rendere nota la propria affiliazione con il prodotto. – LittleBobbyTables

+0

Oh, mi dispiace, non lo sapevo. Sono l'autore della sceneggiatura. – Banezaka

2

Non vorrei archiviare i rami. In altre parole, le filiali si archiviano da sole. Quello che vuoi è assicurare che le informazioni rilevanti per gli archeologi possano essere trovate con mezzi affidabili. Affidabili in quanto aiutano lo sviluppo quotidiano e non aggiungono un ulteriore passaggio al processo di completamento del lavoro. Cioè, non credo che le persone si ricorderanno di aggiungere un tag una volta che hanno finito con un ramo.

Ecco due semplici passaggi che aiuteranno enormemente lo sviluppo archeologico e.

  1. Link each task branch with an associated issue in the issue tracker using a simple naming convention.
  2. Utilizzare sempre git merge --no-ff per unire i rami attività; vuoi che si unisca la bolla commit e cronologia, anche per un solo commit.

Questo è tutto. Perché? Perché come archeologo del codice, raramente comincio a voler sapere quale lavoro è stato svolto su una filiale. Molto più spesso è per questo che in tutti gli urlanti nove inferni il codice è scritto in questo modo ?! Ho bisogno di cambiare codice, ma ha alcune caratteristiche strane, e ho bisogno di risolverli per evitare di rompere qualcosa di importante.

Il passaggio successivo è git blame per trovare i commit associati e quindi sperare che il messaggio di registro sia esplicativo. Se ho bisogno di scavare più a fondo, scoprirò se il lavoro è stato fatto in un ramo e leggere il ramo nel suo insieme (insieme al suo commento nel tracker del problema).

Diciamo git blame punti al commit XYZ. Apro un browser storia Git (gitk, GitX, git log --decorate --graph, ecc ...), trovare commettere XYZ e vedere ...

AA - BB - CC - DD - EE - FF - GG - II ... 
    \      /
     QQ - UU - XYZ - JJ - MM 

C'è mio ramo! So che QQ, UU, XYZ, JJ e MM fanno tutti parte dello stesso ramo e dovrei guardare i loro messaggi di registro per i dettagli. So che GG sarà un commit di merge e avrà il nome del ramo che si spera sia associato a un problema nel tracker.

Se, per qualche ragione, voglio trovare un vecchio ramo, posso eseguire git log e cercare il nome del ramo nel commit di unione. È abbastanza veloce anche su repository di grandi dimensioni.

Questo è ciò che intendo quando dico che gli archivi di rami stessi.

Tagging su ogni ramo aggiunge lavoro inutile per ottenere risultati (un processo critico che deve essere spietatamente snellito), gum su l'elenco di tag (non parlando di prestazioni, ma leggibilità umana) con centinaia di tag che sono solo molto occasionalmente utili e non è nemmeno molto utile per l'archeologia.

+0

Ma per quanto riguarda la confusione? Forse se ci fosse un modo per nascondere i vecchi rami sotto 10 metri cubi di terra. – bvj

7

Ecco un alias per questo:

arc = "! f() { git tag archive/$1 $1 && git branch -D $1;}; f" 

inserirlo in questo modo:

git config --global alias.arc '! f() { git tag archive/$1 $1 && git branch -D $1;}; f' 

Tenete a mente c'è git archive comando già così non è possibile utilizzare archive come un nome alias.

Inoltre è possibile definire alias per visualizzare l'elenco delle filiali 'archiviati':

arcl = "! f() { git tag | grep '^archive/';}; f" 

about adding aliases

+1

Con le versioni più recenti di git (come suggerito [qui] (https://stackoverflow.com/a/7534289/431033), questo alias dà il completamento: '! Git tag archive/$ 1 $ 1 && git branch -D' – Lack

1

Il mio approccio è quello di rinominare tutti i rami che non si preoccupano con un "trash_" prefisso, quindi utilizzare:

git branch | grep -v trash 

Per mantenere la colorazione del ramo attivo, sarebbe necessario:

git branch --color=always | grep --color=never --invert-match trash 
9

Sì, è possibile creare un riferimento con un prefisso non standard utilizzando git update-ref (ad es. git update-ref refs/archive/old-topic topic.) Non ho visto nessun problema finora. A differenza dei normali rami o tag, questi non verranno visualizzati nel solito git branch, git loggit tag (mentre è possibile vederli con git log --all).

La copia di SHA1 è sufficiente per il breve termine, ma il commit senza alcun riferimento sarà GC'd after 3 months (or a couple of weeks without reflog). I commit con i ref sono sicuri.

sto usando seguenti alias:

[alias] 
    archive-ref = "!git update-ref refs/archive/$(date '+%Y%m%d-%s')" 
    list-archive-ref = for-each-ref --sort=-authordate --format='%(refname) %(objectname:short) %(contents:subject)' refs/archive/ 
    rem = !git archive-ref 
    lsrem = !git list-archive-ref 

Inoltre, è possibile configurare i telecomandi come push = +refs/archive/*:refs/archive/* per spingere automaticamente (o git push origin refs/archive/*:refs/archive/* per one-shot).

Edit: trovato un'implementazione perl della stessa idea da @ap: git-attic

Edit^2: Trovato a blog post dove Gitster se stesso con la stessa tecnica.

+0

Eccellente , a parte tutti su questo thread, hai effettivamente risposto alla domanda. – tzrlk

6

Estendere Steve answer per riflettere i cambiamenti del telecomando, ho fatto

git tag archive/<branchname> <branchname> 
git branch -D <branchname> 
git branch -d -r origin/<branchname> 
git push --tags 
git push origin :<branchname> 

Per ripristinare dal telecomando, vedere this question.