2011-08-31 19 views
13

Chcę wykonać pojedyncze zatwierdzenie w różnych oddziałach jednocześnie, ponieważ w moim projekcie mam różne gałęzie dla różnych klientów.Git: Zaakceptuj jednocześnie wiele oddziałów.

Powiedzmy, że dokonałem nowego zatwierdzenia funkcji w Oddziale A. Czy mogę również dokonać tego zatwierdzenia w Oddziale B, Oddziałach C i D w tym samym czasie? Czy istnieje jakieś polecenie skrótu? To bardzo kłopotliwe, by sprawdzić jedną gałąź, i za każdym razem, gdy zobowiązanie jest konieczne w wielu gałęziach, czepiać się za każdym razem, byłoby to dla mnie koszmarem.

Każdy prosty skrypt bash dla tej operacji?

Jest tam similar question. ale zmiana nie jest taka, jak chcę.

+0

możliwe duplikat [Commit do wielu gałęziach jednocześnie git] (http://stackoverflow.com/questions/4532063/commit-to-multiple-branches-at-the-same-time- z-git) – Johann

+0

Zobacz także http://stackoverflow.com/a/30186843/6309 – VonC

+0

Jeśli odpowiedź Spoutnika pomogła ci, rozważ zaakceptowanie go z zielonym znacznikiem wyboru –

Odpowiedz

0

Nie, nie sądzę, że możesz to zrobić. Najlepszym wyjściem byłoby zobowiązanie się do jednego z twoich oddziałów (lub oddziału głównego), a następnie albo scalenie commitów z innymi pojedynczo, albo wiśnia - wybierz commit do każdej z pozostałych gałęzi.

+0

Nie chcę scalić, ponieważ nie chcę spraw, aby wszystkie gałęzie były takie same. Cherry-pick jest wyborem, ale wymaga czasu, trzeba sprawdzić każdą gałąź, jeśli mam więcej niż 5 oddziałów, potrzebuje czasu ... cóż, czy myślisz, że skrypt może to zrobić? –

+0

Pisanie skryptu powinno być dość banalne. Sprawdź także odpowiedź @ rangalo. – harald

2

Myślę, że możesz napisać hak po zatwierdzeniu, aby scalić lub wybrać inne gałęzie. Ale to oczywiście nie będzie jedno zobowiązanie.

Hak automatyzuje to, co chcesz osiągnąć.

http://git-scm.com/docs/githooks

7

Coś warto rzucić okiem na: git stash zmiany, git commit, git checkout inny oddział, git stash apply, git commit itp

Zobacz man pages.

+1

Ten schemat będzie działał, ale chcesz użyć 'git stash apply', a nie' git stash pop'. – wjl

+0

@wjl: Dziękuję za korektę - powinienem był skierować Kit Ho, żeby przeczytał także strony man ;-) –

9

Ponieważ nie ma typowej odpowiedzi na moje pytanie, napisałem prosty skrypt, aby zautomatyzować ten proces. Możesz skomentować ten kod.

#!/bin/bash 
BRANCHES=(
master_branch 
develop_branch 
testing_branch 
) 
ORIGINALBRANCH=`git status | head -n1 | cut -c13-` 
git commit -m $1 
CHERRYCOMMIT=`git log -n1 | head -n1 | cut -c8-` 
for BRANCH in "${BRANCHES[@]}"; 
do 
    git stash; 
    git checkout $BRANCH; 
    git cherry-pick $CHERRYCOMMIT; 
    git checkout $ORIGINALBRANCH; 
    git stash pop; 
done 
+0

Dlaczego więc nie przyjmiesz odpowiedzi jako rozwiązania? – Sampath

0

Nie sądzę, że jest jakaś droga do tego. Być może musisz napisać skrypt bash dla niego lub zrobić inne repo dla różnych gałęzi.

33

Funkcja cherry-pick będzie wykonać zadanie i będzie dotyczyć tylko ostatniego zatwierdzenia:

ZWAŻYWSZY branże A, B

git checkout A 
git commit -m "Fixed the bug x" 
git checkout B 
git cherry-pick A 

nadzieję, że to pomaga!

0

Można również zrobić piękny automatyzacji przy użyciu niektórych Python:

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

""" 
Populate specified or latest commit across all branches in the repository. 

""" 

import os 
import re 
import sys 
import sh 


git = sh.git.bake(_cwd=os.curdir) 

if len(sys.argv) > 1: 
    if '-h' in sys.argv or '--help' in sys.argv: 
     print('Usage: git-populate.py [commit] [-h|--help]') 
     sys.exit(0) 
    else: 
     commit = sys.argv[1] 
else: 
    # By default choose latest commit. 
    git_log = git('--no-pager', 'log', '-n', '1', '--no-color').stdout 
    commit = re.search(r'[a-f0-9]{40}', git_log).group() 

print('Commit to be populated: {0:.6s}'.format(commit)) 

