Merge branch 'cb/match_refs_internal_tail'
authorJunio C Hamano <gitster@pobox.com>
Sat, 13 Jun 2009 19:47:52 +0000 (12:47 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 13 Jun 2009 19:47:52 +0000 (12:47 -0700)
* cb/match_refs_internal_tail:
match_refs: search ref list tail internally

1  2 
builtin-remote.c
builtin-send-pack.c
http-push.c
remote.c
transport.c
diff --combined builtin-remote.c
index d7ab6b2d5ff872c7872648bae4c97d7e1aa3ebba,9248e0aac79462261ba3cf2b21342c93c38fc1eb..dfc0b9e706507fc557cc2b593632fda4683387bc
@@@ -79,8 -79,7 +79,8 @@@ static int add(int argc, const char **a
                OPT_END()
        };
  
 -      argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
 +      argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 +                           0);
  
        if (argc < 2)
                usage_with_options(builtin_remote_usage, options);
@@@ -295,17 -294,14 +295,14 @@@ static int get_push_ref_states(const st
        struct ref_states *states)
  {
        struct remote *remote = states->remote;
-       struct ref *ref, *local_refs, *push_map, **push_tail;
+       struct ref *ref, *local_refs, *push_map;
        if (remote->mirror)
                return 0;
  
        local_refs = get_local_heads();
        push_map = copy_ref_list(remote_refs);
  
-       push_tail = &push_map;
-       while (*push_tail)
-               push_tail = &((*push_tail)->next);
-       match_refs(local_refs, push_map, &push_tail, remote->push_refspec_nr,
+       match_refs(local_refs, &push_map, remote->push_refspec_nr,
                   remote->push_refspec, MATCH_REFS_NONE);
  
        states->push.strdup_strings = 1;
@@@ -987,8 -983,7 +984,8 @@@ static int show(int argc, const char **
        struct string_list info_list = { NULL, 0, 0, 0 };
        struct show_info info;
  
 -      argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
 +      argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 +                           0);
  
        if (argc < 1)
                return show_all();
  
                get_remote_ref_states(*argv, &states, query_flag);
  
 -              printf("* remote %s\n  URL: %s\n", *argv,
 -                      states.remote->url_nr > 0 ?
 -                              states.remote->url[0] : "(no URL)");
 +              printf("* remote %s\n", *argv);
 +              if (states.remote->url_nr) {
 +                      for (i=0; i < states.remote->url_nr; i++)
 +                              printf("  URL: %s\n", states.remote->url[i]);
 +              } else
 +                      printf("  URL: %s\n", "(no URL)");
                if (no_query)
                        printf("  HEAD branch: (not queried)\n");
                else if (!states.heads.nr)
@@@ -1081,8 -1073,7 +1078,8 @@@ static int set_head(int argc, const cha
                            "delete refs/remotes/<name>/HEAD"),
                OPT_END()
        };
 -      argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
 +      argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 +                           0);
        if (argc)
                strbuf_addf(&buf, "refs/remotes/%s/HEAD", argv[0]);
  
@@@ -1136,8 -1127,7 +1133,8 @@@ static int prune(int argc, const char *
                OPT_END()
        };
  
 -      argc = parse_options(argc, argv, options, builtin_remote_usage, 0);
 +      argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
 +                           0);
  
        if (argc < 1)
                usage_with_options(builtin_remote_usage, options);
