Example #1
0
def main(args):
  parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter
  )
  parser.add_argument('branch_name')
  g = parser.add_mutually_exclusive_group()
  g.add_argument('--upstream_current', action='store_true',
                 help='set upstream branch to current branch.')
  g.add_argument('--upstream', metavar='REF', default=root(),
                 help='upstream branch (or tag) to track.')
  g.add_argument('--lkgr', action='store_const', const='lkgr', dest='upstream',
                 help='set basis ref for new branch to lkgr.')

  opts = parser.parse_args(args)

  try:
    if opts.upstream_current:
      run('checkout', '--track', '-b', opts.branch_name)
    else:
      if opts.upstream in tags():
        # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
        run('checkout', '--no-track', '-b', opts.branch_name,
            hash_one(opts.upstream))
        set_config('branch.%s.remote' % opts.branch_name, '.')
        set_config('branch.%s.merge' % opts.branch_name, opts.upstream)
      else:
        # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
        # teleport to a conflicting portion of history?
        run('checkout', '--track', opts.upstream, '-b', opts.branch_name)

    get_or_create_merge_base(opts.branch_name)
  except subprocess2.CalledProcessError as cpe:
    sys.stdout.write(cpe.stdout)
    sys.stderr.write(cpe.stderr)
    return 1
Example #2
0
def main(args):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter,
        description=__doc__,
    )
    parser.add_argument('branch_name')
    g = parser.add_mutually_exclusive_group()
    g.add_argument('--upstream-current',
                   '--upstream_current',
                   action='store_true',
                   help='set upstream branch to current branch.')
    g.add_argument('--upstream',
                   metavar='REF',
                   default=root(),
                   help='upstream branch (or tag) to track.')
    g.add_argument('--inject-current',
                   '--inject_current',
                   action='store_true',
                   help='new branch adopts current branch\'s upstream,' +
                   ' and new branch becomes current branch\'s upstream.')
    g.add_argument('--lkgr',
                   action='store_const',
                   const='lkgr',
                   dest='upstream',
                   help='set basis ref for new branch to lkgr.')

    opts = parser.parse_args(args)

    try:
        if opts.inject_current:
            below = current_branch()
            if below is None:
                raise Exception('no current branch')
            above = upstream(below)
            if above is None:
                raise Exception('branch %s has no upstream' % (below))
            run('checkout', '--track', above, '-b', opts.branch_name)
            run('branch', '--set-upstream-to', opts.branch_name, below)
        elif opts.upstream_current:
            run('checkout', '--track', '-b', opts.branch_name)
        else:
            if opts.upstream in tags():
                # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
                run('checkout', '--no-track', '-b', opts.branch_name,
                    hash_one(opts.upstream))
                set_config('branch.%s.remote' % opts.branch_name, '.')
                set_config('branch.%s.merge' % opts.branch_name, opts.upstream)
            else:
                # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
                # teleport to a conflicting portion of history?
                run('checkout', '--track', opts.upstream, '-b',
                    opts.branch_name)
        get_or_create_merge_base(opts.branch_name)
    except subprocess2.CalledProcessError as cpe:
        sys.stdout.write(cpe.stdout)
        sys.stderr.write(cpe.stderr)
        return 1
    sys.stderr.write('Switched to branch %s.\n' % opts.branch_name)
    return 0
def find_return_branch():
    """Finds the branch which we should return to after rebase-update completes.

  This value may persist across multiple invocations of rebase-update, if
  rebase-update runs into a conflict mid-way.
  """
    return_branch = git.config(STARTING_BRANCH_KEY)
    if not return_branch:
        return_branch = git.current_branch()
        if return_branch != 'HEAD':
            git.set_config(STARTING_BRANCH_KEY, return_branch)

    return return_branch
Example #4
0
def find_return_branch():
  """Finds the branch which we should return to after rebase-update completes.

  This value may persist across multiple invocations of rebase-update, if
  rebase-update runs into a conflict mid-way.
  """
  return_branch = git.config(STARTING_BRANCH_KEY)
  if not return_branch:
    return_branch = git.current_branch()
    if return_branch != 'HEAD':
      git.set_config(STARTING_BRANCH_KEY, return_branch)

  return return_branch
