# HG changeset patch # User Jeff Hammel # Date 1279754339 25200 # Node ID ef895ddba2d3f6f6d27a0596061e2aea67c9939d # Parent 0bfbd062765dded10aee7be87270ee3852689f28 add an apply command diff -r 0bfbd062765d -r ef895ddba2d3 gut/command.py --- a/gut/command.py Wed Jul 21 13:49:46 2010 -0700 +++ b/gut/command.py Wed Jul 21 16:18:59 2010 -0700 @@ -183,6 +183,12 @@ elif value is False: parser.add_option('--%s' % key, action='store_true', default=False, help=help) + elif type(value) in set([type(()), type([])]): + if value: + help += ' [DEFAULT: %s]' % value + parser.add_option('--%s' % key, action='append', + default=list(value), + help=help) else: if value is not None: help += ' [DEFAULT: %s]' % value diff -r 0bfbd062765d -r ef895ddba2d3 gut/main.py --- a/gut/main.py Wed Jul 21 13:49:46 2010 -0700 +++ b/gut/main.py Wed Jul 21 16:18:59 2010 -0700 @@ -42,22 +42,33 @@ a workflow for git """ - def __init__(self, remote=None, simulate=False): + def __init__(self, remote=None, simulate=False, branches=('master',)): """ - remote: name of the remote repository in .git/config - simulate: print what calls will be used but don't run them + - branches: branches to apply to """ + + # sanity check + self.root() + self.remote = remote self.simulate = simulate + self.branches = branches if simulate: globals()['call'] = fake_call + def update(self): - """update the master and the branch you're on""" + """update the master""" + branch = self.branch() + if self.simulate: + branch = '' call(['git', 'checkout', 'master']) call(['git', 'pull', 'origin', 'master']) if self.remote: call(['git', 'pull', self.remote, 'master']) + call(['git', 'checkout', branch]) def feature(self, name): """make a new feature branch""" @@ -65,8 +76,13 @@ call(['git', 'checkout', '-b', name]) call(['git', 'push', 'origin', name]) - def patch(self, output=None): - """generate a patch for review""" + def patch(self, output=None, logfile=None): + """ + generate a patch for review + - output: name of patch + - logfile: name of file to output the log to [DEFAULT: stdout] + """ + self.update() diff = call(['git', 'diff', 'master'], pipe=True, output=False) log = call(['git', 'log', 'master..'], pipe=True, output=False) if self.simulate: @@ -107,17 +123,62 @@ f = file(output, 'w') # write the output to a patch file print >> f, diff f.close() - return log + + # output the log + if logfile: + f = file(logfile, 'w') # write the log to a file + print >> f, log + else: + return log + + def apply(self): + """ + apply the existing feature branch to master as a patch + """ + + # sanity check + branch = self.branch() + assert branch != 'master', "Can't apply master to itself!" + assert self.branches, "No branches defined!" + + # get the patch + self.patch(branch + '.diff', branch + '.log') + diff = os.path.abspath(branch + '.diff') + log = os.path.abspath(branch + '.log') + + # apply the patch + cwd = os.getcwd() + os.chdir(self.root()) + for b in self.branches: + call(['git', 'checkout', b]) + call(['patch -p1 < %s' % diff]) + call(['git', 'commit', '-a', '-F', log]) + call(['git', 'push', 'origin', b]) + if self.remote: + call(['git', 'push', self.remote, b]) + + # cleanup + call(['git', 'checkout', branch]) + os.chdir(cwd) def branch(self): """print what branch you're on""" output = call(['git', 'branch'], output=False, pipe=True) if self.simulate: - return + return for line in output['stdout'].splitlines(): if line.startswith('*'): return line[1:].strip() + def root(self): + """return (relative) root location of repository""" + + output = call(['git', 'rev-parse', '--show-cdup'], output=False, pipe=True) + location = output['stdout'].strip() + if not location: + return '.' + return location + def main(args=sys.argv[1:]): parser = CommandParser(gut) parser.invoke(args)