Esempio n. 1
0
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
Esempio n. 2
0
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