def main(args):
  parser = argparse.ArgumentParser(
    formatter_class=argparse.ArgumentDefaultsHelpFormatter,
    description=__doc__,
  )
  parser.add_argument('branch_name')
  g = parser.add_mutually_exclusive_group()
  g.add_argument('--upstream-current', '--upstream_current',
                 action='store_true',
                 help='set upstream branch to current branch.')
  g.add_argument('--upstream', metavar='REF', default=root(),
                 help='upstream branch (or tag) to track.')
  g.add_argument('--inject-current', '--inject_current',
                 action='store_true',
                 help='new branch adopts current branch\'s upstream,' +
                 ' and new branch becomes current branch\'s upstream.')
  g.add_argument('--lkgr', action='store_const', const='lkgr', dest='upstream',
                 help='set basis ref for new branch to lkgr.')

  opts = parser.parse_args(args)

  try:
    if opts.inject_current:
      below = current_branch()
      if below is None:
        raise Exception('no current branch')
      above = upstream(below)
      if above is None:
        raise Exception('branch %s has no upstream' % (below))
      run('checkout', '--track', above, '-b', opts.branch_name)
      run('branch', '--set-upstream-to', opts.branch_name, below)
    elif opts.upstream_current:
      run('checkout', '--track', '-b', opts.branch_name)
    else:
      if opts.upstream in tags():
        # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
        run('checkout', '--no-track', '-b', opts.branch_name,
            hash_one(opts.upstream))
        set_config('branch.%s.remote' % opts.branch_name, '.')
        set_config('branch.%s.merge' % opts.branch_name, opts.upstream)
      else:
        # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
        # teleport to a conflicting portion of history?
        run('checkout', '--track', opts.upstream, '-b', opts.branch_name)
    get_or_create_merge_base(opts.branch_name)
  except subprocess2.CalledProcessError as cpe:
    sys.stdout.write(cpe.stdout)
    sys.stderr.write(cpe.stderr)
    return 1
  sys.stderr.write('Switched to branch %s.\n' % opts.branch_name)
  return 0
def find_return_branch_workdir():
  """Finds the branch and working directory which we should return to after
  rebase-update completes.

  These values may persist across multiple invocations of rebase-update, if
  rebase-update runs into a conflict mid-way.
  """
  return_branch = git.config(STARTING_BRANCH_KEY)
  workdir = git.config(STARTING_WORKDIR_KEY)
  if not return_branch:
    workdir = os.getcwd()
    git.set_config(STARTING_WORKDIR_KEY, workdir)
    return_branch = git.current_branch()
    if return_branch != 'HEAD':
      git.set_config(STARTING_BRANCH_KEY, return_branch)

  return return_branch, workdir
def find_return_branch_workdir():
    """Finds the branch and working directory which we should return to after
  rebase-update completes.

  These values may persist across multiple invocations of rebase-update, if
  rebase-update runs into a conflict mid-way.
  """
    return_branch = git.config(STARTING_BRANCH_KEY)
    workdir = git.config(STARTING_WORKDIR_KEY)
    if not return_branch:
        workdir = os.getcwd()
        git.set_config(STARTING_WORKDIR_KEY, workdir)
        return_branch = git.current_branch()
        if return_branch != 'HEAD':
            git.set_config(STARTING_BRANCH_KEY, return_branch)

    return return_branch, workdir
