Merge branch 'maint'
authorJunio C Hamano <gitster@pobox.com>
Fri, 22 Jan 2010 04:08:31 +0000 (20:08 -0800)
committerJunio C Hamano <gitster@pobox.com>
Fri, 22 Jan 2010 04:08:31 +0000 (20:08 -0800)
* maint:
merge-recursive: do not return NULL only to cause segfault
retry request without query when info/refs?query fails

1  2 
merge-recursive.c
remote-curl.c
diff --combined merge-recursive.c
index 1239647fc0bcda68e744f5f3040c99314c8b8714,22a31ed5ff5d1affd54da43769a3982ba2ec1b75..cb53b01c19159e66ef265bde7feceabebab42232
  #include "merge-recursive.h"
  #include "dir.h"
  
 -static struct tree *shift_tree_object(struct tree *one, struct tree *two)
 +static struct tree *shift_tree_object(struct tree *one, struct tree *two,
 +                                    const char *subtree_shift)
  {
        unsigned char shifted[20];
  
 -      /*
 -       * NEEDSWORK: this limits the recursion depth to hardcoded
 -       * value '2' to avoid excessive overhead.
 -       */
 -      shift_tree(one->object.sha1, two->object.sha1, shifted, 2);
 +      if (!*subtree_shift) {
 +              shift_tree(one->object.sha1, two->object.sha1, shifted, 0);
 +      } else {
 +              shift_tree_by(one->object.sha1, two->object.sha1, shifted,
 +                            subtree_shift);
 +      }
        if (!hashcmp(two->object.sha1, shifted))
                return two;
        return lookup_tree(shifted);
@@@ -202,14 -200,14 +202,14 @@@ struct tree *write_tree_from_memory(str
  
        if (unmerged_cache()) {
                int i;
-               output(o, 0, "There are unmerged index entries:");
+               fprintf(stderr, "BUG: There are unmerged index entries:\n");
                for (i = 0; i < active_nr; i++) {
                        struct cache_entry *ce = active_cache[i];
                        if (ce_stage(ce))
-                               output(o, 0, "%d %.*s", ce_stage(ce),
-                                      (int)ce_namelen(ce), ce->name);
+                               fprintf(stderr, "BUG: %d %.*s", ce_stage(ce),
+                                       (int)ce_namelen(ce), ce->name);
                }
-               return NULL;
+               die("Bug in merge-recursive.c");
        }
  
        if (!active_cache_tree)
@@@ -627,23 -625,6 +627,23 @@@ static int merge_3way(struct merge_opti
        mmfile_t orig, src1, src2;
        char *name1, *name2;
        int merge_status;
 +      int favor;
 +
 +      if (o->call_depth)
 +              favor = 0;
 +      else {
 +              switch (o->recursive_variant) {
 +              case MERGE_RECURSIVE_OURS:
 +                      favor = XDL_MERGE_FAVOR_OURS;
 +                      break;
 +              case MERGE_RECURSIVE_THEIRS:
 +                      favor = XDL_MERGE_FAVOR_THEIRS;
 +                      break;
 +              default:
 +                      favor = 0;
 +                      break;
 +              }
 +      }
  
        if (strcmp(a->path, b->path)) {
                name1 = xstrdup(mkpath("%s:%s", branch1, a->path));
  
        merge_status = ll_merge(result_buf, a->path, &orig,
                                &src1, name1, &src2, name2,
 -                              o->call_depth);
 +                              (!!o->call_depth) | (favor << 1));
  
        free(name1);
        free(name2);
@@@ -1220,9 -1201,9 +1220,9 @@@ int merge_trees(struct merge_options *o
  {
        int code, clean;
  
 -      if (o->subtree_merge) {
 -              merge = shift_tree_object(head, merge);
 -              common = shift_tree_object(head, common);
 +      if (o->subtree_shift) {
 +              merge = shift_tree_object(head, merge, o->subtree_shift);
 +              common = shift_tree_object(head, common, o->subtree_shift);
        }
  
        if (sha_eq(common->object.sha1, merge->object.sha1)) {
diff --combined remote-curl.c
index 136100695994049f2e9d6357cb25dd5a9d73ae28,3edbf5717c94f3123a97939acf265cc8334ca899..a904164e425097380781c1ecd9bb13f4feec0de6
@@@ -102,7 -102,7 +102,7 @@@ static struct discovery* discover_refs(
        struct strbuf buffer = STRBUF_INIT;
        struct discovery *last = last_discovery;
        char *refs_url;
-       int http_ret, is_http = 0;
+       int http_ret, is_http = 0, proto_git_candidate = 1;
  
        if (last && !strcmp(service, last->service))
                return last;
  
        init_walker();
        http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
+       /* try again with "plain" url (no ? or & appended) */
+       if (http_ret != HTTP_OK) {
+               free(refs_url);
+               strbuf_reset(&buffer);
+               proto_git_candidate = 0;
+               strbuf_addf(&buffer, "%s/info/refs", url);
+               refs_url = strbuf_detach(&buffer, NULL);
+               http_ret = http_get_strbuf(refs_url, &buffer, HTTP_NO_CACHE);
+       }
        switch (http_ret) {
        case HTTP_OK:
                break;
        last->buf_alloc = strbuf_detach(&buffer, &last->len);
        last->buf = last->buf_alloc;
  
-       if (is_http && 5 <= last->len && last->buf[4] == '#') {
+       if (is_http && proto_git_candidate
+               && 5 <= last->len && last->buf[4] == '#') {
                /* smart HTTP response; validate that the service
                 * pkt-line matches our request.
                 */
@@@ -290,7 -304,6 +304,7 @@@ struct rpc_state 
        int out;
        struct strbuf result;
        unsigned gzip_request : 1;
 +      unsigned initial_buffer : 1;
  };
  
  static size_t rpc_out(void *ptr, size_t eltsize,
        size_t avail = rpc->len - rpc->pos;
  
        if (!avail) {
 +              rpc->initial_buffer = 0;
                avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc);
                if (!avail)
                        return 0;
        return avail;
  }
  
 +#ifndef NO_CURL_IOCTL
 +static curlioerr rpc_ioctl(CURL *handle, int cmd, void *clientp)
 +{
 +      struct rpc_state *rpc = clientp;
 +
 +      switch (cmd) {
 +      case CURLIOCMD_NOP:
 +              return CURLIOE_OK;
 +
 +      case CURLIOCMD_RESTARTREAD:
 +              if (rpc->initial_buffer) {
 +                      rpc->pos = 0;
 +                      return CURLIOE_OK;
 +              }
 +              fprintf(stderr, "Unable to rewind rpc post data - try increasing http.postBuffer\n");
 +              return CURLIOE_FAILRESTART;
 +
 +      default:
 +              return CURLIOE_UNKNOWNCMD;
 +      }
 +}
 +#endif
 +
  static size_t rpc_in(const void *ptr, size_t eltsize,
                size_t nmemb, void *buffer_)
  {
@@@ -395,13 -384,8 +409,13 @@@ static int post_rpc(struct rpc_state *r
                 */
                headers = curl_slist_append(headers, "Expect: 100-continue");
                headers = curl_slist_append(headers, "Transfer-Encoding: chunked");
 +              rpc->initial_buffer = 1;
                curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, rpc_out);
                curl_easy_setopt(slot->curl, CURLOPT_INFILE, rpc);
 +#ifndef NO_CURL_IOCTL
 +              curl_easy_setopt(slot->curl, CURLOPT_IOCTLFUNCTION, rpc_ioctl);
 +              curl_easy_setopt(slot->curl, CURLOPT_IOCTLDATA, rpc);
 +#endif
                if (options.verbosity > 1) {
                        fprintf(stderr, "POST %s (chunked)\n", rpc->service_name);
                        fflush(stderr);