From: Junio C Hamano <gitster@pobox.com>
Date: Mon, 9 Sep 2013 21:50:42 +0000 (-0700)
Subject: Merge branch 'nd/magic-pathspec'
X-Git-Tag: v1.8.5-rc0~158
X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/fadf96abaa5f42c4bb7b4b5017926779c23d8ef3?hp=-c

Merge branch 'nd/magic-pathspec'

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
---

fadf96abaa5f42c4bb7b4b5017926779c23d8ef3
diff --combined builtin/add.c
index ae0bdc78bb,b4035f6468..31ddabd994
--- a/builtin/add.c
+++ b/builtin/add.c
@@@ -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 62a96a7e2f,b235e04558..0f57397037
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@@ -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))
@@@ -102,7 -102,7 +102,7 @@@
  	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)) {
@@@ -116,7 -116,7 +116,7 @@@
  		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;
  
@@@ -314,14 -316,14 +314,14 @@@
  
  	/* 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 {
@@@ -345,9 -347,9 +345,9 @@@
  				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")),
@@@ -1059,15 -1061,16 +1059,15 @@@
  		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(),
  	};
  
@@@ -1146,13 -1149,6 +1146,6 @@@
  	}
  
  	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 4b32cc32cb,62fde5060f..ad1a9f5b28
--- a/pathspec.c
+++ b/pathspec.c
@@@ -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 04b632fa33,04b632fa33..944baeb622
--- a/pathspec.h
+++ b/pathspec.h
@@@ -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() */