]> git.ipfire.org Git - thirdparty/git.git/commitdiff
Merge branch 'ab/refspec-init-fix'
authorJunio C Hamano <gitster@pobox.com>
Thu, 28 Jun 2018 19:53:29 +0000 (12:53 -0700)
committerJunio C Hamano <gitster@pobox.com>
Thu, 28 Jun 2018 19:53:29 +0000 (12:53 -0700)
Make refspec parsing codepath more robust.

* ab/refspec-init-fix:
  refspec: initalize `refspec_item` in `valid_fetch_refspec()`
  refspec: add back a refspec_item_init() function
  refspec: s/refspec_item_init/&_or_die/g

1  2 
builtin/clone.c
builtin/pull.c
refspec.c

diff --combined builtin/clone.c
index 99e73dae8595d37f704d0fe7f7fd84a190edfcf6,05cd23097378db16e4273679e867d051b2b8c63a..74a804f2e814b726c95e8f572f91eba581c6ca4b
@@@ -824,7 -824,7 +824,7 @@@ static void write_refspec_config(const 
                        } else if (remote_head_points_at) {
                                const char *head = remote_head_points_at->name;
                                if (!skip_prefix(head, "refs/heads/", &head))
 -                                      die("BUG: remote HEAD points at non-head?");
 +                                      BUG("remote HEAD points at non-head?");
  
                                strbuf_addf(&value, "+%s:%s%s", remote_head_points_at->name,
                                                branch_top->buf, head);
@@@ -1077,7 -1077,7 +1077,7 @@@ int cmd_clone(int argc, const char **ar
        if (option_required_reference.nr || option_optional_reference.nr)
                setup_reference();
  
-       refspec_item_init(&refspec, value.buf, REFSPEC_FETCH);
+       refspec_item_init_or_die(&refspec, value.buf, REFSPEC_FETCH);
  
        strbuf_reset(&value);
  
diff --combined builtin/pull.c
index 49cc3beb4c428a4bd0513d922b59465ab0c5c414,af9306ecdc1616d3cae19825b1ba6f4c8ef8ccf2..fe002a72f8ac7f1020a951769641f5f4b39f23b3
@@@ -28,16 -28,14 +28,16 @@@ enum rebase_type 
        REBASE_FALSE = 0,
        REBASE_TRUE,
        REBASE_PRESERVE,
 +      REBASE_MERGES,
        REBASE_INTERACTIVE
  };
  
  /**
   * Parses the value of --rebase. If value is a false value, returns
   * REBASE_FALSE. If value is a true value, returns REBASE_TRUE. If value is
 - * "preserve", returns REBASE_PRESERVE. If value is a invalid value, dies with
 - * a fatal error if fatal is true, otherwise returns REBASE_INVALID.
 + * "merges", returns REBASE_MERGES. If value is "preserve", returns
 + * REBASE_PRESERVE. If value is a invalid value, dies with a fatal error if
 + * fatal is true, otherwise returns REBASE_INVALID.
   */
  static enum rebase_type parse_config_rebase(const char *key, const char *value,
                int fatal)
@@@ -50,8 -48,6 +50,8 @@@
                return REBASE_TRUE;
        else if (!strcmp(value, "preserve"))
                return REBASE_PRESERVE;
 +      else if (!strcmp(value, "merges"))
 +              return REBASE_MERGES;
        else if (!strcmp(value, "interactive"))
                return REBASE_INTERACTIVE;
  
@@@ -135,7 -131,7 +135,7 @@@ static struct option pull_options[] = 
        /* Options passed to git-merge or git-rebase */
        OPT_GROUP(N_("Options related to merging")),
        { OPTION_CALLBACK, 'r', "rebase", &opt_rebase,
 -        "false|true|preserve|interactive",
 +        "false|true|merges|preserve|interactive",
          N_("incorporate changes by rebasing rather than merging"),
          PARSE_OPT_OPTARG, parse_opt_rebase },
        OPT_PASSTHRU('n', NULL, &opt_diffstat, NULL,
@@@ -544,7 -540,7 +544,7 @@@ static int run_fetch(const char *repo, 
                argv_array_push(&args, repo);
                argv_array_pushv(&args, refspecs);
        } else if (*refspecs)
 -              die("BUG: refspecs without repo?");
 +              BUG("refspecs without repo?");
        ret = run_command_v_opt(args.argv, RUN_GIT_CMD);
        argv_array_clear(&args);
        return ret;
@@@ -673,7 -669,7 +673,7 @@@ static const char *get_upstream_branch(
  }
  
  /**
 - * Derives the remote tracking branch from the remote and refspec.
 + * Derives the remote-tracking branch from the remote and refspec.
   *
   * FIXME: The current implementation assumes the default mapping of
   * refs/heads/<branch_name> to refs/remotes/<remote_name>/<branch_name>.
@@@ -684,7 -680,7 +684,7 @@@ static const char *get_tracking_branch(
        const char *spec_src;
        const char *merge_branch;
  
-       refspec_item_init(&spec, refspec, REFSPEC_FETCH);
+       refspec_item_init_or_die(&spec, refspec, REFSPEC_FETCH);
        spec_src = spec.src;
        if (!*spec_src || !strcmp(spec_src, "HEAD"))
                spec_src = "HEAD";
  
  /**
   * Given the repo and refspecs, sets fork_point to the point at which the
 - * current branch forked from its remote tracking branch. Returns 0 on success,
 + * current branch forked from its remote-tracking branch. Returns 0 on success,
   * -1 on failure.
   */
  static int get_rebase_fork_point(struct object_id *fork_point, const char *repo,
@@@ -805,9 -801,7 +805,9 @@@ static int run_rebase(const struct obje
        argv_push_verbosity(&args);
  
        /* Options passed to git-rebase */
 -      if (opt_rebase == REBASE_PRESERVE)
 +      if (opt_rebase == REBASE_MERGES)
 +              argv_array_push(&args, "--rebase-merges");
 +      else if (opt_rebase == REBASE_PRESERVE)
                argv_array_push(&args, "--preserve-merges");
        else if (opt_rebase == REBASE_INTERACTIVE)
                argv_array_push(&args, "--interactive");
diff --combined refspec.c
index 78edc48ae8eebcfdbfd87172e7ef4ead6c3fff85,e4c9e86bb60bc381d5ee03fd61bb9ed6d1ad55c9..e8010dce0ce27472c2b3269e13b9c1de6a69f3cc
+++ b/refspec.c
@@@ -49,8 -49,6 +49,8 @@@ static int parse_refspec(struct refspec
                size_t rlen = strlen(++rhs);
                is_glob = (1 <= rlen && strchr(rhs, '*'));
                item->dst = xstrndup(rhs, rlen);
 +      } else {
 +              item->dst = NULL;
        }
  
        llen = (rhs ? (rhs - lhs - 1) : strlen(lhs));
        return 1;
  }
  
void refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
int refspec_item_init(struct refspec_item *item, const char *refspec, int fetch)
  {
        memset(item, 0, sizeof(*item));
+       return parse_refspec(item, refspec, fetch);
+ }
  
-       if (!parse_refspec(item, refspec, fetch))
+ void refspec_item_init_or_die(struct refspec_item *item, const char *refspec,
+                             int fetch)
+ {
+       if (!refspec_item_init(item, refspec, fetch))
                die("Invalid refspec '%s'", refspec);
  }
  
@@@ -152,7 -155,7 +157,7 @@@ void refspec_append(struct refspec *rs
  {
        struct refspec_item item;
  
-       refspec_item_init(&item, refspec, rs->fetch);
+       refspec_item_init_or_die(&item, refspec, rs->fetch);
  
        ALLOC_GROW(rs->items, rs->nr + 1, rs->alloc);
        rs->items[rs->nr++] = item;
@@@ -191,7 -194,7 +196,7 @@@ void refspec_clear(struct refspec *rs
  int valid_fetch_refspec(const char *fetch_refspec_str)
  {
        struct refspec_item refspec;
-       int ret = parse_refspec(&refspec, fetch_refspec_str, REFSPEC_FETCH);
+       int ret = refspec_item_init(&refspec, fetch_refspec_str, REFSPEC_FETCH);
        refspec_item_clear(&refspec);
        return ret;
  }