@@@ -1227,7 -1217,7 +1224,7 @@@ static int update(int argc, const char 
                OPT_END()
        };
  
 -      argc = parse_options(argc, argv, options, builtin_remote_usage,
 +      argc = parse_options(argc, argv, NULL, options, builtin_remote_usage,
                             PARSE_OPT_KEEP_ARGV0);
        if (argc < 2) {
                argc = 2;
@@@ -1313,7 -1303,7 +1310,7 @@@ int cmd_remote(int argc, const char **a
        };
        int result;
  
 -      argc = parse_options(argc, argv, options, builtin_remote_usage,
 +      argc = parse_options(argc, argv, prefix, options, builtin_remote_usage,
                PARSE_OPT_STOP_AT_NON_OPTION);
  
        if (argc < 1)
diff --combined builtin-send-pack.c
index be3b0926deeb38f34b75c08bedf29fd80bac9b3c,0b3d00bfb914f9eadfa0b2613aaf6f08a577f1cc..c375a3dbde0a75af592c8881965f255f66b599d1
@@@ -178,9 -178,9 +178,9 @@@ static void print_ref_status(char flag
  {
        fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
        if (from)
 -              fprintf(stderr, "%s -> %s", prettify_ref(from), prettify_ref(to));
 +              fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
        else
 -              fputs(prettify_ref(to), stderr);
 +              fputs(prettify_refname(to->name), stderr);
        if (msg) {
                fputs(" (", stderr);
                fputs(msg, stderr);
@@@ -473,7 -473,7 +473,7 @@@ int cmd_send_pack(int argc, const char 
        int fd[2];
        struct child_process *conn;
        struct extra_have_objects extra_have;
-       struct ref *remote_refs, **remote_tail, *local_refs;
+       struct ref *remote_refs, *local_refs;
        int ret;
        int send_all = 0;
        const char *receivepack = "git-receive-pack";
                flags |= MATCH_REFS_MIRROR;
  
        /* match them up */
-       remote_tail = &remote_refs;
-       while (*remote_tail)
-               remote_tail = &((*remote_tail)->next);
-       if (match_refs(local_refs, remote_refs, &remote_tail,
-                      nr_refspecs, refspecs, flags)) {
+       if (match_refs(local_refs, &remote_refs, nr_refspecs, refspecs, flags))
                return -1;
-       }
  
        ret = send_pack(&args, fd, conn, remote_refs, &extra_have);
  
diff --combined http-push.c
index 43e2dda2e147d47461d52bbd8f66cce8e2739773,35b3856a473d8c69d31b8885cab902ed787674e9..a7e28e345fb303534c4b99189096424bd7d9e887
@@@ -1844,7 -1844,7 +1844,7 @@@ static int update_remote(unsigned char 
        return 1;
  }
  
- static struct ref *remote_refs, **remote_tail;
+ static struct ref *remote_refs;
  
  static void one_remote_ref(char *refname)
  {
                }
        }
  
-       *remote_tail = ref;
-       remote_tail = &ref->next;
+       ref->next = remote_refs;
+       remote_refs = ref;
  }
  
  static void get_dav_remote_heads(void)
  {
-       remote_tail = &remote_refs;
        remote_ls("refs/", (PROCESS_FILES | PROCESS_DIRS | RECURSIVE), process_ls_ref, NULL);
  }
  
 -static int is_zero_sha1(const unsigned char *sha1)
 -{
 -      int i;
 -
 -      for (i = 0; i < 20; i++) {
 -              if (*sha1++)
 -                      return 0;
 -      }
 -      return 1;
 -}
 -
  static void add_remote_info_ref(struct remote_ls_ctx *ls)
  {
        struct strbuf *buf = (struct strbuf *)ls->userData;
@@@ -2109,13 -2119,13 +2108,13 @@@ static int delete_remote_branch(char *p
                /* Remote HEAD must resolve to a known object */
                if (symref)
                        return error("Remote HEAD symrefs too deep");
 -              if (is_zero_sha1(head_sha1))
 +              if (is_null_sha1(head_sha1))
                        return error("Unable to resolve remote HEAD");
                if (!has_sha1_file(head_sha1))
                        return error("Remote HEAD resolves to object %s\nwhich does not exist locally, perhaps you need to fetch?", sha1_to_hex(head_sha1));
  
                /* Remote branch must resolve to a known object */
 -              if (is_zero_sha1(remote_ref->old_sha1))
 +              if (is_null_sha1(remote_ref->old_sha1))
                        return error("Unable to resolve remote branch %s",
                                     remote_ref->name);
                if (!has_sha1_file(remote_ref->old_sha1))
@@@ -2300,9 -2310,7 +2299,7 @@@ int main(int argc, char **argv
        }
  
        /* match them up */
-       if (!remote_tail)
-               remote_tail = &remote_refs;
-       if (match_refs(local_refs, remote_refs, &remote_tail,
+       if (match_refs(local_refs, &remote_refs,
                       nr_refspec, (const char **) refspec, push_all)) {
                rc = -1;
                goto cleanup;
        new_refs = 0;
        for (ref = remote_refs; ref; ref = ref->next) {
                char old_hex[60], *new_hex;
 -              const char *commit_argv[4];
 +              const char *commit_argv[5];
                int commit_argc;
                char *new_sha1_hex, *old_sha1_hex;
  
                if (!ref->peer_ref)
                        continue;
  
 -              if (is_zero_sha1(ref->peer_ref->new_sha1)) {
 +              if (is_null_sha1(ref->peer_ref->new_sha1)) {
                        if (delete_remote_branch(ref->name, 1) == -1) {
                                error("Could not remove %s", ref->name);
                                rc = -4;
                }
  
                if (!force_all &&
 -                  !is_zero_sha1(ref->old_sha1) &&
 +                  !is_null_sha1(ref->old_sha1) &&
                    !ref->force) {
                        if (!has_sha1_file(ref->old_sha1) ||
                            !ref_newer(ref->peer_ref->new_sha1,
                old_sha1_hex = NULL;
                commit_argv[1] = "--objects";
                commit_argv[2] = new_sha1_hex;
 -              if (!push_all && !is_zero_sha1(ref->old_sha1)) {
 +              if (!push_all && !is_null_sha1(ref->old_sha1)) {
                        old_sha1_hex = xmalloc(42);
                        sprintf(old_sha1_hex, "^%s",
                                sha1_to_hex(ref->old_sha1));
                        commit_argv[3] = old_sha1_hex;
                        commit_argc++;
                }
 +              commit_argv[commit_argc] = NULL;
                init_revisions(&revs, setup_git_directory());
                setup_revisions(commit_argc, commit_argv, &revs, NULL);
                revs.edge_hint = 0; /* just in case */
diff --combined remote.c
index 2c3e9053a492e0029eb1f98a8d2c649564888197,9feb8f4f13791ae0711968ef038f079b159cd528..08a59644c03b9c61bfad8383e521ac813e0c4f05
+++ b/remote.c
@@@ -1085,12 -1085,20 +1085,20 @@@ static const struct refspec *check_patt
                return NULL;
  }
  
+ static struct ref **tail_ref(struct ref **head)
+ {
+       struct ref **tail = head;
+       while (*tail)
+               tail = &((*tail)->next);
+       return tail;
+ }
  /*
   * Note. This is used only by "push"; refspec matching rules for
   * push and fetch are subtly different, so do not try to reuse it
   * without thinking.
   */
- int match_refs(struct ref *src, struct ref *dst, struct ref ***dst_tail,
+ int match_refs(struct ref *src, struct ref **dst,
               int nr_refspec, const char **refspec, int flags)
  {
        struct refspec *rs;
        int send_mirror = flags & MATCH_REFS_MIRROR;
        int errs;
        static const char *default_refspec[] = { ":", 0 };
+       struct ref **dst_tail = tail_ref(dst);
  
        if (!nr_refspec) {
                nr_refspec = 1;
                refspec = default_refspec;
        }
        rs = parse_push_refspec(nr_refspec, (const char **) refspec);
-       errs = match_explicit_refs(src, dst, dst_tail, rs, nr_refspec);
+       errs = match_explicit_refs(src, *dst, &dst_tail, rs, nr_refspec);
  
        /* pick the remainder */
        for ( ; src; src = src->next) {
                                                     dst_side, &dst_name))
                                die("Didn't think it matches any more");
                }
-               dst_peer = find_ref_by_name(dst, dst_name);
+               dst_peer = find_ref_by_name(*dst, dst_name);
                if (dst_peer) {
                        if (dst_peer->peer_ref)
                                /* We're already sending something to this ref. */
                                goto free_name;
  
                        /* Create a new one and link it */
-                       dst_peer = make_linked_ref(dst_name, dst_tail);
+                       dst_peer = make_linked_ref(dst_name, &dst_tail);
                        hashcpy(dst_peer->new_sha1, src->new_sha1);
                }
                dst_peer->peer_ref = copy_ref(src);
@@@ -1399,13 -1408,13 +1408,13 @@@ int stat_tracking_info(struct branch *b
        base = branch->merge[0]->dst;
        if (!resolve_ref(base, sha1, 1, NULL))
                return 0;
 -      theirs = lookup_commit(sha1);
 +      theirs = lookup_commit_reference(sha1);
        if (!theirs)
                return 0;
  
        if (!resolve_ref(branch->refname, sha1, 1, NULL))
                return 0;
 -      ours = lookup_commit(sha1);
 +      ours = lookup_commit_reference(sha1);
        if (!ours)
                return 0;
  
diff --combined transport.c
index 17891d5149aab99ce0ec5538a0e11b8e9c2398ec,2f5786d38b8d95078530749182b905e137299ff7..d8a2392a655dc67948581b4bd94e14536972377b
@@@ -732,9 -732,9 +732,9 @@@ static void print_ref_status(char flag
  {
        fprintf(stderr, " %c %-*s ", flag, SUMMARY_WIDTH, summary);
        if (from)
 -              fprintf(stderr, "%s -> %s", prettify_ref(from), prettify_ref(to));
 +              fprintf(stderr, "%s -> %s", prettify_refname(from->name), prettify_refname(to->name));
        else
 -              fputs(prettify_ref(to), stderr);
 +              fputs(prettify_refname(to->name), stderr);
        if (msg) {
                fputs(" (", stderr);
                fputs(msg, stderr);
@@@ -1003,7 -1003,6 +1003,6 @@@ int transport_push(struct transport *tr
        if (transport->push_refs) {
                struct ref *remote_refs =
                        transport->get_refs_list(transport, 1);
-               struct ref **remote_tail;
                struct ref *local_refs = get_local_heads();
                int match_flags = MATCH_REFS_NONE;
                int verbose = flags & TRANSPORT_PUSH_VERBOSE;
                if (flags & TRANSPORT_PUSH_MIRROR)
                        match_flags |= MATCH_REFS_MIRROR;
  
-               remote_tail = &remote_refs;
-               while (*remote_tail)
-                       remote_tail = &((*remote_tail)->next);
-               if (match_refs(local_refs, remote_refs, &remote_tail,
+               if (match_refs(local_refs, &remote_refs,
                               refspec_nr, refspec, match_flags)) {
                        return -1;
                }
@@@ -1083,51 -1079,3 +1079,51 @@@ int transport_disconnect(struct transpo
        free(transport);
        return ret;
  }
 +
 +/*
 + * Strip username (and password) from an url and return
 + * it in a newly allocated string.
 + */
 +char *transport_anonymize_url(const char *url)
 +{
 +      char *anon_url, *scheme_prefix, *anon_part;
 +      size_t anon_len, prefix_len = 0;
 +
 +      anon_part = strchr(url, '@');
 +      if (is_local(url) || !anon_part)
 +              goto literal_copy;
 +
 +      anon_len = strlen(++anon_part);
 +      scheme_prefix = strstr(url, "://");
 +      if (!scheme_prefix) {
 +              if (!strchr(anon_part, ':'))
 +                      /* cannot be "me@there:/path/name" */
 +                      goto literal_copy;
 +      } else {
 +              const char *cp;
 +              /* make sure scheme is reasonable */
 +              for (cp = url; cp < scheme_prefix; cp++) {
 +                      switch (*cp) {
 +                              /* RFC 1738 2.1 */
 +                      case '+': case '.': case '-':
 +                              break; /* ok */
 +                      default:
 +                              if (isalnum(*cp))
 +                                      break;
 +                              /* it isn't */
 +                              goto literal_copy;
 +                      }
 +              }
 +              /* @ past the first slash does not count */
 +              cp = strchr(scheme_prefix + 3, '/');
 +              if (cp && cp < anon_part)
 +                      goto literal_copy;
 +              prefix_len = scheme_prefix - url + 3;
 +      }
 +      anon_url = xcalloc(1, 1 + prefix_len + anon_len);
 +      memcpy(anon_url, url, prefix_len);
 +      memcpy(anon_url + prefix_len, anon_part, anon_len);
 +      return anon_url;
 +literal_copy:
 +      return xstrdup(url);
 +}