def main(): remote = git_common.run('remote') # Use first remote as source of truth remote = remote.split("\n")[0] if not remote: raise RuntimeError('Could not find any remote') url = scm.GIT.GetConfig(git_common.repo_root(), 'remote.%s.url' % remote) host = urllib.parse.urlparse(url).netloc if not host: raise RuntimeError('Could not find remote host') project_head = gerrit_util.GetProjectHead(GetGerritHost(host), GetGerritProject(url)) if project_head != 'refs/heads/main': raise RuntimeError("The repository is not migrated yet.") logging.info("Running fetch...") git_common.run('fetch', remote) logging.info("Updating remote HEAD...") git_common.run('remote', 'set-head', '-a', remote) branches = git_common.get_branches_info(True) if 'master' in branches: logging.info("Migrating master branch...") if 'main' in branches: logging.info( 'You already have master and main branch, consider removing ' 'master manually:\n' ' $ git branch -d master\n') else: git_common.run('branch', '-m', 'master', 'main') branches = git_common.get_branches_info(True) for name in branches: branch = branches[name] if not branch: continue if 'master' in branch.upstream: logging.info("Migrating %s branch..." % name) new_upstream = branch.upstream.replace('master', 'main') git_common.run('branch', '--set-upstream-to', new_upstream, name) git_common.remove_merge_base(name)
def main(argv): parser = argparse.ArgumentParser( description=__doc__.strip().splitlines()[0], epilog=' '.join(__doc__.strip().splitlines()[1:])) g = parser.add_mutually_exclusive_group() g.add_argument( 'merge_base', nargs='?', help='The new hash to use as the merge base for the current branch') g.add_argument('--delete', '-d', action='store_true', help='Remove the set mark.') opts = parser.parse_args(argv) cur = current_branch() if opts.delete: try: remove_merge_base(cur) except CalledProcessError: print "No merge base currently exists for %s." % cur return 0 if opts.merge_base: try: opts.merge_base = hash_one(opts.merge_base) except CalledProcessError: print >> sys.stderr, ('fatal: could not resolve %s as a commit' % (opts.merge_base)) return 1 manual_merge_base(cur, opts.merge_base, upstream(cur)) ret = 0 actual = get_or_create_merge_base(cur) if opts.merge_base and opts.merge_base != actual: ret = 1 print "Invalid merge_base %s" % opts.merge_base print "merge_base(%s): %s" % (cur, actual) return ret
def main(argv): parser = argparse.ArgumentParser( description=__doc__.strip().splitlines()[0], epilog=' '.join(__doc__.strip().splitlines()[1:])) g = parser.add_mutually_exclusive_group() g.add_argument( 'merge_base', nargs='?', help='The new hash to use as the merge base for the current branch' ) g.add_argument('--delete', '-d', action='store_true', help='Remove the set mark.') opts = parser.parse_args(argv) cur = current_branch() if opts.delete: try: remove_merge_base(cur) except CalledProcessError: print "No merge base currently exists for %s." % cur return 0 if opts.merge_base: try: opts.merge_base = hash_one(opts.merge_base) except CalledProcessError: print >> sys.stderr, ( 'fatal: could not resolve %s as a commit' % (opts.merge_base) ) return 1 manual_merge_base(cur, opts.merge_base) ret = 0 actual = get_or_create_merge_base(cur) if opts.merge_base and opts.merge_base != actual: ret = 1 print "Invalid merge_base %s" % opts.merge_base print "merge_base(%s): %s" % (cur, actual) return ret
def rebase_branch(branch, parent, start_hash): logging.debug('considering %s(%s) -> %s(%s) : %s', branch, git.hash_one(branch), parent, git.hash_one(parent), start_hash) # If parent has FROZEN commits, don't base branch on top of them. Instead, # base branch on top of whatever commit is before them. back_ups = 0 orig_parent = parent while git.run('log', '-n1', '--format=%s', parent, '--').startswith(git.FREEZE): back_ups += 1 parent = git.run('rev-parse', parent+'~') if back_ups: logging.debug('Backed parent up by %d from %s to %s', back_ups, orig_parent, parent) if git.hash_one(parent) != start_hash: # Try a plain rebase first print 'Rebasing:', branch rebase_ret = git.rebase(parent, start_hash, branch, abort=True) if not rebase_ret.success: # TODO(iannucci): Find collapsible branches in a smarter way? print "Failed! Attempting to squash", branch, "...", squash_branch = branch+"_squash_attempt" git.run('checkout', '-b', squash_branch) git.squash_current_branch(merge_base=start_hash) # Try to rebase the branch_squash_attempt branch to see if it's empty. squash_ret = git.rebase(parent, start_hash, squash_branch, abort=True) empty_rebase = git.hash_one(squash_branch) == git.hash_one(parent) git.run('checkout', branch) git.run('branch', '-D', squash_branch) if squash_ret.success and empty_rebase: print 'Success!' git.squash_current_branch(merge_base=start_hash) git.rebase(parent, start_hash, branch) else: print "Failed!" print # rebase and leave in mid-rebase state. # This second rebase attempt should always fail in the same # way that the first one does. If it magically succeeds then # something very strange has happened. second_rebase_ret = git.rebase(parent, start_hash, branch) if second_rebase_ret.success: # pragma: no cover print "Second rebase succeeded unexpectedly!" print "Please see: http://crbug.com/425696" print "First rebased failed with:" print rebase_ret.stderr else: print "Here's what git-rebase (squashed) had to say:" print print squash_ret.stdout print squash_ret.stderr print textwrap.dedent( """\ Squashing failed. You probably have a real merge conflict. Your working copy is in mid-rebase. Either: * completely resolve like a normal git-rebase; OR * abort the rebase and mark this branch as dormant: git config branch.%s.dormant true And then run `git rebase-update` again to resume. """ % branch) return False else: print '%s up-to-date' % branch git.remove_merge_base(branch) git.get_or_create_merge_base(branch) return True
def rebase_branch(branch, parent, start_hash): logging.debug('considering %s(%s) -> %s(%s) : %s', branch, git.hash_one(branch), parent, git.hash_one(parent), start_hash) # If parent has FROZEN commits, don't base branch on top of them. Instead, # base branch on top of whatever commit is before them. back_ups = 0 orig_parent = parent while git.run('log', '-n1', '--format=%s', parent, '--').startswith(git.FREEZE): back_ups += 1 parent = git.run('rev-parse', parent + '~') if back_ups: logging.debug('Backed parent up by %d from %s to %s', back_ups, orig_parent, parent) if git.hash_one(parent) != start_hash: # Try a plain rebase first print 'Rebasing:', branch rebase_ret = git.rebase(parent, start_hash, branch, abort=True) if not rebase_ret.success: # TODO(iannucci): Find collapsible branches in a smarter way? print "Failed! Attempting to squash", branch, "...", squash_branch = branch + "_squash_attempt" git.run('checkout', '-b', squash_branch) git.squash_current_branch(merge_base=start_hash) # Try to rebase the branch_squash_attempt branch to see if it's empty. squash_ret = git.rebase(parent, start_hash, squash_branch, abort=True) empty_rebase = git.hash_one(squash_branch) == git.hash_one(parent) git.run('checkout', branch) git.run('branch', '-D', squash_branch) if squash_ret.success and empty_rebase: print 'Success!' git.squash_current_branch(merge_base=start_hash) git.rebase(parent, start_hash, branch) else: print "Failed!" print # rebase and leave in mid-rebase state. # This second rebase attempt should always fail in the same # way that the first one does. If it magically succeeds then # something very strange has happened. second_rebase_ret = git.rebase(parent, start_hash, branch) if second_rebase_ret.success: # pragma: no cover print "Second rebase succeeded unexpectedly!" print "Please see: http://crbug.com/425696" print "First rebased failed with:" print rebase_ret.stderr else: print "Here's what git-rebase (squashed) had to say:" print print squash_ret.stdout print squash_ret.stderr print textwrap.dedent("""\ Squashing failed. You probably have a real merge conflict. Your working copy is in mid-rebase. Either: * completely resolve like a normal git-rebase; OR * abort the rebase and mark this branch as dormant: git config branch.%s.dormant true And then run `git rebase-update` again to resume. """ % branch) return False else: print '%s up-to-date' % branch git.remove_merge_base(branch) git.get_or_create_merge_base(branch) return True