Example #8
0
def main(args):
    parser = argparse.ArgumentParser(
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('branch_name')
    g = parser.add_mutually_exclusive_group()
    g.add_argument('--upstream_current',
                   action='store_true',
                   help='set upstream branch to current branch.')
    g.add_argument('--upstream',
                   metavar='REF',
                   default=root(),
                   help='upstream branch (or tag) to track.')
    g.add_argument('--lkgr',
                   action='store_const',
                   const='lkgr',
                   dest='upstream',
                   help='set basis ref for new branch to lkgr.')

    opts = parser.parse_args(args)

    try:
        if opts.upstream_current:
            run('checkout', '--track', '-b', opts.branch_name)
        else:
            if opts.upstream in tags():
                # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
                run('checkout', '--no-track', '-b', opts.branch_name,
                    hash_one(opts.upstream))
                set_config('branch.%s.remote' % opts.branch_name, '.')
                set_config('branch.%s.merge' % opts.branch_name, opts.upstream)
            else:
                # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
                # teleport to a conflicting portion of history?
                run('checkout', '--track', opts.upstream, '-b',
                    opts.branch_name)

        get_or_create_merge_base(opts.branch_name)
    except subprocess2.CalledProcessError as cpe:
        sys.stdout.write(cpe.stdout)
        sys.stderr.write(cpe.stderr)
        return 1
Example #9
0
def main(argv):
  # No command line flags. Just use the parser to prevent people from trying
  # to pass flags that don't do anything, and to provide 'usage'.
  parser = argparse.ArgumentParser(
      description='Automatically set up git-svn for a repo mirrored from svn.')
  parser.parse_args(argv[1:])

  upstream = root()
  message = run_git('log', '-1', '--format=%B', upstream)
  footers = parse_footers(message)
  git_svn_id = get_unique(footers, 'git-svn-id')
  match = GIT_SVN_ID_PATTERN.match(git_svn_id)
  assert match, 'No valid git-svn-id footer found on %s.' % upstream
  print 'Found git-svn-id footer %s on %s' % (match.group(1), upstream)

  parsed_svn = urlparse.urlparse(match.group(1))
  path_components = parsed_svn.path.split('/')
  svn_repo = None
  svn_path = None
  for i in xrange(len(path_components)):
    try:
      maybe_repo = '%s://%s%s' % (
          parsed_svn.scheme, parsed_svn.netloc, '/'.join(path_components[:i+1]))
      print 'Checking ', maybe_repo
      run_svn('info', maybe_repo)
      svn_repo = maybe_repo
      svn_path = '/'.join(path_components[i+1:])
      break
    except subprocess2.CalledProcessError:
      continue
  assert svn_repo is not None, 'Unable to find svn repo for %s' % match.group(1)
  print 'Found upstream svn repo %s and path %s' % (svn_repo, svn_path)

  prefix = upstream.rsplit('/')[0]
  run_git('svn', 'init', '--prefix=%s' % prefix, '-T', svn_path, svn_repo)
  set_config('svn-remote.svn.fetch',
             '%s:refs/remotes/%s' % (svn_path, upstream))
  print 'Configured metadata, running "git svn fetch". This may take some time.'
  for line in run_git_stream('svn', 'fetch').xreadlines():
    print line.strip()
Example #10
0
def create_new_branch(branch_name,
                      upstream_current=False,
                      upstream=None,
                      inject_current=False):
    upstream = upstream or git_common.root()
    try:
        if inject_current:
            below = git_common.current_branch()
            if below is None:
                raise Exception('no current branch')
            above = git_common.upstream(below)
            if above is None:
                raise Exception('branch %s has no upstream' % (below))
            git_common.run('checkout', '--track', above, '-b', branch_name)
            git_common.run('branch', '--set-upstream-to', branch_name, below)
        elif upstream_current:
            git_common.run('checkout', '--track', '-b', branch_name)
        else:
            if upstream in git_common.tags():
                # TODO(iannucci): ensure that basis_ref is an ancestor of HEAD?
                git_common.run('checkout', '--no-track', '-b', branch_name,
                               git_common.hash_one(upstream))
                git_common.set_config('branch.%s.remote' % branch_name, '.')
                git_common.set_config('branch.%s.merge' % branch_name,
                                      upstream)
            else:
                # TODO(iannucci): Detect unclean workdir then stash+pop if we need to
                # teleport to a conflicting portion of history?
                git_common.run('checkout', '--track', upstream, '-b',
                               branch_name)
        git_common.get_or_create_merge_base(branch_name)
    except subprocess2.CalledProcessError as cpe:
        sys.stdout.write(cpe.stdout.decode('utf-8', 'replace'))
        sys.stderr.write(cpe.stderr.decode('utf-8', 'replace'))
        return 1
    sys.stderr.write('Switched to branch %s.\n' % branch_name)
    return 0
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
def main(args=None):
    parser = argparse.ArgumentParser()
    parser.add_argument('--verbose', '-v', action='store_true')
    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
    # 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
                break

    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
Example #13
0
      run_svn('info', maybe_repo)
      svn_repo = maybe_repo
      svn_path = '/'.join(path_components[i+1:])
      break
    except subprocess2.CalledProcessError, e:
      if 'E170001' in str(e):
        print 'Authentication failed:'
        print e
        print ('Try running "svn ls %s" with the password'
               ' from https://chromium-access.appspot.com' % maybe_repo)
        print
      continue
  assert svn_repo is not None, 'Unable to find svn repo for %s' % svn_id
  print 'Found upstream svn repo %s and path %s' % (svn_repo, svn_path)

  set_config('svn-remote.svn.url', svn_repo)
  set_config('svn-remote.svn.fetch',
             '%s:refs/remotes/%s' % (svn_path, upstream))
  print 'Configured metadata, running "git svn fetch". This may take some time.'
  with run_git_stream_with_retcode('svn', 'fetch') as stdout:
    for line in stdout.xreadlines():
      print line.strip()
  return 0


if __name__ == '__main__':
  try:
    sys.exit(main(sys.argv[1:]))
  except KeyboardInterrupt:
    sys.stderr.write('interrupted\n')
    sys.exit(1)
Example #14
0
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.')
  parser.add_argument(
      '--current', action='store_true', help='Only rebase the current branch.')
  parser.add_argument('branches', nargs='*',
                      help='Branches to be rebased. All branches are assumed '
                           'if none specified.')
  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.

  branches_to_rebase = set(opts.branches)
  if opts.current:
    branches_to_rebase.add(git.current_branch())

  skipped, branch_tree = git.get_branch_tree()
  if branches_to_rebase:
    skipped = set(skipped).intersection(branches_to_rebase)
  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.items():
    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):
    # Only rebase specified branches, unless none specified.
    if branches_to_rebase and branch not in branches_to_rebase:
      continue
    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("%s was merged with its parent, checking out %s instead." %
              (git.unicode_repr(return_branch), git.unicode_repr(root_branch)))
      git.run('checkout', root_branch)

    # return_workdir may also not be there any more.
    if return_workdir:
      try:
        os.chdir(return_workdir)
      except OSError as e:
        print(
            "Unable to return to original workdir %r: %s" % (return_workdir, e))
    git.set_config(STARTING_BRANCH_KEY, '')
    git.set_config(STARTING_WORKDIR_KEY, '')

  return retcode
Example #15
0
            maybe_repo = '%s://%s%s' % (parsed_svn.scheme, parsed_svn.netloc,
                                        '/'.join(path_components[:i + 1]))
            print 'Checking ', maybe_repo
            run_svn('info', maybe_repo)
            svn_repo = maybe_repo
            svn_path = '/'.join(path_components[i + 1:])
            break
        except subprocess2.CalledProcessError, e:
            if 'E170001' in str(e):
                print 'Authentication failed:'
                print e
                print(
                    'Try running "svn ls %s" with the password'
                    ' from https://chromium-access.appspot.com' % maybe_repo)
                print
            continue
    assert svn_repo is not None, 'Unable to find svn repo for %s' % match.group(
        1)
    print 'Found upstream svn repo %s and path %s' % (svn_repo, svn_path)

    set_config('svn-remote.svn.url', svn_repo)
    set_config('svn-remote.svn.fetch',
               '%s:refs/remotes/%s' % (svn_path, upstream))
    print 'Configured metadata, running "git svn fetch". This may take some time.'
    for line in run_git_stream('svn', 'fetch').xreadlines():
        print line.strip()


if __name__ == '__main__':
    sys.exit(main(sys.argv))