2012-12-27 39 views
6

Questo è un esempio di come il mio git repo è adesso:Set branch master per ultima tag

v1.0 v1.1 v1.2 
    |  |  | 
    a - b - c 
    |    | 
master   HEAD 

solito impegno, tag e spingere i tag in questo modo:

git commit -a -m "Commit msg" 
git tag -a v1.3 -m "Tag msg" 
git push --tags 

Il problema principale che ho è che il ramo principale non si sposta al tag più recente, quindi sono sempre nello stato Detached HEAD. C'è un modo per risolvere questo problema in modo che il ramo principale punta sempre sull'ultimo tag spinto?

+2

Qual è il tuo flusso di lavoro? Perché sei sempre in uno stato di TESTA distaccato? Perché non lavori in una filiale? Penso che questo sia più un problema con il tuo flusso di lavoro di qualsiasi altra cosa. – jszakmeister

+1

Se non si controlla direttamente un tag, questo non accadrà. Solo effettuare nuovi commit dopo aver controllato un * ramo *, mai un * tag *. – cdhowie

+0

Per essere in grado di generare i file del pacchetto nel repository ho bisogno di taggarli, altrimenti diventano 'a3fsr2' per esempio, ecco perché ho bisogno di usare i tag. – Peter

risposta

7

In questo caso particolare, ho dovuto effettuare le seguenti operazioni:

1) In primo luogo impostare il branch master per puntare al più recente tag (dove la testa è rivolto), perché è il tag più recente. Per fare ciò ho creato un nuovo ramo e un master unito.

git branch -b exp 
git merge -s ours master 
git checkout master 
git merge exp 

Ora master è lo stesso di ultima tag:

v1.0 v1.1 v1.2 
    |  |  | 
    a - b - c 
        | 
       HEAD 
        | 
       master 

2) Una volta che abbiamo maestro di nuovo in luogo, abbiamo bisogno di spingere sia padrone e tag ogni volta che facciamo un nuovo commit:

git commit -a -m "Commit msg" 
git tag -a v1.4 -m "Tag msg" 
git push master --tags 

In questo modo si evita di essere in una modalità HEAD distaccata e il ramo master viene aggiornato.

+0

Feedback interessante, più completo della mia risposta. +1 – VonC

+1

'git checkout -B master HEAD' esegue direttamente il punto 1. – jthill

2

Un ramo non fa riferimento a un tag.
Un tag fa riferimento a un commit corretto.

Finché non si è git checkout master, non si è in uno detached HEAD mode.
È quindi possibile eseguire il commit e tag: il tag verrà creato sul LATEST del ramo corrente.

Se si era in una modalità CUFFIA distaccata, vedere "Git: How can I reconcile detached HEAD with master/origin?" per un modo diverso di riconciliare un commit distaccato con un ramo.

+0

Il ramo master attuale non è aggiornato, quindi se eseguo il checkout, sto perdendo le modifiche applicate in v1.1 e v1.2. – Peter

3

varie risposte/commenti già dato sul perché di non fare le cose in questo modo, ma ecco come si fissa questo scenario particolare:

git checkout -b tmpbranch  # creates a branch called tmpbranch at HEAD 
git checkout master    # switch back to master branch 
git merge --ff-only tmpbranch # fast-forward merge master to tmpbranch, fail if not possible 
git branch -d tmpbranch   # delete tmpbranch, it's not needed anymore 

Poi, andando avanti, non controlla un tag, ad eccezione di in questo modo:

git checkout -b somebranch refs/tags/tagname # creates a new branch starting at tag 

in questo modo, non sarà in stato di testa staccata, e verrà aggiunto nuove impegna a partire dalla tag in questione, che sembra essere ciò che si vuole ... Dopo aver fatto un commit Puoi git tag newtag creare tag aggiuntivi nei punti giusti.

+0

Il problema con questa soluzione è che avrei un ramo per ogni tag che ho nel repository. – Peter

+0

@Peter Solo se i tag sono tutti su linee di sviluppo separate, che non appare è il caso della domanda originale. Avresti un ramo, come 'master', con un tag' v2.0' che punta a un commit recente su quel ramo, e tag precedenti (ad esempio 'v1.9',' v1.8' ....) che puntano in precedenza commette su quello stesso ramo. Un ramo dovrebbe indicare "quale sarà il genitore del prossimo commit che faccio". Il precedente comando 'checkout' è per quando è necessario controllare un vecchio tag (-er) per preparare una correzione di bug o qualcosa del genere, non per lo sviluppo attuale ... – twalberg