Come unire il ramo corrente in un altro ramo


182

Ho due rami, master e dev. Lavoro sempre su dev e controllo il codice nel ramo master solo dopo che è stato approvato per l'uso in produzione. Quando lo faccio, devo fare quanto segue:

git checkout master
git merge dev
git checkout dev

È terribilmente prolisso, e dal momento che lo faccio frequentemente, vorrei minimizzarlo. Esiste un comando git che posso usare per unire dal mio attuale branch dev all'altro master del ramo senza dover prima verificare il ramo master? Qualcosa di simile forse:

git merge dev to master

sarebbe fantastico. Ho controllato la documentazione di Git e non ho visto nulla.


1
Hai provato a usare git push per questo?
Jay Sullivan,

11
Che cosa sono i suggerimenti di push? Questo è per l'aggiornamento dei telecomandi , non per la fusione all'interno del proprio repository.
Cascabel,

4
Jefromi ha ragione, la spinta non è utile qui. Sto parlando di un altro ramo locale, non di un ramo remoto.
Chris,

2
Ancora peggio è quando si ha non impegnati modifiche locali: git stash, git checkout master, git merge dev, git checkout dev, git stash pop.
Mu Mind,

2
Bella domanda Lo volevo anche perché volevo entrare in un ramo non corrente. Volevo evitare di cambiare ramo perché ho un processo che dà il via a una build se qualche file nell'albero di lavoro cambia.
Kelvin,

Risposte:


94

1. Aggiungi un alias remoto per il tuo repository locale, ad esempio:

git remote add self file:///path/to/your/repository

(O su Windows git remote add self C:\path\to\your\repository)

2. Premere sul telecomando, ad esempio:

git push self dev:master

2
Moduli! Questo non solo risolve il problema della domanda posta, ma risolve anche il problema di cambiare ramo quando si ha solo un sottomodulo. Ottimo consiglio!
eddiemoya,

2
+1 Questo è creativo e non tocca affatto l'albero di lavoro. Solo un chiarimento: /path/to/your/repositoryè il percorso del tuo albero di lavoro, cioè non includere la .gitdirectory. Inoltre, questo dovrebbe essere ovvio: il telecomando dovrà essere aggiornato se si sposta il repository.
Kelvin,

Non ho avuto fortuna a farlo funzionare in Windows ... git remote add self file:///c/projectsRitorna solo con le note di utilizzo
Maslow

2
@ JosephK.Strauss Puoi prima unire il master nel ramo corrente ( dev) e poi premere il commit di unione usando git push self dev:master.
Leonid Shvechikov,

4
Perché l'alias remoto? .funzionato bene per me: git push . head:master.
geon,

60

L'attuale risposta più votata da @zerome è buona, ma è un po 'inutilmente dettagliata.

Nella base del tuo repository git puoi semplicemente fare questo: git push . dev:master

Una soluzione più generalizzata che funzionerebbe ovunque nell'albero sarebbe:

git push $(git rev-parse --show-toplevel) dev:master

3
git push . dev:mastermi ha semplificato molto la vita! La risposta migliore in assoluto, grazie
Jeremy Belolo,

hai intenzione di spingere il master unito in un repository remoto come github? salva un passo facendogit push origin dev:master
Alex R

1
È possibile replicare il merge --no-ffcomportamento con questo?
exhuma,

1
Ricevo un nome remoto non valido "." in Windows. Devo ancora fare git remote add self file:///myRepo?
kiewic,

1
Ma questo non fa davvero una fusione ... Funzionerà se dev è davanti al maestro, ma cosa succede se non lo è?
Thomas Levesque,

44

La tua scommessa migliore sarebbe semplicemente usare un alias, inserito nel tuo gitconfig globale ( ~/.gitconfig):

[alias]
    merge-to = "!f() { git checkout $1 && git merge $2 && git checkout -; }; f"

in modo che tu possa invocarlo da qualsiasi repository come

git merge-to master dev

3
Cosa accadrebbe se l'unione non fosse automatica, ma richiedesse la risoluzione dell'unione? (In questo caso presumo che non sia stato svolto alcun lavoro sul master, quindi non accadrà, ma comunque) ...
Stein G. Strindhaug

@Stein: Da quando l'ho usato &&, non ;avrebbe fallito l'unione e non avrei provato a tornare indietro. Speriamo che l'utente sia abbastanza intelligente da vedere il messaggio "unione fallita" e gestirlo.
Cascabel,

6
Preferisco questo merge-to = "!f() { export tmp_branch=ramo git | grep '*' | tr -d '*' ; git checkout $1 && echo git merge $tmp_branch && echo git checkout $tmp_branch; unset $tmp_branch; }; f", che mi permetta di non dover digitare il ramo Sono attualmente in, quindi se voglio fondono devin mastere sono in devquesto momento mi basta digitaregit merge-to master
Steve

2
Versione migliore con backtick corretti e senza eco:merge-to = "!f() { export tmp_branch=`git branch | grep '* ' | tr -d '* '`; git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset $tmp_branch; }; f"
Simon Epskamp

