def CMDfreeze(parser, args): """Freeze a branch's changes.""" parser.parse_args(args) return freeze()
def main(args=None): parser = argparse.ArgumentParser() parser.add_argument('--verbose', '-v', action='store_true') parser.add_argument('--keep-going', '-k', action='store_true', help='Keep processing past failed rebases.') parser.add_argument('--no_fetch', '--no-fetch', '-n', action='store_true', help='Skip fetching remotes.') opts = parser.parse_args(args) if opts.verbose: # pragma: no cover logging.getLogger().setLevel(logging.DEBUG) # TODO(iannucci): snapshot all branches somehow, so we can implement # `git rebase-update --undo`. # * Perhaps just copy packed-refs + refs/ + logs/ to the side? # * commit them to a secret ref? # * Then we could view a summary of each run as a # `diff --stat` on that secret ref. if git.in_rebase(): # TODO(iannucci): Be able to resume rebase with flags like --continue, # etc. print ( 'Rebase in progress. Please complete the rebase before running ' '`git rebase-update`.' ) return 1 return_branch, return_workdir = find_return_branch_workdir() os.chdir(git.run('rev-parse', '--show-toplevel')) if git.current_branch() == 'HEAD': if git.run('status', '--porcelain'): print 'Cannot rebase-update with detached head + uncommitted changes.' return 1 else: git.freeze() # just in case there are any local changes. skipped, branch_tree = git.get_branch_tree() for branch in skipped: print 'Skipping %s: No upstream specified' % branch if not opts.no_fetch: fetch_remotes(branch_tree) merge_base = {} for branch, parent in branch_tree.iteritems(): merge_base[branch] = git.get_or_create_merge_base(branch, parent) logging.debug('branch_tree: %s' % pformat(branch_tree)) logging.debug('merge_base: %s' % pformat(merge_base)) retcode = 0 unrebased_branches = [] # Rebase each branch starting with the root-most branches and working # towards the leaves. for branch, parent in git.topo_iter(branch_tree): if git.is_dormant(branch): print 'Skipping dormant branch', branch else: ret = rebase_branch(branch, parent, merge_base[branch]) if not ret: retcode = 1 if opts.keep_going: print '--keep-going set, continuing with next branch.' unrebased_branches.append(branch) if git.in_rebase(): git.run_with_retcode('rebase', '--abort') if git.in_rebase(): # pragma: no cover print 'Failed to abort rebase. Something is really wrong.' break else: break if unrebased_branches: print print 'The following branches could not be cleanly rebased:' for branch in unrebased_branches: print ' %s' % branch if not retcode: remove_empty_branches(branch_tree) # return_branch may not be there any more. if return_branch in git.branches(): git.run('checkout', return_branch) git.thaw() else: root_branch = git.root() if return_branch != 'HEAD': print ( "%r was merged with its parent, checking out %r instead." % (return_branch, root_branch) ) git.run('checkout', root_branch) if return_workdir: os.chdir(return_workdir) git.set_config(STARTING_BRANCH_KEY, '') git.set_config(STARTING_WORKDIR_KEY, '') return retcode