summaryrefslogtreecommitdiffstats
path: root/src/pyfedpkg/initial_merge.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/pyfedpkg/initial_merge.py')
-rwxr-xr-xsrc/pyfedpkg/initial_merge.py172
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:])