2
il comando unset non è corretto. fixed is: merge-to = "! f () {export tmp_branch = git branch | grep '* ' | tr -d '* '; git checkout $ 1 && git merge --no-ff $ tmp_branch && git checkout $ tmp_branch; unset tmp_branch;}; f"
sassman

38

Una piccola modifica dell'alias Jefromi che non richiede di digitare il ramo corrente.

Quindi lo si utilizza come: git merge-to dev.

Questo passerà al devramo, lo unirà con CORRENTE e poi tornerà indietro.

Ad esempio, supponendo che tu sia sul masterramo, unirà il master in dev e sarai ancora sul master.

Va sicuramente ai miei dotfile :)

[alias]
  merge-to = "!gitmergeto() { export tmp_branch=`git branch | grep '* ' | tr -d '* '` && git checkout $1 && git merge $tmp_branch && git checkout $tmp_branch; unset tmp_branch; }; gitmergeto"

6

Questo è vecchio, ma ...

Combinando le soluzioni di @ kevin-lyda e @ dmytrii-nagirniak sopra. questo alias unisce il ramo corrente nel ramo specificato. Usa il metodo dei telecomandi e usa i comandi git per ottenere il contesto.

[alias]
    merge-to = "!gitmergeto() { git push \"`git rev-parse --show-toplevel`\" `git rev-parse --abbrev-ref HEAD`:$1; } && gitmergeto"

Da usare come:

git merge-to other-branch-name

4

Per unire il ramo corrente in un altro ramo senza estrarre l'altro ramo:

Unione rapida

Questo è davvero facile. Per definizione, una fusione in avanti veloce significa semplicemente che il puntatore del ramo viene spostato avanti nella struttura di commit. Quindi tutto ciò che devi fare è solo simulare che:

git branch -f master dev

Avvertenze: questo presuppone che masterpunti a un commit che è anche in devbranch o in qualche altro branch. In caso contrario, rischi di perdere il lavoro! Diversamente da git mergeciò creerà un commit di unione (o lamentarsi) quando non è possibile avanzare rapidamente, questo metodo forza silenziosamente il puntatore del ramo a puntare a un altro commit.

Questo presuppone anche che tu sia l'unico a lavorare sul repository e / o tu sappia cosa stai facendo.

Suggerimento: se hai fatto un git fetche hai nuovi commit origin/master, puoi spostare la masterfiliale senza effettuare il checkout utilizzando:

git branch -f master origin/master

Unisci tramite unisci unione

Questo non è sempre possibile. Per creare un commit di unione, è necessario eseguire un'operazione di unione. E per eseguire un'operazione di unione, è necessario eseguire commit nell'altro ramo che non si trova nel ramo corrente.

Se hai commesso in master filiale sono che non sono nella devbranch, è possibile:

Disclaimer: questa è solo una prova di concetto, solo per dimostrare che a volte è possibile fare una fusione con l'altra filiale senza effettuare il check-out. Se vuoi usarlo ogni giorno, probabilmente vorrai creare un alias usando il reindirizzamento della shell o creare uno script di shell per esso. Quindi, puoi anche creare uno script di shell per il processo più breve mostrato nella domanda.

git checkout -b temp
git merge --no-ff -e master
git branch -f master temp
git checkout dev
git branch -D temp

Spiegazione:

  1. Controlla un ramo temporaneo che punta allo stesso commit del ramo corrente.
  2. Unisci masternel ramo temporaneo e avvia l'editor dei messaggi di commit. Se si desidera che il commit della fusione assomigli hai unito il devramo in master, modificalo da questo:

    Merge branch 'master' into temp
    

    a questa:

    Merge branch 'dev'
    

    Mancia: puoi usare -m "Merge branch 'dev'"invece di -eessere più veloce.

  3. Aggiorna il masterpuntatore del ramo in modo che punti al commit di unione.
  4. Dai un'occhiata alla devfiliale.
  5. Forza l'eliminazione del ramo temporaneo.

Questo tocca ancora l'albero di lavoro, ma minimamente. Non esegue il rollback dell'albero fino allo stato originale mastersolo per apportare nuovamente i cambiamenti di sviluppo. Ad alcuni potrebbe non interessare, ma per altri potrebbe essere importante.


1

Molte volte vieni dal ramo in cui vorresti unire il ramo corrente. In tal caso potresti fare:

git co - && git merge @{-1}

per esempio:

git checkout somebranch      // (while on master)

// add some commits

git co - && git merge @{-1}  // will merge somebranch into master

1

La mia soluzione è simile alle altre risposte, con le seguenti differenze:

  • la funzione è divisa in più righe per leggibilità
  • la funzione chiama set -excosì ogni comando viene stampato e se il comando fallisce la funzione esce immediatamente
  • alias passa i suoi argomenti tranne il primo (ramo di destinazione) a git merge
  • la funzione include un comando null : git mergeche assicura che il completamento della scheda funzioni con alcune configurazioni della shell (ad es. gitfastda oh-my-zsh)
[alias]
  merge-to = "!f() { : git merge ; \
      set -ex ; \
      local this=$(git rev-parse --abbrev-ref HEAD) ; \
      local target=$1 ; \
      shift ; \
      git checkout $target ; \
      git merge $this \"$@\" ; \
      git checkout $this ; \
    } ; f"
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.