Merge branch 'nd/magic-pathspec'
authorJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2013 21:50:42 +0000 (14:50 -0700)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2013 21:50:44 +0000 (14:50 -0700)
Use "struct pathspec" interface in more places, instead of array of
characters, the latter of which cannot express magic pathspecs
(e.g. ":(icase)makefile" that matches both Makefile and makefile).

* nd/magic-pathspec:
add: lift the pathspec magic restriction on "add -p"
pathspec: catch prepending :(prefix) on pathspec with short magic

1  2 
builtin/add.c
builtin/checkout.c
pathspec.c
pathspec.h
diff --combined builtin/add.c
index ae0bdc78bbf47094a2f0656ef8f3f561e60dc072,b4035f64689e0c9c9a8c2040aa53bbbe97dcaa40..31ddabd99472a099ccc34810a9821050883bc1fa
@@@ -270,13 -270,7 +270,7 @@@ int interactive_add(int argc, const cha
  {
        struct pathspec pathspec;
  
-       /*
-        * git-add--interactive itself does not parse pathspec. It
-        * simply passes the pathspec to other builtin commands. Let's
-        * hope all of them support all magic, or we'll need to limit
-        * the magic here.
-        */
-       parse_pathspec(&pathspec, PATHSPEC_ALL_MAGIC & ~PATHSPEC_FROMTOP,
+       parse_pathspec(&pathspec, 0,
                       PATHSPEC_PREFER_FULL |
                       PATHSPEC_SYMLINK_LEADING_PATH |
                       PATHSPEC_PREFIX_ORIGIN,
@@@ -309,7 -303,6 +303,7 @@@ static int edit_patch(int argc, const c
  
        argc = setup_revisions(argc, argv, &rev, NULL);
        rev.diffopt.output_format = DIFF_FORMAT_PATCH;
 +      rev.diffopt.use_color = 0;
        DIFF_OPT_SET(&rev.diffopt, IGNORE_DIRTY_SUBMODULES);
        out = open(file, O_CREAT | O_WRONLY, 0666);
        if (out < 0)
diff --combined builtin/checkout.c
index 62a96a7e2fb868ab93f83d7b8df5aecf20aad3d4,b235e0455892badb655499aae21e28b798bb9bb9..0f573970372664a16024e83ed9733c94eeee3b50
@@@ -94,7 -94,7 +94,7 @@@ static int read_tree_some(struct tree *
        return 0;
  }
  
 -static int skip_same_name(struct cache_entry *ce, int pos)
 +static int skip_same_name(const struct cache_entry *ce, int pos)
  {
        while (++pos < active_nr &&
               !strcmp(active_cache[pos]->name, ce->name))
        return pos;
  }
  
 -static int check_stage(int stage, struct cache_entry *ce, int pos)
 +static int check_stage(int stage, const struct cache_entry *ce, int pos)
  {
        while (pos < active_nr &&
               !strcmp(active_cache[pos]->name, ce->name)) {
                return error(_("path '%s' does not have their version"), ce->name);
  }
  
 -static int check_stages(unsigned stages, struct cache_entry *ce, int pos)
 +static int check_stages(unsigned stages, const struct cache_entry *ce, int pos)
  {
        unsigned seen = 0;
        const char *name = ce->name;
@@@ -225,6 -225,8 +225,6 @@@ static int checkout_paths(const struct 
        int flag;
        struct commit *head;
        int errs = 0;
 -      int stage = opts->writeout_stage;
 -      int merge = opts->merge;
        int newfd;
        struct lock_file *lock_file;
  
  
        /* Any unmerged paths? */
        for (pos = 0; pos < active_nr; pos++) {
 -              struct cache_entry *ce = active_cache[pos];
 +              const struct cache_entry *ce = active_cache[pos];
                if (ce->ce_flags & CE_MATCHED) {
                        if (!ce_stage(ce))
                                continue;
                        if (opts->force) {
                                warning(_("path '%s' is unmerged"), ce->name);
 -                      } else if (stage) {
 -                              errs |= check_stage(stage, ce, pos);
 +                      } else if (opts->writeout_stage) {
 +                              errs |= check_stage(opts->writeout_stage, ce, pos);
                        } else if (opts->merge) {
                                errs |= check_stages((1<<2) | (1<<3), ce, pos);
                        } else {
                                errs |= checkout_entry(ce, &state, NULL);
                                continue;
                        }
 -                      if (stage)
 -                              errs |= checkout_stage(stage, ce, pos, &state);
 -                      else if (merge)
 +                      if (opts->writeout_stage)
 +                              errs |= checkout_stage(opts->writeout_stage, ce, pos, &state);
 +                      else if (opts->merge)
                                errs |= checkout_merged(pos, &state);
                        pos = skip_same_name(ce, pos) - 1;
                }
@@@ -1049,8 -1051,8 +1049,8 @@@ int cmd_checkout(int argc, const char *
                           N_("create and checkout a new branch")),
                OPT_STRING('B', NULL, &opts.new_branch_force, N_("branch"),
                           N_("create/reset and checkout a branch")),
 -              OPT_BOOLEAN('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
 -              OPT_BOOLEAN(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
 +              OPT_BOOL('l', NULL, &opts.new_branch_log, N_("create reflog for new branch")),
 +              OPT_BOOL(0, "detach", &opts.force_detach, N_("detach the HEAD at named commit")),
                OPT_SET_INT('t', "track",  &opts.track, N_("set upstream info for new branch"),
                        BRANCH_TRACK_EXPLICIT),
                OPT_STRING(0, "orphan", &opts.new_orphan_branch, N_("new branch"), N_("new unparented branch")),
                OPT_SET_INT('3', "theirs", &opts.writeout_stage, N_("checkout their version for unmerged files"),
                            3),
                OPT__FORCE(&opts.force, N_("force checkout (throw away local modifications)")),
 -              OPT_BOOLEAN('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
 -              OPT_BOOLEAN(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
 +              OPT_BOOL('m', "merge", &opts.merge, N_("perform a 3-way merge with the new branch")),
 +              OPT_BOOL(0, "overwrite-ignore", &opts.overwrite_ignore, N_("update ignored files (default)")),
                OPT_STRING(0, "conflict", &conflict_style, N_("style"),
                           N_("conflict style (merge or diff3)")),
 -              OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
 +              OPT_BOOL('p', "patch", &opts.patch_mode, N_("select hunks interactively")),
                OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree,
                         N_("do not limit pathspecs to sparse entries only")),
 -              { OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL,
 -                N_("second guess 'git checkout no-such-branch'"),
 -                PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },
 +              OPT_HIDDEN_BOOL(0, "guess", &dwim_new_local_branch,
 +                              N_("second guess 'git checkout no-such-branch'")),
                OPT_END(),
        };
  
        }
  
        if (argc) {
-               /*
-                * In patch mode (opts.patch_mode != 0), we pass the
-                * pathspec to an external program, git-add--interactive.
-                * Do not accept any kind of magic that that program
-                * cannot handle. Magic mask is pretty safe to be
-                * lifted for new magic when opts.patch_mode == 0.
-                */
                parse_pathspec(&opts.pathspec, 0,
                               opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
                               prefix, argv);
diff --combined pathspec.c
index 4b32cc32cb5b0be495ac941c5e96d8aee8fd8ff9,62fde5060f064388387059d55e18f4ca5c36ad00..ad1a9f5b28c5119275fbcf9a53e62651190de137
@@@ -32,7 -32,7 +32,7 @@@ void add_pathspec_matches_against_index
        if (!num_unmatched)
                return;
        for (i = 0; i < active_nr; i++) {
 -              struct cache_entry *ce = active_cache[i];
 +              const struct cache_entry *ce = active_cache[i];
                match_pathspec_depth(pathspec, ce->name, ce_namelen(ce), 0, seen);
        }
  }
@@@ -231,7 -231,9 +231,9 @@@ static unsigned prefix_pathspec(struct 
                const char *start = elt;
                if (prefixlen && !literal_global) {
                        /* Preserve the actual prefix length of each pattern */
-                       if (long_magic_end) {
+                       if (short_magic)
+                               die("BUG: prefixing on short magic is not supported");
+                       else if (long_magic_end) {
                                strbuf_add(&sb, start, long_magic_end - start);
                                strbuf_addf(&sb, ",prefix:%d", prefixlen);
                                start = long_magic_end;
diff --combined pathspec.h
index 04b632fa3326defd3d119d88beadb296f8e4a722,04b632fa3326defd3d119d88beadb296f8e4a722..944baeb622cee4aeebb835d01982466cf2c2ce29
@@@ -14,7 -14,7 +14,7 @@@
         PATHSPEC_GLOB          | \
         PATHSPEC_ICASE)
  
--#define PATHSPEC_ONESTAR 1    /* the pathspec pattern sastisfies GFNM_ONESTAR */
++#define PATHSPEC_ONESTAR 1    /* the pathspec pattern satisfies GFNM_ONESTAR */
  
  struct pathspec {
        const char **_raw; /* get_pathspec() result, not freed by free_pathspec() */