come tirare in più rami contemporaneamente con git?


13

In un repository ho più rami, tra cui "master" e "sviluppo", che sono impostati per tenere traccia dei rami remoti "origine / master" e "origine / sviluppo".

È possibile specificare che voglio che sia master e sviluppo vengano uniti (avanzamento rapido) contemporaneamente?

Quando lo faccio git pullora ottengo qualcosa del genere:

remote: Counting objects: 92, done.
remote: Compressing objects: 100% (56/56), done.
remote: Total 70 (delta 29), reused 28 (delta 8)
Unpacking objects: 100% (70/70), done.
From scm.my-site.com:my-repo
   5386563..902fb45  develop    -> origin/develop
   d637d67..ba81fb2  master     -> origin/master
Updating 5386563..902fb45
Fast-forward

tutti i rami remoti vengono recuperati, ma solo il ramo in cui mi trovo attualmente viene unito al ramo remoto corrispondente.

Quindi devo fare git checkout master...

Switched to branch 'master'
Your branch is behind 'origin/master' by 106 commits, and can be fast-forwarded.

... e poi git pullancora, e poi tornare indietro per sviluppare, per ottenere il risultato desiderato.

So di poter creare alias / script che eseguono questi passaggi. Ma voglio evitarlo, se possibile, poiché è soggetto a errori e non molto efficiente .
Modifica: ok fammi riformulare. Il mio obiettivo non era quello di scoraggiare o disapprovare la personalizzazione di script / alias di git. Preferirei solo una soluzione integrata se esiste :)


Ci ho provato, git pull origin refs/heads/develop:refs/remotes/origin/develop refs/heads/master:refs/remotes/origin/masterma ciò ha causato la fusione del master remoto nello sviluppo ..
Superole,

1
Perché sarebbe soggetto a errori o inefficiente? Git è progettato per essere personalizzato in questo modo. A proposito, per evitare di dover controllare ogni ramo, potresti voler dividere il tuo pullin fetchseguito da un mergein ogni ramo.
jjlin,

@jjlin bene, se riesco a farlo senza controllare ogni ramo che può aiutare sull'efficienza. È soggetto a errori perché la matrice delle cose che può andare storta e gli effetti che può avere sul resto della sceneggiatura sono alquanto complessi. Non sto dicendo che è impossibile renderlo sicuro, ma sarebbe un compromesso. Quindi preferirei una soluzione integrata se esiste :)
Superole

Risposte:


11

Puoi impostare un alias che utilizza git fetchcon refspecs per far avanzare rapidamente i tuoi rami con un solo comando. Impostalo come alias nel tuo .gitconfigfile utente :

[alias]
    sync = "!sh -c 'git checkout --quiet --detach HEAD && \
                    git fetch origin master:master develop:develop ; \
                    git checkout --quiet -'"

Uso: git sync.

Ecco perché funziona:

  1. git checkout --quiet HEADcontrolla direttamente il tuo attuale commit, mettendoti in stato di testa staccato . In questo modo, se sei su mastero develop, scolleghi la tua copia di lavoro da quei puntatori di ramo, permettendo loro di essere spostati (Git non ti permetterà di spostare i riferimenti di ramo mentre la tua copia di lavoro li ha estratti).

  2. git fetch origin master:master develop:developusa refspecs con fetchper far avanzare rapidamente i rami mastere developnel repository locale. La sintassi sostanzialmente dice a Git "ecco un refspec del form <source>:<destination>, prendilo <destination>e avanzalo velocemente allo stesso punto di <source>". Quindi le fonti dell'alias sono i rami da origin, mentre le destinazioni sono le versioni repo locali di quei rami.

  3. Infine, git checkout --quiet -controlla il ramo in cui eri l'ultima volta, indipendentemente dal fatto che ci fosse o meno un errore nei comandi precedenti. Quindi, se eri acceso masterquando hai funzionato git synce tutto ha successo, lascerai lo stato principale distaccato e controlla il nuovo aggiornamento master.

Vedi anche la mia risposta a git: aggiornare una filiale locale senza verificarla? .


Non capisco bene la magia distaccata qui, perché il puntatore al master non può essere spostato quando lo sviluppo è estratto? ... comunque ho provato questo, e sembra funzionare, tranne ora che ottengo "Il tuo ramo è davanti a 'origine / sviluppo' di 1 commit."
Superole,

... che viene risolto la prossima volta che tiro
Superole il

@Superole quale ramo è più avanti origin/developquando usi l'alias? Non avrebbe senso se fosse la tua developfiliale locale . Inoltre, il puntatore per master può essere spostato se developè estratto, il punto è che se masterè estratto, non è possibile avanzare rapidamente masterperché ciò influirebbe sulla copia di lavoro, quindi è per questo che si stacca la copia di lavoro da esso prima usando git checkout head. Ho visto un'altra risposta che lo ha descritto come "in piedi su una roccia", devi scendere dalla roccia prima di poterlo spostare.
40XUserNotFound

era davvero il mio sviluppo locale. E il motivo deve essere che questo recupero non aggiorna i rami di tracciamento. A quanto ho capito; una spinta prenderà in origine / sviluppo, e poi unirà in sviluppo.
Superole,

È molto importante che questa risposta provochi fatal: bad config line xx in file xxx. che è causato dal punto e virgola. devi racchiudere l'intero comando tra virgolette doppie per evitare questo problema.
William Leung,

1

Installa git-up . Ti dà il comando git-upche attirerà tutti i rami locali nel tuo repository.


dolce! Lo controllerò di sicuro.
Superole,

2
heh: P Le dichiarazioni che il supporto di Windows è prevedibilmente assente. e una prova rigorosa deve ancora essere formulata che sicuramente non guasterà con la tua configurazione git, eliminerà i dati o invierà una guida inane a Notizie Hacker per tuo conto. , unito alla necessità di Ruby, mi ha allontanato. Mi piace il concetto però.
Superole,

Sono contento che c'è un metodo a tutti ... un po sucky, ma che ogni singolo metodo richiede un po 'di strumento di terze parti. Come questo e quelli con qualche comando di shell "ricetta" o un alias che utilizza una particolare shell (specifica della piattaforma).
0xC0000022L

0

Sembra che non ci sia un'opzione incorporata per git per inserire più rami. Almeno non nella versione 1.8.0. sebbene la risposta di @ Cupcake sia vicina.

Tuttavia, il commento di @jjlin mi ha fatto capire che almeno non ho bisogno di tirare due volte.

Quindi una sequenza leggermente più efficiente sarebbe:

git pull
git checkout master
git merge origin/master
git checkout -

Inevitabilmente ho finito per creare un alias, ma ho deciso di lasciarlo fuori e mi sono concentrato solo sull'avanzamento veloce di un altro ramo.

[alias]
ffwd = "!_() { git checkout $1 && git merge --ff-only origin/$1 && git checkout -; }; _"

Naturalmente, senza test questo alias presuppone che io fornisca un nome valido di un ramo ff'able come primo argomento, e altrimenti ha un comportamento indefinito. Inoltre, non è ottimale per i casi d'uso con più di due rami, ma mi darà ciò di cui ho bisogno per ora.

git pull
git ffwd master
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.