def fetch_remotes(branch_tree):
    """Fetches all remotes which are needed to update |branch_tree|."""
    fetch_tags = False
    remotes = set()
    tag_set = git.tags()
    fetchspec_map = {}
    all_fetchspec_configs = git.get_config_regexp(r'^remote\..*\.fetch')
    for fetchspec_config in all_fetchspec_configs:
        key, _, fetchspec = fetchspec_config.partition(' ')
        dest_spec = fetchspec.partition(':')[2]
        remote_name = key.split('.')[1]
        fetchspec_map[dest_spec] = remote_name
    for parent in branch_tree.itervalues():
        if parent in tag_set:
            fetch_tags = True
        else:
            full_ref = git.run('rev-parse', '--symbolic-full-name', parent)
            for dest_spec, remote_name in fetchspec_map.iteritems():
                if fnmatch(full_ref, dest_spec):
                    remotes.add(remote_name)
                    break

    fetch_args = []
    if fetch_tags:
        # Need to fetch all because we don't know what remote the tag comes from :(
        # TODO(iannucci): assert that the tags are in the remote fetch refspec
        fetch_args = ['--all']
    else:
        fetch_args.append('--multiple')
        fetch_args.extend(remotes)
    # TODO(iannucci): Should we fetch git-svn?

    if not fetch_args:  # pragma: no cover
        print('Nothing to fetch.')
    else:
        git.run_with_stderr('fetch',
                            *fetch_args,
                            stdout=sys.stdout,
                            stderr=sys.stderr)
def fetch_remotes(branch_tree):
  """Fetches all remotes which are needed to update |branch_tree|."""
  fetch_tags = False
  remotes = set()
  tag_set = git.tags()
  fetchspec_map = {}
  all_fetchspec_configs = git.get_config_regexp(r'^remote\..*\.fetch')
  for fetchspec_config in all_fetchspec_configs:
    key, _, fetchspec = fetchspec_config.partition(' ')
    dest_spec = fetchspec.partition(':')[2]
    remote_name = key.split('.')[1]
    fetchspec_map[dest_spec] = remote_name
  for parent in branch_tree.itervalues():
    if parent in tag_set:
      fetch_tags = True
    else:
      full_ref = git.run('rev-parse', '--symbolic-full-name', parent)
      for dest_spec, remote_name in fetchspec_map.iteritems():
        if fnmatch(full_ref, dest_spec):
          remotes.add(remote_name)
          break

  fetch_args = []
  if fetch_tags:
    # Need to fetch all because we don't know what remote the tag comes from :(
    # TODO(iannucci): assert that the tags are in the remote fetch refspec
    fetch_args = ['--all']
  else:
    fetch_args.append('--multiple')
    fetch_args.extend(remotes)
  # TODO(iannucci): Should we fetch git-svn?

  if not fetch_args:  # pragma: no cover
    print 'Nothing to fetch.'
  else:
    git.run_with_stderr('fetch', *fetch_args, stdout=sys.stdout,
                        stderr=sys.stderr)