git_branch = git.branch('-a', '--no-color').stdout 
source_branch = re.search(r'\*\s(\w+)$', git_branch, re.MULTILINE).group(1) 
print('Source branch: {0}'.format(source_branch)) 

branches = re.findall(r'remotes/\w+/([\w-]+)$', git_branch, re.MULTILINE) 
# Exclude current branch from target branches. 
branches = [i for i in branches if i != source_branch] 
print('Target branches: {0}'.format(branches)) 


print('Stashing local changes') 
git_stash = git.stash().stdout 

for branch in branches: 
    print('Ading commit {0:.6s} to branch {1}'.format(commit, branch)) 
    git.checkout(branch) 
    try: 
     result = git('cherry-pick', commit) 
    except sh.ErrorReturnCode_1: 
     # Ignore diplicate cherry pick and discard changes. 
     git.reset() 


git.checkout(source_branch) 
print('Return to branch {0}'.format(source_branch)) 

if not git_stash.startswith('No local changes to save'): 
    print('Restoring local changes') 
    git.stash.pop() 
0

To może zależeć od tego, jak idziesz do pchania zobowiązuje. Chodzi mi o to, że zawsze masz szansę na przejście do wielu gałęzi za pomocą jednej komendy git push.

Wykonaj następujące ustawienia .git/config, aby upewnić się, że gałąź master zawsze zostanie przesunięta do gałęzi foobar.

[remote "origin"] 
     url = [email protected]:mgerhardy/example.git 
     fetch = +refs/heads/*:refs/remotes/origin/* 
     push = refs/heads/master:refs/heads/master 
     push = refs/heads/master:refs/heads/foobar 

Ale problemem może być to, że jeśli te dwie gałęzie się rozdzieliły, nie można do nich naciskać.Nadal możesz zreorganizować swój kod, którego wykrywanie klienta opiera się na budowanym filtrze. W ten sposób możesz utrzymywać dziesiątki klientów i zawsze synchronizować wszystkie gałęzie.

0

Może to pomóc niektórym ludziom,

użyłem metodę "zestaw ho" s powyżej i dodaje go do .gitconfig jako alias.

; commitall commits to the current branch as well the all the branches mentionedin BRANCHES array var as shown below. 
commitall = "!f() { \ 
    BRANCHES=(\ 
    branches1 \ 
    branches2 \ 
    ); \ 
    usage() \ 
    { \ 
     echo \"Usage: git commitall -m 'JIRA: BRANCHNAME:<comment to check in>'\"; \ 
     exit 1; \ 
    }; \ 
    OPTIND=1; \ 
    DFNs=\"\"; \ 
    while getopts \"h:m:\" opt; \ 
    do \ 
     case \"$opt\" in \ 
      h) \ 
      usage; \ 
      ;; \ 
      m) export Comment=$OPTARG; \ 
      ;; \ 
     esac; \ 
    done; \ 
    ORIGINALBRANCH=`git symbolic-ref HEAD|cut -d/ -f3- `; \ 
    echo \"Current branch is $ORIGINALBRANCH \" ; \ 
    echo $Comment | grep \"^JIRA: $ORIGINALBRANCH:\" > /dev/null 2>&1 ; \ 
    if [ $? -ne 0 ]; then \ 
     usage; \ 
    fi; \ 
    LOGMSG=`git log -1 --pretty=%B --grep=\"JIRA: $ORIGINALBRANCH:\" `; \ 
    MSG='commit first time in this branch is a success' ; \ 
    if [ \"$LOGMSG\" == \"\" ]; then \ 
     git commit -m \"$Comment\"; \ 
    else \ 
     git commit -a --amend -C HEAD; \ 
     MSG='commit with amend succeeded' ; \ 
    fi; \ 
    if [ $? -ne 0 ]; then \ 
     echo \"git commit failed!\"; \ 
     exit 1; \ 
    else \ 
     echo \"$MSG\" ; \ 
    fi; \ 
    CHERRYCOMMIT=`git log -n1 | head -n 1 | cut -c8- ` ; \ 
    if [ \"$CHERRYCOMMIT\" == \"\" ]; then \ 
     echo \"'git log -n1 | head -n 1 | cut -c8-' no commits for this branch\"; \ 
     exit 1; \ 
    fi; \ 
    echo \"found this commit -> $CHERRYCOMMIT for current branch\"; \ 
    stashes=`git stash list | grep \"WIP on $ORIGINALBRANCH\" ` ; \ 
    for BRANCH in \"${BRANCHES[@]}\"; do \ 
     if [ \"$stashes\" ]; then \ 
      git stash; \ 
     fi;\ 
     git checkout $BRANCH; \ 
     if [ $? -ne 0 ]; then \ 
      echo \"git checkout $BRANCH failed!\"; \ 
      exit 1; \ 
     fi; \ 
     git cherry-pick $CHERRYCOMMIT; \ 
     git checkout $ORIGINALBRANCH; \ 
     if [ \"$stashes\" ]; then \ 
      git stash pop; \ 
     fi; \ 
    done; \ 
    }; \ 
f" 
Powiązane problemy