diff options
Diffstat (limited to 'src/pyfedpkg/initial_merge.py')
-rwxr-xr-x | src/pyfedpkg/initial_merge.py | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/pyfedpkg/initial_merge.py b/src/pyfedpkg/initial_merge.py new file mode 100755 index 0000000..22134ad --- /dev/null +++ b/src/pyfedpkg/initial_merge.py @@ -0,0 +1,172 @@ +#!/usr/bin/python +"""initial-merge.py - perform initial merge after dist-git migration + +initial-merge.py performs a merge of all git branches with the same +content in the directory tree, i.e. with the same packages. + +This is useful after Fedora's dist-cvs to dist-git migration, as often +different branches have different histories but the same content on the +filesystem. + +After these merges, future merges between the branches will be a lot +easier. + +Note that this is a standalone script which calls fedpkg via subprocess.Popen, +as fedpkg has a bunch of issues with changing CWD. +""" + +import sys +import os +import subprocess + + +global global_dry_run +global_dry_run = False +# global_dry_run = True + + +def run_cmd_out(cmd, dry_run=None, shell=False): + if dry_run==None: + dry_run = global_dry_run + if dry_run: + print 'RUN-', cmd + else: + print 'RUN:', cmd + if dry_run: + return (0,'','') + proc = subprocess.Popen(cmd, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + shell=shell) + stdout, stderr = proc.communicate() + return (proc.returncode,stdout,stderr) + + +def run_cmd(cmd, dry_run=None, shell=False): + retcode, stdout, stderr = run_cmd_out(cmd, dry_run=dry_run, shell=shell) + sys.stdout.write(stdout) + sys.stdout.write(stderr) + return retcode + + +def cmp_Branch(a, b): + if a.sha == b.sha: + return cmp(a.localbranch,b.localbranch) + else: + return cmp(a.sha,b.sha) + + +class Branch: + + def __init__(self, string): + self.sha, self.origbranch = string.split() + a = self.origbranch.split('/') + assert(a[0] == 'origin') + assert(a[-1] == 'master') + self.localbranch = a[1] + + def __repr__(self): + return "%(sha)s %(origbranch)s" % self.__dict__ + + +def switch_branch(branch): + ret = run_cmd(['fedpkg', 'switch-branch', branch], dry_run=False) + assert(ret == 0) + + +def do_initial_merge(into, to_merge): + print + print "######## Merging", [ x.localbranch for x in to_merge ], \ + "into", into.localbranch, "########" + switch_branch(into.localbranch) + ret = run_cmd(['git', 'merge', + '-m', '"Initial peudo merge for dist-git setup"', + '-s', 'ours'] + + [ x.origbranch for x in to_merge]) + assert(ret == 0) + for t in to_merge: + switch_branch(t.localbranch) + ret = run_cmd(['git', 'merge', into.localbranch]) + assert(ret == 0) + + +class Consumer: + + def __reset(self): + self.branch_list = [] + + def __init__(self): + self.__reset() + + def __git_merge(self): + head = self.branch_list[-1] + others = self.branch_list[:-1] + do_initial_merge(head, others) + + def __flush(self): + if len(self.branch_list) < 2: + return + # print "Flush", self.branch_list + self.__git_merge() + self.__reset() + + def eat(self, item): + if self.branch_list: + last = self.branch_list[-1] + if last.sha == item.sha: + # print " ", "=", item + self.branch_list.extend([item]) + else: + # print " ", "?", item + self.__flush() + self.branch_list = [item] + else: + self.branch_list = [item] + + def finish(self): + self.__flush() + + +def handle_directory(): + + git_branch_cmd = """for branch in $(git branch -r | grep -v '/HEAD'); do echo "$(git rev-parse "$branch^{tree}") $branch"; done""" + retcode, stdout, stderr = run_cmd_out(git_branch_cmd, + dry_run=False, shell=True) + assert(retcode == 0) + assert(stderr == "") + # print "RESULT:" + # sys.stdout.write(stdout) + + a = stdout.splitlines() + a = [ Branch(s) for s in a ] + a.sort(cmp_Branch) + # print "SORTED:" + for x in a: print " ", x + + # print "ITERATING:" + n = 0 + c = Consumer() + while n < len(a): + c.eat(a[n]) + n = n + 1 + c.finish() + + print + print "FINISHED." + + +def main(args): + if args: + for d in args: + oldcwd = os.getcwd() + os.chdir(d) + print "########", "Entering", d, "########" + handle_directory() + print "Leaving", os.getcwd() + os.chdir(oldcwd) + else: + handle_directory() + + +if __name__ == '__main__': + main(sys.argv[1:]) |