def main(): ap = argparse.ArgumentParser(description='Create a new patch', prog='git qnew') ap.add_argument('pname', help='Name of patch') ap.add_argument('-a', dest='all', help='Add all unstaged changes to patch', action='store_true', default=False) ap.add_argument('-m', dest='commitmsg', help='Commit message for patch', default=None) # TODO - handle different username/email args = ap.parse_args() # Make sure we have all the config we need gitq.include_config() # Make sure our queue directory is setup if not os.path.exists(pgl.config['QUEUE_SERIES']): if not os.path.exists(pgl.config['BRANCH_QUEUE']): if not os.path.exists(pgl.config['QUEUES']): os.mkdir(pgl.config['QUEUES']) os.mkdir(pgl.config['BRANCH_QUEUE']) file(pgl.config['QUEUE_SERIES'], 'w').close() if not os.path.exists(pgl.config['UNAPPLIED_PATCHES']): file(pgl.config['UNAPPLIED_PATCHES'], 'w').close() if not os.path.exists(pgl.config['SHA_NAME_MAP']): file(pgl.config['SHA_NAME_MAP'], 'w').close() # Make sure we don't already have a patch named like the one we want gitq.load_series() # Commit outstanding changes if not gitq.update_patch( commit_all=args.all, commitmsg=args.commitmsg, new=True): pgl.die('Nothing to make a new patch from!') # Do this again here to figure out the base of our new patch gitq.include_config() patchbase = pgl.config['HEAD_SHA'] # Update our stored idea of the patch series on disk pgl.config['SERIES'].append(patchbase) pgl.config['ACTIVE_PATCH'] = patchbase pgl.config['NAMES'][patchbase] = args.pname gitq.write_series() # Done! sys.stdout.write('Started new patch on branch %s\n' % (pgl.config['BRANCH'], )) return 0
def main(): ap = argparse.ArgumentParser(description='Create a new patch', prog='git qnew') ap.add_argument('pname', help='Name of patch') ap.add_argument('-a', dest='all', help='Add all unstaged changes to patch', action='store_true', default=False) ap.add_argument('-m', dest='commitmsg', help='Commit message for patch', default=None) # TODO - handle different username/email args = ap.parse_args() # Make sure we have all the config we need gitq.include_config() # Make sure our queue directory is setup if not os.path.exists(pgl.config['QUEUE_SERIES']): if not os.path.exists(pgl.config['BRANCH_QUEUE']): if not os.path.exists(pgl.config['QUEUES']): os.mkdir(pgl.config['QUEUES']) os.mkdir(pgl.config['BRANCH_QUEUE']) file(pgl.config['QUEUE_SERIES'], 'w').close() if not os.path.exists(pgl.config['UNAPPLIED_PATCHES']): file(pgl.config['UNAPPLIED_PATCHES'], 'w').close() if not os.path.exists(pgl.config['SHA_NAME_MAP']): file(pgl.config['SHA_NAME_MAP'], 'w').close() # Make sure we don't already have a patch named like the one we want gitq.load_series() # Commit outstanding changes if not gitq.update_patch(commit_all=args.all, commitmsg=args.commitmsg, new=True): pgl.die('Nothing to make a new patch from!') # Do this again here to figure out the base of our new patch gitq.include_config() patchbase = pgl.config['HEAD_SHA'] # Update our stored idea of the patch series on disk pgl.config['SERIES'].append(patchbase) pgl.config['ACTIVE_PATCH'] = patchbase pgl.config['NAMES'][patchbase] = args.pname gitq.write_series() # Done! sys.stdout.write('Started new patch on branch %s\n' % (pgl.config['BRANCH'],)) return 0
def main(): ap = argparse.ArgumentParser(description='Update a patch', prog='git qrefresh') ap.add_argument('-a', dest='all', help='Add all unstaged changes to patch', action='store_true', default=False) args = ap.parse_args() gitq.include_config() gitq.load_series() if not os.path.exists(pgl.config['QUEUE_SERIES']): pgl.die('There is no git queue for branch %s here!' % (pgl.config['BRANCH'],)) if not gitq.update_patch(commit_all=args.all): pgl.die('There was nothing to update the patch with!') return 0
def main(): # Make sure we have all the config we need gitq.include_config() gitq.load_series() patchbase = pgl.config['ACTIVE_PATCH'] if not patchbase: pgl.die('No patches for this branch!') # Make sure we have no uncommitted changes if gitq.repo_has_changes(): pgl.die('Working copy has uncommitted stages. Either qrefresh or ' 'stash them before continuing.') # Write the patch to disk using format-patch patchdir = os.path.join(pgl.config['BRANCH_QUEUE'], patchbase) os.mkdir(patchdir) gfp = subprocess.Popen(['git', 'format-patch', '-o', patchdir, '--no-signature', '-n', '--no-stat', '%s~1' % (patchbase,)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if gfp.wait(): pgl.die('Failed to save patch') # Reset our working copy to before the patch reset_point = '%s~1' % (patchbase,) gitreset = subprocess.Popen(['git', 'reset', '--hard', reset_point], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if gitreset.wait(): shutil.rmtree(patchdir) pgl.die('Failed to pop patch') # Move our now-saved patch into the unapplied list and save new state pgl.config['SERIES'] = pgl.config['SERIES'][:-1] pgl.config['UNAPPLIED'].append(patchbase) gitq.write_series() return 0
def do_cleanup_and_fix_series(patchdir_ref, patchdir, apply_sha, apply_name): """Performs cleanup and re-writing of metadata after a qpush succeeds """ # Remove cache of patchdir os.unlink(patchdir_ref) # Remove saved patches directory shutil.rmtree(patchdir) # Put our reapplied patch in the series, and save to disk gitq.include_config() # Re-read HEAD sha pgl.config['SERIES'].append(pgl.config['HEAD_SHA']) pgl.config['UNAPPLIED'].remove(apply_sha) # Now that we may (or may not) have a new base sha for this patch, # update that info, too pgl.config['SHAS'][apply_name] = pgl.config['HEAD_SHA'] del pgl.config['NAMES'][apply_sha] pgl.config['NAMES'][pgl.config['HEAD_SHA']] = apply_name gitq.write_series()
def main(): ap = argparse.ArgumentParser(description='Commit an applied queue series', prog='git qcommit') ap.add_argument('branch', help='Branch to commit to', default='master', nargs='?') ap.add_argument('--resolved', dest='resolved', help='Continue paused qcommit', default=False, action='store_true') ap.add_argument('--abort', dest='abort', help='Abort paused qcommit', default=False, action='store_true') args = ap.parse_args() if gitq.repo_has_changes(): pgl.die('Working copy has changes. Stash or commit to continue.') gitq.include_config() gitq.load_series() patchdir = os.path.join(pgl.config['QUEUES'], 'qcommit_patches') abfile = os.path.join(pgl.config['QUEUES'], 'abortbranch') if args.abort: # Abort the underlying git-am gitam = subprocess.Popen(['git', 'am', '--abort']) gitam.wait() # Figure out our original branch was abortbranch = None with file(abfile) as f: abortbranch = f.read() # Go back to our original branch gc = subprocess.Popen(['git', 'checkout', '-b', abortbranch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() # Figure out what commit we were at before this mess started gsr = subprocess.Popen(['git', 'symbolic-ref', 'QPATCH_HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = gsr.readlines() gsr.wait() sha = lines[0].strip() # Reset to that commit so we're back where we started gr = subprocess.Popen(['git', 'reset', '--hard', sha], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gr.wait() do_cleanup(patchdir, abfile) return 0 if args.resolved: # Tell our underlying git-am to keep going gitam = subprocess.Popen(['git', 'am', '--resolved', '--reject'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) do_cleanup_and_empty_series(patchdir, abfile) return 0 # Make sure we know where to apply our patches grp = subprocess.Popen(['git', 'rev-parse', '--verify', args.branch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if grp.wait(): pgl.die('Could not find branch %s' % (args.branch,)) # Make sure our temporary patch location isn't already in use if os.path.exists(patchdir): gitstart = patchdir.rindex('.git') pgl.die("It appears that another 'git qcommit' is already in progress.\n" "Remove %s if that is not the case." % (patchdir[gitstart:],)) # Figure out what branch we're on gb = subprocess.Popen(['git', 'branch', '--color=never', '--contains', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = gb.stdout.readlines() gb.wait() for l in lines: if l.startswith('*'): abortbranch = l.strip().split()[-1] with file(abfile, 'w') as f: f.write(abortbranch) break # Use our patch generator to create patches for git-am gqp = subprocess.Popen(['git', 'qpatch', '--nocleanup', '-o', patchdir], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if gqp.wait(): pgl.die('Error exporting patches for commit') # Get our list of patches to apply patches = glob.glob(os.path.join(patchdir, '*.patch')) # Go to our destination branch gc = subprocess.Popen(['git', 'checkout', args.branch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() # Now run git am gaargs = ['git', 'am', '--reject'] gaargs.extend(patches) gitam = subprocess.Popen(gaargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) do_cleanup_and_empty_series(patchdir, abfile) return 0
def main(): ap = argparse.ArgumentParser(description='Commit an applied queue series', prog='git qcommit') ap.add_argument('branch', help='Branch to commit to', default='master', nargs='?') ap.add_argument('--resolved', dest='resolved', help='Continue paused qcommit', default=False, action='store_true') ap.add_argument('--abort', dest='abort', help='Abort paused qcommit', default=False, action='store_true') args = ap.parse_args() if gitq.repo_has_changes(): pgl.die('Working copy has changes. Stash or commit to continue.') gitq.include_config() gitq.load_series() patchdir = os.path.join(pgl.config['QUEUES'], 'qcommit_patches') abfile = os.path.join(pgl.config['QUEUES'], 'abortbranch') if args.abort: # Abort the underlying git-am gitam = subprocess.Popen(['git', 'am', '--abort']) gitam.wait() # Figure out our original branch was abortbranch = None with file(abfile) as f: abortbranch = f.read() # Go back to our original branch gc = subprocess.Popen(['git', 'checkout', '-b', abortbranch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() # Figure out what commit we were at before this mess started gsr = subprocess.Popen(['git', 'symbolic-ref', 'QPATCH_HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = gsr.readlines() gsr.wait() sha = lines[0].strip() # Reset to that commit so we're back where we started gr = subprocess.Popen(['git', 'reset', '--hard', sha], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gr.wait() do_cleanup(patchdir, abfile) return 0 if args.resolved: # Tell our underlying git-am to keep going gitam = subprocess.Popen(['git', 'am', '--resolved', '--reject'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) do_cleanup_and_empty_series(patchdir, abfile) return 0 # Make sure we know where to apply our patches grp = subprocess.Popen(['git', 'rev-parse', '--verify', args.branch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if grp.wait(): pgl.die('Could not find branch %s' % (args.branch, )) # Make sure our temporary patch location isn't already in use if os.path.exists(patchdir): gitstart = patchdir.rindex('.git') pgl.die( "It appears that another 'git qcommit' is already in progress.\n" "Remove %s if that is not the case." % (patchdir[gitstart:], )) # Figure out what branch we're on gb = subprocess.Popen( ['git', 'branch', '--color=never', '--contains', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = gb.stdout.readlines() gb.wait() for l in lines: if l.startswith('*'): abortbranch = l.strip().split()[-1] with file(abfile, 'w') as f: f.write(abortbranch) break # Use our patch generator to create patches for git-am gqp = subprocess.Popen(['git', 'qpatch', '--nocleanup', '-o', patchdir], stdout=subprocess.PIPE, stderr=subprocess.PIPE) if gqp.wait(): pgl.die('Error exporting patches for commit') # Get our list of patches to apply patches = glob.glob(os.path.join(patchdir, '*.patch')) # Go to our destination branch gc = subprocess.Popen(['git', 'checkout', args.branch], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() # Now run git am gaargs = ['git', 'am', '--reject'] gaargs.extend(patches) gitam = subprocess.Popen(gaargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) do_cleanup_and_empty_series(patchdir, abfile) return 0
def main(): gitq.include_config() gitq.load_series() os.execvp('git', ['git', 'diff', '%s~1' % (pgl.config['ACTIVE_PATCH'],)])
def main(): ap = argparse.ArgumentParser( description='Make patches for the current queue', prog='git qpatch') ap.add_argument('--hg', dest='hg', help='Make an HG-style patch', action='store_true', default=False) ap.add_argument('-o', dest='outdir', help='Directory to write patches to', default='.') ap.add_argument('--nocleanup', dest='nocleanup', help='Do not reset to QPATCH_HEAD after creating patches', default=False, action='store_true') args = ap.parse_args() if gitq.repo_has_changes(): pgl.die('Working copy has uncommitted changes. Either stash or commit ' 'them to continue') gitq.include_config() gitq.load_series() # Figure out our current HEAD so we can reset to it grp = subprocess.Popen(['git', 'rev-parse', '--verify', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = grp.stdout.readlines() if grp.wait(): pgl.die('Could not figure out HEAD') orig_head = lines[0].strip() if not orig_head: pgl.die('Could not figure out HEAD sha') # Set up a symbolic ref so we can get back to where we were gsr = subprocess.Popen(['git', 'symbolic-ref', 'QPATCH_HEAD', orig_head], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gsr.wait() # Squash down our patches into a sane set of patches base = '%s~1' % (pgl.config['SERIES'][0],) grenv = copy.deepcopy(os.environ) grenv['GIT_EDITOR'] = 'true' gr = subprocess.Popen(['git', 'rebase', '-i', '--autosquash', base], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=grenv) gr.wait() # Use format-patch to make the patches gfpargs = ['git', 'format-patch', '-n'] if args.hg: gfpargs.extend(['--no-signature', '--no-stat']) if args.outdir != '.': gfpargs.extend(['-o', args.outdir]) gfpargs.append(base) gfp = subprocess.Popen(gfpargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) patches = gfp.stdout.readlines() gfp.wait() # Make into hg-style patches if necessary if args.hg: for patch in patches: # Write out to a temporary file fname = patch.strip() fname_out = '%s.temp' % (fname,) fin = file(fname) fout = file(fname_out, 'w') fout.writelines(hgify(fin)) fin.close() fout.close() # And move the temp file into place os.unlink(fname) os.rename(fname_out, fname) if not args.nocleanup: # Finally, go back to our original state gc = subprocess.Popen(['git', 'reset', '--hard', orig_head], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() return 0
def main(): ap = argparse.ArgumentParser(description='Apply a popped patch', prog='git qpush') ap.add_argument('pname', help='Name of patch', default=None, nargs='?') ap.add_argument('-i', dest='interactive', help='Choose patch interactively', default=False, action='store_true') ap.add_argument('--resolved', dest='resolved', help='Continue paused qpush', default=False, action='store_true') ap.add_argument('--abort', dest='abort', help='Abort paused qpush', default=False, action='store_true') args = ap.parse_args() # Make sure we have all the config we need gitq.include_config() gitq.load_series() if args.abort: gitam = subprocess.Popen(['git', 'am', '--abort']) return gitam.wait() if args.resolved: gitam = subprocess.Popen(['git', 'am', '--resolved', '--reject'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) patchdir_ref = os.path.join(pgl.config['QUEUES'], 'applying_dir') patchdir = None with file(patchdir_ref) as f: patchdir = f.read() apply_sha = os.path.split(patchdir)[1] apply_name = pgl.config['NAMES'][apply_sha] do_cleanup_and_fix_series(patchdir_ref, patchdir, apply_sha, apply_name) return 0 # Make sure we have no uncommitted changes if gitq.repo_has_changes(): pgl.die('Working directory has uncommitted changes. Either qrefresh ' 'or stash them before continuing.') if not pgl.config['UNAPPLIED']: pgl.die('No patches for this branch!') # Figure out what patch to apply if they didn't specify on the command line apply_sha, apply_name = None, None if args.interactive: while apply_sha is None: sys.stdout.write('Choose a patch to apply:\n') for i, sha in enumerate(pgl.config['UNAPPLIED']): sys.stdout.write('%d %s\n' % (i + 1, pgl.config['NAMES'][sha])) sys.stdout.flush() choice = raw_input('> ') try: if 0 < int(choice) <= len(pgl.config['UNAPPLIED']): apply_sha = pgl.config['UNAPPLIED'][choice - 1] apply_name = pgl.config['NAMES'][apply_sha] except ValueError: pass elif args.pname: if args.pname not in pgl.config['SHAS']: pgl.die('Unknown patch: %s' % (args.pname,)) apply_name = args.pname apply_sha = pgl.config['SHAS'][args.pname] else: apply_sha = pgl.config['UNAPPLIED'][-1] apply_name = pgl.config['NAMES'][apply_sha] # Get the list of patches to apply using git-am patchdir = os.path.join(pgl.config['BRANCH_QUEUE'], apply_sha) if not os.path.exists(patchdir): pgl.die('Missing patch directory for %s. Oops!' % (apply_name,)) patches = glob.glob(os.path.join(patchdir, '*.patch')) if not patches: pgl.die('Missing patches for %s. Oops!' % (apply_name,)) # Save our patchdir off for later use patchdir_ref = os.path.join(pgl.config['QUEUES'], 'applying_dir') with file(patchdir_ref, 'w') as f: f.write(patchdir) # Re-apply the patches gitamargs = ['git', 'am', '--reject'] gitamargs.extend(patches) gitam = subprocess.Popen(gitamargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) check_am_and_maybe_die(gitam) do_cleanup_and_fix_series(patchdir_ref, patchdir, apply_sha, apply_name) return 0
def main(): ap = argparse.ArgumentParser( description='Make patches for the current queue', prog='git qpatch') ap.add_argument('--hg', dest='hg', help='Make an HG-style patch', action='store_true', default=False) ap.add_argument('-o', dest='outdir', help='Directory to write patches to', default='.') ap.add_argument('--nocleanup', dest='nocleanup', help='Do not reset to QPATCH_HEAD after creating patches', default=False, action='store_true') args = ap.parse_args() if gitq.repo_has_changes(): pgl.die('Working copy has uncommitted changes. Either stash or commit ' 'them to continue') gitq.include_config() gitq.load_series() # Figure out our current HEAD so we can reset to it grp = subprocess.Popen(['git', 'rev-parse', '--verify', 'HEAD'], stdout=subprocess.PIPE, stderr=subprocess.PIPE) lines = grp.stdout.readlines() if grp.wait(): pgl.die('Could not figure out HEAD') orig_head = lines[0].strip() if not orig_head: pgl.die('Could not figure out HEAD sha') # Set up a symbolic ref so we can get back to where we were gsr = subprocess.Popen(['git', 'symbolic-ref', 'QPATCH_HEAD', orig_head], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gsr.wait() # Squash down our patches into a sane set of patches base = '%s~1' % (pgl.config['SERIES'][0], ) grenv = copy.deepcopy(os.environ) grenv['GIT_EDITOR'] = 'true' gr = subprocess.Popen(['git', 'rebase', '-i', '--autosquash', base], stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=grenv) gr.wait() # Use format-patch to make the patches gfpargs = ['git', 'format-patch', '-n'] if args.hg: gfpargs.extend(['--no-signature', '--no-stat']) if args.outdir != '.': gfpargs.extend(['-o', args.outdir]) gfpargs.append(base) gfp = subprocess.Popen(gfpargs, stdout=subprocess.PIPE, stderr=subprocess.PIPE) patches = gfp.stdout.readlines() gfp.wait() # Make into hg-style patches if necessary if args.hg: for patch in patches: # Write out to a temporary file fname = patch.strip() fname_out = '%s.temp' % (fname, ) fin = file(fname) fout = file(fname_out, 'w') fout.writelines(hgify(fin)) fin.close() fout.close() # And move the temp file into place os.unlink(fname) os.rename(fname_out, fname) if not args.nocleanup: # Finally, go back to our original state gc = subprocess.Popen(['git', 'reset', '--hard', orig_head], stdout=subprocess.PIPE, stderr=subprocess.PIPE) gc.wait() return 0
def main(): gitq.include_config() gitq.load_series() os.execvp('git', ['git', 'diff', '%s~1' % (pgl.config['ACTIVE_PATCH'], )])