git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH/WIP 00/10] Fancy pathspec stuff
@ 2013-01-13 12:49 Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
                   ` (9 more replies)
  0 siblings, 10 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

I wanted to see how new pathspec feature can be implemented after
nd/parse-pathspec, mainly to see if nd/parse-pathspec needs fixing.
It's nowhere near 'pu' quality but may be interesting for some people.

It does:

- introduce :q/.../ syntax in addition to :(...), which always
  requires quoting in bash

- separate prefix part from the rest of pathspec, allowing it to be
  treated differently (e.g. prefix is matched exactly regardless
  pathspec magic)

- implement :(glob) using wildmatch (i.e. incompatible with the
  wildcards that current pathspec uses)

- implement :(icase) -- with bugs

- implement :(literal), similar to --literal-pathspecs

That's all my spam for today.

Nguyễn Thái Ngọc Duy (10):
  pathspec: allow to use alternate char for quoting long magic mnemonic
  parse_pathspec: make sure the prefix part is wildcard-free
  pathspec: support :(literal) syntax for noglob pathspec
  parse_pathspec: save prefix information
  pathspec: prepare for :(glob)path syntax
  Enable :(glob)path syntax for a lot of commands
  parse_pathspec: accept :(icase)path syntax
  common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards
  pathspec: support icase in match_pathspec_depth and
    tree_entry_interesting
  Enable ls-files and ls-tree for testing PATHSPEC_ICASE

 archive.c                  |  4 ++-
 builtin/add.c              | 19 +++++++++++---
 builtin/checkout.c         |  6 ++++-
 builtin/clean.c            |  6 ++++-
 builtin/commit.c           | 10 +++++--
 builtin/diff.c             |  2 +-
 builtin/grep.c             |  6 ++++-
 builtin/ls-files.c         |  6 ++++-
 builtin/ls-tree.c          |  7 ++++-
 builtin/rerere.c           |  6 ++++-
 builtin/reset.c            |  6 ++++-
 builtin/rm.c               |  6 ++++-
 builtin/update-index.c     |  6 ++++-
 cache.h                    | 23 +++++++++++++++-
 dir.c                      | 60 ++++++++++++++++++++++++++++--------------
 dir.h                      |  8 +++---
 path.c                     | 15 ++++++++++-
 revision.c                 |  7 +++--
 setup.c                    | 65 +++++++++++++++++++++++++++++++++-------------
 t/t6130-pathspec-noglob.sh | 18 +++++++++++++
 t/t6131-pathspec-prefix.sh | 47 +++++++++++++++++++++++++++++++++
 tree-diff.c                |  2 +-
 tree-walk.c                | 39 +++++++++++++++++-----------
 23 files changed, 295 insertions(+), 79 deletions(-)
 create mode 100755 t/t6131-pathspec-prefix.sh

-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free Nguyễn Thái Ngọc Duy
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

Currently use parentheses, e.g. ":(icase,literal)path", but they do
not play well with unix shells because they have special meaning and
we need to quote them. Allow an alternate syntax ":q/icase,literal/path".

Similar to ed's s/// syntax, '/' can be replaced with anything. If the
opening quote has a closing counterpart, e.g. () [] <> {}, then it'll
be quoted as such.

It may even be a good thing to kill ':(...)' syntax, which can easily
be replaced with ':q(...)'. It's unlikely that anybody is used to it
yet.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 setup.c | 30 ++++++++++++++++++++++++------
 1 file changed, 24 insertions(+), 6 deletions(-)

diff --git a/setup.c b/setup.c
index 69ca047..9db6093 100644
--- a/setup.c
+++ b/setup.c
@@ -196,14 +196,32 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 
 	if (elt[0] != ':') {
 		; /* nothing to do */
-	} else if (elt[1] == '(') {
+	} else if (elt[1] == '(' || elt[1] == 'q') {
 		/* longhand */
 		const char *nextat;
-		for (copyfrom = elt + 2;
-		     *copyfrom && *copyfrom != ')';
+		char close = ')';
+		char sep[3] = ",)";
+		if (elt[1] == '(')
+			copyfrom = elt + 2;
+		else {
+			copyfrom = elt + 3;
+			switch (elt[2]) {
+			case '(': close = ')'; break;
+			case '[': close = ']'; break;
+			case '{': close = '}'; break;
+			case '<': close = '>'; break;
+			case '\0':
+				die("Invalid pathspec '%s'", elt);
+			default:
+				close = elt[2];
+			}
+			sep[1] = close;
+		}
+		for (;
+		     *copyfrom && *copyfrom != close;
 		     copyfrom = nextat) {
-			size_t len = strcspn(copyfrom, ",)");
-			if (copyfrom[len] == ')')
+			size_t len = strcspn(copyfrom, sep);
+			if (copyfrom[len] == close)
 				nextat = copyfrom + len;
 			else
 				nextat = copyfrom + len + 1;
@@ -219,7 +237,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 				die("Invalid pathspec magic '%.*s' in '%s'",
 				    (int) len, copyfrom, elt);
 		}
-		if (*copyfrom == ')')
+		if (*copyfrom == close)
 			copyfrom++;
 	} else {
 		/* shorthand */
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec Nguyễn Thái Ngọc Duy
                   ` (7 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h                    |  1 +
 path.c                     | 15 ++++++++++++++-
 setup.c                    | 24 +++++++++++++++--------
 t/t6131-pathspec-prefix.sh | 47 ++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 78 insertions(+), 9 deletions(-)
 create mode 100755 t/t6131-pathspec-prefix.sh

diff --git a/cache.h b/cache.h
index c7a8d28..f3de28d 100644
--- a/cache.h
+++ b/cache.h
@@ -747,6 +747,7 @@ const char *real_path(const char *path);
 const char *real_path_if_valid(const char *path);
 const char *absolute_path(const char *path);
 const char *relative_path(const char *abs, const char *base);
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len);
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, struct string_list *prefixes);
 char *strip_path_suffix(const char *path, const char *suffix);
diff --git a/path.c b/path.c
index d3d3f8b..7baf334 100644
--- a/path.c
+++ b/path.c
@@ -487,8 +487,14 @@ const char *relative_path(const char *abs, const char *base)
  *
  * Note that this function is purely textual.  It does not follow symlinks,
  * verify the existence of the path, or make any system calls.
+ *
+ * prefix_len != NULL is for a specific case of prefix_pathspec():
+ * assume that src == dst and src[0..prefix_len-1] is already
+ * normalized, any time "../" eats up to the prefix_len part,
+ * prefix_len is reduced. In the end prefix_len is the remaining
+ * prefix that has not been overridden by user pathspec.
  */
-int normalize_path_copy(char *dst, const char *src)
+int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
 {
 	char *dst0;
 
@@ -563,11 +569,18 @@ int normalize_path_copy(char *dst, const char *src)
 		/* Windows: dst[-1] cannot be backslash anymore */
 		while (dst0 < dst && dst[-1] != '/')
 			dst--;
+		if (prefix_len && *prefix_len > dst - dst0)
+			*prefix_len = dst - dst0;
 	}
 	*dst = '\0';
 	return 0;
 }
 
+int normalize_path_copy(char *dst, const char *src)
+{
+	return normalize_path_copy_len(dst, src, NULL);
+}
+
 /*
  * path = Canonical absolute path
  * prefixes = string_list containing normalized, absolute paths without
diff --git a/setup.c b/setup.c
index 9db6093..c5e97c9 100644
--- a/setup.c
+++ b/setup.c
@@ -5,10 +5,11 @@
 static int inside_git_dir = -1;
 static int inside_work_tree = -1;
 
-static char *prefix_path_gently(const char *prefix, int len, const char *path)
+static char *prefix_path_gently(const char *prefix, int *p_len, const char *path)
 {
 	const char *orig = path;
 	char *sanitized;
+	int len = *p_len;
 	if (is_absolute_path(orig)) {
 		const char *temp = real_path(path);
 		sanitized = xmalloc(len + strlen(temp) + 1);
@@ -19,7 +20,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
 			memcpy(sanitized, prefix, len);
 		strcpy(sanitized + len, path);
 	}
-	if (normalize_path_copy(sanitized, sanitized))
+	if (normalize_path_copy_len(sanitized, sanitized, p_len))
 		goto error_out;
 	if (is_absolute_path(orig)) {
 		size_t root_len, len, total;
@@ -44,7 +45,7 @@ static char *prefix_path_gently(const char *prefix, int len, const char *path)
 
 char *prefix_path(const char *prefix, int len, const char *path)
 {
-	char *r = prefix_path_gently(prefix, len, path);
+	char *r = prefix_path_gently(prefix, &len, path);
 	if (!r)
 		die("'%s' is outside repository", path);
 	return r;
@@ -53,7 +54,7 @@ char *prefix_path(const char *prefix, int len, const char *path)
 int path_inside_repo(const char *prefix, const char *path)
 {
 	int len = prefix ? strlen(prefix) : 0;
-	char *r = prefix_path_gently(prefix, len, path);
+	char *r = prefix_path_gently(prefix, &len, path);
 	if (r) {
 		free(r);
 		return 1;
@@ -261,10 +262,14 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 			copyfrom++;
 	}
 
-	if (magic & PATHSPEC_FROMTOP)
+	if (magic & PATHSPEC_FROMTOP) {
 		match = xstrdup(copyfrom);
-	else
-		match = prefix_path(prefix, prefixlen, copyfrom);
+		prefixlen = 0;
+	} else {
+		match = prefix_path_gently(prefix, &prefixlen, copyfrom);
+		if (!match)
+			die("%s: '%s' is outside repository", elt, copyfrom);
+	}
 	*raw = item->match = match;
 	item->original = elt;
 	item->len = strlen(item->match);
@@ -300,8 +305,11 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 	item->flags = 0;
 	if (limit_pathspec_to_literal())
 		item->nowildcard_len = item->len;
-	else
+	else {
 		item->nowildcard_len = simple_length(item->match);
+		if (item->nowildcard_len < prefixlen)
+			item->nowildcard_len = prefixlen;
+	}
 	if (item->nowildcard_len < item->len &&
 	    item->match[item->nowildcard_len] == '*' &&
 	    no_wildcard(item->match + item->nowildcard_len + 1))
diff --git a/t/t6131-pathspec-prefix.sh b/t/t6131-pathspec-prefix.sh
new file mode 100755
index 0000000..db59091
--- /dev/null
+++ b/t/t6131-pathspec-prefix.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+
+test_description='Verify the exact matching of prefix part in pathspec'
+
+. ./test-lib.sh
+
+test_expect_success 'setup' '
+	mkdir a\* ab &&
+	: >a\*/foo &&
+	: >ab/foo &&
+	git add .
+'
+
+test_expect_success 'prefix has wildcards but treated as literal' '
+	(
+		cd a\* &&
+		git ls-files --cached foo
+	) >actual &&
+	echo foo >expected &&
+	test_cmp expected actual
+'
+
+test_expect_success 'prefix is reduced to empty' '
+	(
+		cd a\* &&
+		git ls-files --cached ../a\*/foo
+	) >actual &&
+	cat <<\EOF >expected &&
+foo
+../ab/foo
+EOF
+	test_cmp expected actual
+'
+
+test_expect_success 'prefix is reduced to empty (2)' '
+	(
+		cd a\* &&
+		git ls-files --cached non-existing//../fancy/.//../../a\*/foo
+	) >actual &&
+	cat <<\EOF >expected &&
+foo
+../ab/foo
+EOF
+	test_cmp expected actual
+'
+
+test_done
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 04/10] parse_pathspec: save prefix information Nguyễn Thái Ngọc Duy
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 archive.c                  |  4 +++-
 builtin/add.c              |  8 +++++---
 builtin/checkout.c         |  4 +++-
 builtin/clean.c            |  4 +++-
 builtin/commit.c           |  6 ++++--
 builtin/diff.c             |  2 +-
 builtin/grep.c             |  4 +++-
 builtin/ls-files.c         |  3 ++-
 builtin/ls-tree.c          |  4 +++-
 builtin/rerere.c           |  4 +++-
 builtin/reset.c            |  4 +++-
 builtin/rm.c               |  4 +++-
 builtin/update-index.c     |  4 +++-
 cache.h                    |  1 +
 dir.c                      |  6 +++---
 revision.c                 |  5 +++--
 setup.c                    |  7 ++++---
 t/t6130-pathspec-noglob.sh | 18 ++++++++++++++++++
 tree-diff.c                |  2 +-
 tree-walk.c                |  2 +-
 20 files changed, 70 insertions(+), 26 deletions(-)

diff --git a/archive.c b/archive.c
index d9da58b..d3b6969 100644
--- a/archive.c
+++ b/archive.c
@@ -234,7 +234,9 @@ static void parse_pathspec_arg(const char **pathspec,
 	 * mark "used" pathspec. The magic mask cannot be lifted until
 	 * it does.
 	 */
-	parse_pathspec(&ar_args->pathspec, PATHSPEC_FROMTOP, 0, "", pathspec);
+	parse_pathspec(&ar_args->pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, "", pathspec);
 	if (ar_args->pathspec.nr) {
 		pathspec = ar_args->pathspec._raw;
 		while (*pathspec) {
diff --git a/builtin/add.c b/builtin/add.c
index a7840c8..d09a07a 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -202,7 +202,8 @@ int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 	 * Do not enable fancy magic here.  git-add--interactive may
 	 * not be able to handle it.
 	 */
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP,
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
 		       PATHSPEC_EMPTY_MATCH_ALL |
 		       PATHSPEC_SYMLINK_LEADING_PATH,
 		       prefix, argv);
@@ -377,7 +378,8 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	 * Check the "pathspec '%s' did not match any files" block
 	 * below before enabling new magic.
 	 */
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP,
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
 		       PATHSPEC_SYMLINK_LEADING_PATH |
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
 		       prefix, argv);
@@ -414,7 +416,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		/*
 		 * file_exists() assumes exact match
 		 */
-		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP);
+		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 
 		for (i = 0; i < pathspec.nr; i++) {
 			const char *path = pathspec.items[i].match;
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 1b413e2..90f4a01 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1112,7 +1112,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		 * cannot handle. Magic mask is pretty safe to be
 		 * lifted for new magic when opts.patch_mode == 0.
 		 */
-		parse_pathspec(&opts.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+		parse_pathspec(&opts.pathspec,
+			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       0, prefix, argv);
 
 		if (!opts.pathspec.nr)
 			die(_("invalid path specification"));
diff --git a/builtin/clean.c b/builtin/clean.c
index 1d8ff5f..b4ffa2b 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -100,7 +100,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 		add_exclude(exclude_list.items[i].string, "", 0,
 			    &dir.exclude_list[EXC_CMDL]);
 
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, argv);
 
 	fill_directory(&dir, &pathspec);
 
diff --git a/builtin/commit.c b/builtin/commit.c
index 2011f98..433fdb9 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -281,7 +281,8 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 
 	if (is_status)
 		refresh_flags |= REFRESH_UNMERGED;
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP,
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
 		       PATHSPEC_EMPTY_MATCH_ALL,
 		       prefix, argv);
 
@@ -1203,7 +1204,8 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	handle_untracked_files_arg(&s);
 	if (show_ignored_in_status)
 		s.show_ignored_files = 1;
-	parse_pathspec(&s.pathspec, PATHSPEC_FROMTOP,
+	parse_pathspec(&s.pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
 		       PATHSPEC_EMPTY_MATCH_ALL,
 		       prefix, argv);
 
diff --git a/builtin/diff.c b/builtin/diff.c
index 6b4e3f9..b78435f 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -372,7 +372,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix)
 	}
 	if (rev.prune_data.nr) {
 		/* builtin_diff_b_f() */
-		GUARD_PATHSPEC(&rev.prune_data, PATHSPEC_FROMTOP);
+		GUARD_PATHSPEC(&rev.prune_data, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 		if (!path)
 			path = rev.prune_data.items[0].match;
 		paths += rev.prune_data.nr;
diff --git a/builtin/grep.c b/builtin/grep.c
index f370bad..4d8e82c 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -856,7 +856,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 			verify_filename(prefix, argv[j], j == i);
 	}
 
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + i);
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, argv + i);
 	pathspec.max_depth = opt.max_depth;
 	pathspec.recursive = 1;
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index e3ccf50..1cbd211 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -535,7 +535,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	if (require_work_tree && !is_inside_work_tree())
 		setup_work_tree();
 
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP,
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
 		       prefix, argv);
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 58899a5..4764683 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -172,7 +172,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 	 * cannot be lifted until it is converted to use
 	 * match_pathspec_depth() or tree_entry_interesting()
 	 */
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, argv + 1);
 	for (i = 0; i < pathspec.nr; i++)
 		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
 	pathspec.has_wildcard = 0;
diff --git a/builtin/rerere.c b/builtin/rerere.c
index a573c4a..779fc77 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -71,7 +71,9 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 		struct pathspec pathspec;
 		if (argc < 2)
 			warning("'git rerere forget' without paths is deprecated");
-		parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv + 1);
+		parse_pathspec(&pathspec,
+			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       0, prefix, argv + 1);
 		return rerere_forget(&pathspec);
 	}
 
diff --git a/builtin/reset.c b/builtin/reset.c
index 0185bb0..69ce164 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -183,7 +183,9 @@ static int read_from_tree(const char *prefix, const char **argv,
 	struct diff_options opt;
 
 	memset(&opt, 0, sizeof(opt));
-	parse_pathspec(&opt.pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	parse_pathspec(&opt.pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, argv);
 	opt.output_format = DIFF_FORMAT_CALLBACK;
 	opt.format_callback = update_index_from_diff;
 	opt.format_callback_data = &index_was_discarded;
diff --git a/builtin/rm.c b/builtin/rm.c
index b2a99c2..d46f1aa 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -249,7 +249,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 		}
 	}
 
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, argv);
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, argv);
 	refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
 
 	seen = NULL;
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 6728e59..1dd6178 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -548,7 +548,9 @@ static int do_reupdate(int ac, const char **av,
 	int has_head = 1;
 	struct pathspec pathspec;
 
-	parse_pathspec(&pathspec, PATHSPEC_FROMTOP, 0, prefix, av + 1);
+	parse_pathspec(&pathspec,
+		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, av + 1);
 
 	if (read_ref("HEAD", head_sha1))
 		/* If there is no HEAD, that means it is an initial
diff --git a/cache.h b/cache.h
index f3de28d..900b81a 100644
--- a/cache.h
+++ b/cache.h
@@ -478,6 +478,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
 
 /* Pathspec magic */
 #define PATHSPEC_FROMTOP    (1<<0)
+#define PATHSPEC_LITERAL    (1<<1)
 
 #define PATHSPEC_ONESTAR 1	/* the pathspec pattern sastisfies GFNM_ONESTAR */
 
diff --git a/dir.c b/dir.c
index efc676c..63d07cd 100644
--- a/dir.c
+++ b/dir.c
@@ -64,7 +64,7 @@ static size_t common_prefix_len(const struct pathspec *pathspec)
 	int n;
 	size_t max = 0;
 
-	GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP);
+	GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 
 	for (n = 0; n < pathspec->nr; n++) {
 		size_t i = 0, len = 0;
@@ -181,7 +181,7 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
 	int i, retval = 0;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP);
+	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -1230,7 +1230,7 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
 	 * Check out create_simplify()
 	 */
 	if (pathspec)
-		GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP);
+		GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
diff --git a/revision.c b/revision.c
index 231f53b..079955f 100644
--- a/revision.c
+++ b/revision.c
@@ -1851,8 +1851,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 		 */
 		ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
 		prune_data.path[prune_data.nr++] = NULL;
-		parse_pathspec(&revs->prune_data, PATHSPEC_FROMTOP, 0,
-			       revs->prefix, prune_data.path);
+		parse_pathspec(&revs->prune_data,
+			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       0, revs->prefix, prune_data.path);
 	}
 
 	if (revs->def == NULL)
diff --git a/setup.c b/setup.c
index c5e97c9..6b48f1b 100644
--- a/setup.c
+++ b/setup.c
@@ -157,7 +157,6 @@ void verify_non_filename(const char *prefix, const char *arg)
  *
  * Possible future magic semantics include stuff like:
  *
- *	{ PATHSPEC_NOGLOB, '!', "noglob" },
  *	{ PATHSPEC_ICASE, '\0', "icase" },
  *	{ PATHSPEC_RECURSIVE, '*', "recursive" },
  *	{ PATHSPEC_REGEXP, '\0', "regexp" },
@@ -170,6 +169,7 @@ static struct pathspec_magic {
 	const char *name;
 } pathspec_magic[] = {
 	{ PATHSPEC_FROMTOP, '/', "top" },
+	{ PATHSPEC_LITERAL,   0, "literal" },
 };
 
 /*
@@ -303,7 +303,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 		}
 
 	item->flags = 0;
-	if (limit_pathspec_to_literal())
+	if (limit_pathspec_to_literal() || (magic & PATHSPEC_LITERAL))
 		item->nowildcard_len = item->len;
 	else {
 		item->nowildcard_len = simple_length(item->match);
@@ -397,7 +397,8 @@ void parse_pathspec(struct pathspec *pathspec,
 const char **get_pathspec(const char *prefix, const char **pathspec)
 {
 	struct pathspec ps;
-	parse_pathspec(&ps, PATHSPEC_FROMTOP, 0, prefix, pathspec);
+	parse_pathspec(&ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       0, prefix, pathspec);
 	return ps._raw;
 }
 
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index 39ef619..49c148e 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -47,18 +47,36 @@ test_expect_success 'no-glob option matches literally (vanilla)' '
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (vanilla)' '
+	echo vanilla >expect &&
+	git log --format=%s -- ":(literal)foo" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob option matches literally (star)' '
 	echo star >expect &&
 	git --literal-pathspecs log --format=%s -- "f*" >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (star)' '
+	echo star >expect &&
+	git log --format=%s -- ":(literal)f*" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob option matches literally (bracket)' '
 	echo bracket >expect &&
 	git --literal-pathspecs log --format=%s -- "f[o][o]" >actual &&
 	test_cmp expect actual
 '
 
+test_expect_success 'no-glob option matches literally (bracket)' '
+	echo bracket >expect &&
+	git log --format=%s -- ":(literal)f[o][o]" >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success 'no-glob environment variable works' '
 	echo star >expect &&
 	GIT_LITERAL_PATHSPECS=1 git log --format=%s -- "f*" >actual &&
diff --git a/tree-diff.c b/tree-diff.c
index 718f938..0e2e138 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -203,7 +203,7 @@ static void try_to_follow_renames(struct tree_desc *t1, struct tree_desc *t2, co
 	 * path. Magic that matches more than one path is not
 	 * supported.
 	 */
-	GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP);
+	GUARD_PATHSPEC(&opt->pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 #if 0
 	/*
 	 * We should reject wildcards as well. Unfortunately we
diff --git a/tree-walk.c b/tree-walk.c
index dd03750..d4ed51f 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -635,7 +635,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP);
+	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 04/10] parse_pathspec: save prefix information
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (2 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax Nguyễn Thái Ngọc Duy
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h | 2 +-
 setup.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/cache.h b/cache.h
index 900b81a..fb54876 100644
--- a/cache.h
+++ b/cache.h
@@ -493,7 +493,7 @@ struct pathspec {
 		const char *match;
 		const char *original;
 		unsigned magic;
-		int len;
+		int len, prefix;
 		int nowildcard_len;
 		int flags;
 	} *items;
diff --git a/setup.c b/setup.c
index 6b48f1b..c4af05e 100644
--- a/setup.c
+++ b/setup.c
@@ -310,6 +310,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 		if (item->nowildcard_len < prefixlen)
 			item->nowildcard_len = prefixlen;
 	}
+	item->prefix = prefixlen;
 	if (item->nowildcard_len < item->len &&
 	    item->match[item->nowildcard_len] == '*' &&
 	    no_wildcard(item->match + item->nowildcard_len + 1))
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (3 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 04/10] parse_pathspec: save prefix information Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands Nguyễn Thái Ngọc Duy
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy

:(glob)path differs from path that it uses wildmatch with
FNM_PATHNAME while plain "path" uses fnmatch without FNM_PATHNAME.

git_fnmatch() was probably ill-designed. It was intended to cover
other use of fnmatch besides pathspec. But so far it's only used by
pathspec code.

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c |  9 +++++++--
 cache.h       |  1 +
 dir.c         | 34 ++++++++++++++++++++++------------
 dir.h         |  8 +++-----
 setup.c       |  1 +
 tree-walk.c   | 11 ++++++-----
 6 files changed, 40 insertions(+), 24 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index d09a07a..1b99e2b 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -416,11 +416,16 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		/*
 		 * file_exists() assumes exact match
 		 */
-		GUARD_PATHSPEC(&pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+		GUARD_PATHSPEC(&pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB);
 
 		for (i = 0; i < pathspec.nr; i++) {
 			const char *path = pathspec.items[i].match;
-			if (!seen[i] && !file_exists(path)) {
+			if (!seen[i] &&
+			    ((pathspec.items[i].magic & PATHSPEC_GLOB) ||
+			     !file_exists(path))) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
 					if (is_path_excluded(&check, path, -1, &dtype))
diff --git a/cache.h b/cache.h
index fb54876..9c27f18 100644
--- a/cache.h
+++ b/cache.h
@@ -479,6 +479,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
 /* Pathspec magic */
 #define PATHSPEC_FROMTOP    (1<<0)
 #define PATHSPEC_LITERAL    (1<<1)
+#define PATHSPEC_GLOB       (1<<2)
 
 #define PATHSPEC_ONESTAR 1	/* the pathspec pattern sastisfies GFNM_ONESTAR */
 
diff --git a/dir.c b/dir.c
index 63d07cd..760b776 100644
--- a/dir.c
+++ b/dir.c
@@ -37,26 +37,28 @@ int fnmatch_icase(const char *pattern, const char *string, int flags)
 	return fnmatch(pattern, string, flags | (ignore_case ? FNM_CASEFOLD : 0));
 }
 
-inline int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix)
+inline int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix)
 {
-	int fnm_flags = 0;
-	if (flags & GFNM_PATHNAME)
-		fnm_flags |= FNM_PATHNAME;
 	if (prefix > 0) {
 		if (strncmp(pattern, string, prefix))
 			return FNM_NOMATCH;
 		pattern += prefix;
 		string += prefix;
 	}
-	if (flags & GFNM_ONESTAR) {
+	if (item->flags & PATHSPEC_ONESTAR) {
 		int pattern_len = strlen(++pattern);
 		int string_len = strlen(string);
 		return string_len < pattern_len ||
 		       strcmp(pattern,
 			      string + string_len - pattern_len);
 	}
-	return fnmatch(pattern, string, fnm_flags);
+	if (item->magic & PATHSPEC_GLOB)
+		return wildmatch(pattern, string, 0);
+	else
+		/* wildmatch has not learned no FNM_PATHNAME mode yet */
+		return fnmatch(pattern, string, 0);
 }
 
 static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -64,7 +66,10 @@ static size_t common_prefix_len(const struct pathspec *pathspec)
 	int n;
 	size_t max = 0;
 
-	GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(pathspec,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	for (n = 0; n < pathspec->nr; n++) {
 		size_t i = 0, len = 0;
@@ -159,8 +164,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
 	}
 
 	if (item->nowildcard_len < item->len &&
-	    !git_fnmatch(match, name,
-			 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+	    !git_fnmatch(item, match, name,
 			 item->nowildcard_len - prefix))
 		return MATCHED_FNMATCH;
 
@@ -181,7 +185,10 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
 	int i, retval = 0;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -1230,7 +1237,10 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
 	 * Check out create_simplify()
 	 */
 	if (pathspec)
-		GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+		GUARD_PATHSPEC(pathspec,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB);
 
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
diff --git a/dir.h b/dir.h
index a03af80..b6da4b7 100644
--- a/dir.h
+++ b/dir.h
@@ -168,10 +168,8 @@ extern int fnmatch_icase(const char *pattern, const char *string, int flags);
 /*
  * The prefix part of pattern must not contains wildcards.
  */
-#define GFNM_PATHNAME 1		/* similar to FNM_PATHNAME */
-#define GFNM_ONESTAR  2		/* there is only _one_ wildcard, a star */
-
-extern int git_fnmatch(const char *pattern, const char *string,
-		       int flags, int prefix);
+extern int git_fnmatch(const struct pathspec_item *item,
+		       const char *pattern, const char *string,
+		       int prefix);
 
 #endif
diff --git a/setup.c b/setup.c
index c4af05e..b3e146d 100644
--- a/setup.c
+++ b/setup.c
@@ -170,6 +170,7 @@ static struct pathspec_magic {
 } pathspec_magic[] = {
 	{ PATHSPEC_FROMTOP, '/', "top" },
 	{ PATHSPEC_LITERAL,   0, "literal" },
+	{ PATHSPEC_GLOB,   '\0', "glob" },
 };
 
 /*
diff --git a/tree-walk.c b/tree-walk.c
index d4ed51f..1679ce7 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -635,7 +635,10 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
-	GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_LITERAL);
+	GUARD_PATHSPEC(ps,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -677,8 +680,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 				return entry_interesting;
 
 			if (item->nowildcard_len < item->len) {
-				if (!git_fnmatch(match + baselen, entry->path,
-						 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+				if (!git_fnmatch(item, match + baselen, entry->path,
 						 item->nowildcard_len - baselen))
 					return entry_interesting;
 
@@ -719,8 +721,7 @@ match_wildcards:
 
 		strbuf_add(base, entry->path, pathlen);
 
-		if (!git_fnmatch(match, base->buf + base_offset,
-				 item->flags & PATHSPEC_ONESTAR ? GFNM_ONESTAR : 0,
+		if (!git_fnmatch(item, match, base->buf + base_offset,
 				 item->nowildcard_len)) {
 			strbuf_setlen(base, base_offset + baselen);
 			return entry_interesting;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (4 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax Nguyễn Thái Ngọc Duy
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c          | 4 +++-
 builtin/checkout.c     | 4 +++-
 builtin/clean.c        | 4 +++-
 builtin/commit.c       | 8 ++++++--
 builtin/grep.c         | 4 +++-
 builtin/ls-files.c     | 4 +++-
 builtin/ls-tree.c      | 4 +++-
 builtin/rerere.c       | 4 +++-
 builtin/reset.c        | 4 +++-
 builtin/rm.c           | 4 +++-
 builtin/update-index.c | 4 +++-
 revision.c             | 4 +++-
 12 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 1b99e2b..a3ffa9d 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -379,7 +379,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 	 * below before enabling new magic.
 	 */
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       PATHSPEC_SYMLINK_LEADING_PATH |
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
 		       prefix, argv);
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 90f4a01..cb5d548 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -1113,7 +1113,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix)
 		 * lifted for new magic when opts.patch_mode == 0.
 		 */
 		parse_pathspec(&opts.pathspec,
-			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       (opts.patch_mode ? PATHSPEC_GLOB : 0),
 			       0, prefix, argv);
 
 		if (!opts.pathspec.nr)
diff --git a/builtin/clean.c b/builtin/clean.c
index b4ffa2b..f675d5a 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -101,7 +101,9 @@ int cmd_clean(int argc, const char **argv, const char *prefix)
 			    &dir.exclude_list[EXC_CMDL]);
 
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, argv);
 
 	fill_directory(&dir, &pathspec);
diff --git a/builtin/commit.c b/builtin/commit.c
index 433fdb9..743a3ea 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -282,7 +282,9 @@ static char *prepare_index(int argc, const char **argv, const char *prefix,
 	if (is_status)
 		refresh_flags |= REFRESH_UNMERGED;
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       PATHSPEC_EMPTY_MATCH_ALL,
 		       prefix, argv);
 
@@ -1205,7 +1207,9 @@ int cmd_status(int argc, const char **argv, const char *prefix)
 	if (show_ignored_in_status)
 		s.show_ignored_files = 1;
 	parse_pathspec(&s.pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       PATHSPEC_EMPTY_MATCH_ALL,
 		       prefix, argv);
 
diff --git a/builtin/grep.c b/builtin/grep.c
index 4d8e82c..9f1b029 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -857,7 +857,9 @@ int cmd_grep(int argc, const char **argv, const char *prefix)
 	}
 
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, argv + i);
 	pathspec.max_depth = opt.max_depth;
 	pathspec.recursive = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 1cbd211..feb4220 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -536,7 +536,9 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 		setup_work_tree();
 
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
 		       prefix, argv);
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 4764683..25d0590 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -173,7 +173,9 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 	 * match_pathspec_depth() or tree_entry_interesting()
 	 */
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, argv + 1);
 	for (i = 0; i < pathspec.nr; i++)
 		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
diff --git a/builtin/rerere.c b/builtin/rerere.c
index 779fc77..d64d010 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -72,7 +72,9 @@ int cmd_rerere(int argc, const char **argv, const char *prefix)
 		if (argc < 2)
 			warning("'git rerere forget' without paths is deprecated");
 		parse_pathspec(&pathspec,
-			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB,
 			       0, prefix, argv + 1);
 		return rerere_forget(&pathspec);
 	}
diff --git a/builtin/reset.c b/builtin/reset.c
index 69ce164..f71af9c 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -184,7 +184,9 @@ static int read_from_tree(const char *prefix, const char **argv,
 
 	memset(&opt, 0, sizeof(opt));
 	parse_pathspec(&opt.pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, argv);
 	opt.output_format = DIFF_FORMAT_CALLBACK;
 	opt.format_callback = update_index_from_diff;
diff --git a/builtin/rm.c b/builtin/rm.c
index d46f1aa..ff0fd5b 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -250,7 +250,9 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
 	}
 
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, argv);
 	refresh_index(&the_index, REFRESH_QUIET, &pathspec, NULL, NULL);
 
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 1dd6178..c456e1b 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -549,7 +549,9 @@ static int do_reupdate(int ac, const char **av,
 	struct pathspec pathspec;
 
 	parse_pathspec(&pathspec,
-		       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+		       PATHSPEC_FROMTOP |
+		       PATHSPEC_LITERAL |
+		       PATHSPEC_GLOB,
 		       0, prefix, av + 1);
 
 	if (read_ref("HEAD", head_sha1))
diff --git a/revision.c b/revision.c
index 079955f..5ac480b 100644
--- a/revision.c
+++ b/revision.c
@@ -1852,7 +1852,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s
 		ALLOC_GROW(prune_data.path, prune_data.nr+1, prune_data.alloc);
 		prune_data.path[prune_data.nr++] = NULL;
 		parse_pathspec(&revs->prune_data,
-			       PATHSPEC_FROMTOP | PATHSPEC_LITERAL,
+			       PATHSPEC_FROMTOP |
+			       PATHSPEC_LITERAL |
+			       PATHSPEC_GLOB,
 			       0, revs->prefix, prune_data.path);
 	}
 
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (5 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards Nguyễn Thái Ngọc Duy
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h | 1 +
 setup.c | 2 +-
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/cache.h b/cache.h
index 9c27f18..c3b5585 100644
--- a/cache.h
+++ b/cache.h
@@ -480,6 +480,7 @@ extern int ie_modified(const struct index_state *, struct cache_entry *, struct
 #define PATHSPEC_FROMTOP    (1<<0)
 #define PATHSPEC_LITERAL    (1<<1)
 #define PATHSPEC_GLOB       (1<<2)
+#define PATHSPEC_ICASE      (1<<3)
 
 #define PATHSPEC_ONESTAR 1	/* the pathspec pattern sastisfies GFNM_ONESTAR */
 
diff --git a/setup.c b/setup.c
index b3e146d..e22abf1 100644
--- a/setup.c
+++ b/setup.c
@@ -157,7 +157,6 @@ void verify_non_filename(const char *prefix, const char *arg)
  *
  * Possible future magic semantics include stuff like:
  *
- *	{ PATHSPEC_ICASE, '\0', "icase" },
  *	{ PATHSPEC_RECURSIVE, '*', "recursive" },
  *	{ PATHSPEC_REGEXP, '\0', "regexp" },
  *
@@ -171,6 +170,7 @@ static struct pathspec_magic {
 	{ PATHSPEC_FROMTOP, '/', "top" },
 	{ PATHSPEC_LITERAL,   0, "literal" },
 	{ PATHSPEC_GLOB,   '\0', "glob" },
+	{ PATHSPEC_ICASE,  '\0', "icase" },
 };
 
 /*
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (6 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE Nguyễn Thái Ngọc Duy
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 dir.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/dir.c b/dir.c
index 760b776..d0e7ca8 100644
--- a/dir.c
+++ b/dir.c
@@ -66,15 +66,22 @@ static size_t common_prefix_len(const struct pathspec *pathspec)
 	int n;
 	size_t max = 0;
 
+	/*
+	 * ":(icase)path" is treated as a pathspec full of wildcard
+	 */
 	GUARD_PATHSPEC(pathspec,
 		       PATHSPEC_FROMTOP |
 		       PATHSPEC_LITERAL |
-		       PATHSPEC_GLOB);
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE);
 
 	for (n = 0; n < pathspec->nr; n++) {
-		size_t i = 0, len = 0;
-		while (i < pathspec->items[n].nowildcard_len &&
-		       (n == 0 || i < max)) {
+		size_t i = 0, len = 0, item_len;
+		if (pathspec->items[n].magic & PATHSPEC_ICASE)
+			item_len = pathspec->items[n].prefix;
+		else
+			item_len = pathspec->items[n].nowildcard_len;
+		while (i < item_len && (n == 0 || i < max)) {
 			char c = pathspec->items[n].match[i];
 			if (c != pathspec->items[0].match[i])
 				break;
@@ -1240,7 +1247,8 @@ int read_directory(struct dir_struct *dir, const char *path, int len, const stru
 		GUARD_PATHSPEC(pathspec,
 			       PATHSPEC_FROMTOP |
 			       PATHSPEC_LITERAL |
-			       PATHSPEC_GLOB);
+			       PATHSPEC_GLOB |
+			       PATHSPEC_ICASE);
 
 	if (has_symlink_leading_path(path, len))
 		return dir->nr;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (7 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  2013-01-13 12:49 ` [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE Nguyễn Thái Ngọc Duy
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 cache.h     | 17 +++++++++++++++++
 dir.c       | 18 +++++++++++-------
 tree-walk.c | 30 +++++++++++++++++++-----------
 3 files changed, 47 insertions(+), 18 deletions(-)

diff --git a/cache.h b/cache.h
index c3b5585..216f87c 100644
--- a/cache.h
+++ b/cache.h
@@ -522,6 +522,23 @@ extern void free_pathspec(struct pathspec *);
 extern int ce_path_match(const struct cache_entry *ce, const struct pathspec *pathspec);
 
 extern int limit_pathspec_to_literal(void);
+static inline int ps_strncmp(const struct pathspec_item *item,
+			     const char *s1, const char *s2, size_t n)
+{
+	if (item->magic & PATHSPEC_ICASE)
+		return strncasecmp(s1, s2, n);
+	else
+		return strncmp(s1, s2, n);
+}
+
+static inline int ps_strcmp(const struct pathspec_item *item,
+			    const char *s1, const char *s2)
+{
+	if (item->magic & PATHSPEC_ICASE)
+		return strcasecmp(s1, s2);
+	else
+		return strcmp(s1, s2);
+}
 
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
diff --git a/dir.c b/dir.c
index d0e7ca8..e9edb65 100644
--- a/dir.c
+++ b/dir.c
@@ -42,7 +42,7 @@ inline int git_fnmatch(const struct pathspec_item *item,
 		       int prefix)
 {
 	if (prefix > 0) {
-		if (strncmp(pattern, string, prefix))
+		if (ps_strncmp(item, pattern, string, prefix))
 			return FNM_NOMATCH;
 		pattern += prefix;
 		string += prefix;
@@ -51,14 +51,16 @@ inline int git_fnmatch(const struct pathspec_item *item,
 		int pattern_len = strlen(++pattern);
 		int string_len = strlen(string);
 		return string_len < pattern_len ||
-		       strcmp(pattern,
-			      string + string_len - pattern_len);
+			ps_strcmp(item, pattern,
+				  string + string_len - pattern_len);
 	}
 	if (item->magic & PATHSPEC_GLOB)
-		return wildmatch(pattern, string, 0);
+		return wildmatch(pattern, string,
+				 item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
 	else
 		/* wildmatch has not learned no FNM_PATHNAME mode yet */
-		return fnmatch(pattern, string, 0);
+		return fnmatch(pattern, string,
+			       item->magic & PATHSPEC_ICASE ? FNM_CASEFOLD : 0);
 }
 
 static size_t common_prefix_len(const struct pathspec *pathspec)
@@ -162,7 +164,7 @@ static int match_pathspec_item(const struct pathspec_item *item, int prefix,
 	if (!*match)
 		return MATCHED_RECURSIVELY;
 
-	if (matchlen <= namelen && !strncmp(match, name, matchlen)) {
+	if (matchlen <= namelen && !ps_strncmp(item, match, name, matchlen)) {
 		if (matchlen == namelen)
 			return MATCHED_EXACTLY;
 
@@ -192,10 +194,12 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
 	int i, retval = 0;
 
+	/* BUG: we should not match icase on the prefix part */
 	GUARD_PATHSPEC(ps,
 		       PATHSPEC_FROMTOP |
 		       PATHSPEC_LITERAL |
-		       PATHSPEC_GLOB);
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
diff --git a/tree-walk.c b/tree-walk.c
index 1679ce7..3d9c2ba 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -488,7 +488,8 @@ int get_tree_entry(const unsigned char *tree_sha1, const char *name, unsigned ch
 	return retval;
 }
 
-static int match_entry(const struct name_entry *entry, int pathlen,
+static int match_entry(const struct pathspec_item *item,
+		       const struct name_entry *entry, int pathlen,
 		       const char *match, int matchlen,
 		       enum interesting *never_interesting)
 {
@@ -504,8 +505,8 @@ static int match_entry(const struct name_entry *entry, int pathlen,
 		 * Does match sort strictly earlier than path
 		 * with their common parts?
 		 */
-		m = strncmp(match, entry->path,
-			    (matchlen < pathlen) ? matchlen : pathlen);
+		m = ps_strncmp(item, match, entry->path,
+			       (matchlen < pathlen) ? matchlen : pathlen);
 		if (m < 0)
 			return 0;
 
@@ -540,7 +541,7 @@ static int match_entry(const struct name_entry *entry, int pathlen,
 		 * we cheated and did not do strncmp(), so we do
 		 * that here.
 		 */
-		m = strncmp(match, entry->path, pathlen);
+		m = ps_strncmp(item, match, entry->path, pathlen);
 
 	/*
 	 * If common part matched earlier then it is a hit,
@@ -553,10 +554,11 @@ static int match_entry(const struct name_entry *entry, int pathlen,
 	return 0;
 }
 
-static int match_dir_prefix(const char *base,
+static int match_dir_prefix(const struct pathspec_item *item,
+			    const char *base,
 			    const char *match, int matchlen)
 {
-	if (strncmp(base, match, matchlen))
+	if (ps_strncmp(item, base, match, matchlen))
 		return 0;
 
 	/*
@@ -593,7 +595,7 @@ static int match_wildcard_base(const struct pathspec_item *item,
 		 */
 		if (baselen >= matchlen) {
 			*matched = matchlen;
-			return !strncmp(base, match, matchlen);
+			return !ps_strncmp(item, base, match, matchlen);
 		}
 
 		dirlen = matchlen;
@@ -606,7 +608,7 @@ static int match_wildcard_base(const struct pathspec_item *item,
 		 * base ends with '/' so we are sure it really matches
 		 * directory
 		 */
-		if (strncmp(base, match, baselen))
+		if (ps_strncmp(item, base, match, baselen))
 			return 0;
 		*matched = baselen;
 	} else
@@ -635,10 +637,16 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 	enum interesting never_interesting = ps->has_wildcard ?
 		entry_not_interesting : all_entries_not_interesting;
 
+	/*
+	 * BUG: we should not match icase on the prefix part. The
+	 * prefix length is in 'ps'. Although using it won't be easy
+	 * as the pattern is cut into pieces...
+	 */
 	GUARD_PATHSPEC(ps,
 		       PATHSPEC_FROMTOP |
 		       PATHSPEC_LITERAL |
-		       PATHSPEC_GLOB);
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE);
 
 	if (!ps->nr) {
 		if (!ps->recursive || ps->max_depth == -1)
@@ -659,7 +667,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 
 		if (baselen >= matchlen) {
 			/* If it doesn't match, move along... */
-			if (!match_dir_prefix(base_str, match, matchlen))
+			if (!match_dir_prefix(item, base_str, match, matchlen))
 				goto match_wildcards;
 
 			if (!ps->recursive || ps->max_depth == -1)
@@ -674,7 +682,7 @@ enum interesting tree_entry_interesting(const struct name_entry *entry,
 
 		/* Either there must be no base, or the base must match. */
 		if (baselen == 0 || !strncmp(base_str, match, baselen)) {
-			if (match_entry(entry, pathlen,
+			if (match_entry(item, entry, pathlen,
 					match + baselen, matchlen - baselen,
 					&never_interesting))
 				return entry_interesting;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE
  2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
                   ` (8 preceding siblings ...)
  2013-01-13 12:49 ` [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting Nguyễn Thái Ngọc Duy
@ 2013-01-13 12:49 ` Nguyễn Thái Ngọc Duy
  9 siblings, 0 replies; 11+ messages in thread
From: Nguyễn Thái Ngọc Duy @ 2013-01-13 12:49 UTC (permalink / raw)
  To: git; +Cc: Nguyễn Thái Ngọc Duy


Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 builtin/add.c      | 6 ++++--
 builtin/ls-files.c | 3 ++-
 builtin/ls-tree.c  | 3 ++-
 3 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index a3ffa9d..b9a5432 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -421,12 +421,14 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 		GUARD_PATHSPEC(&pathspec,
 			       PATHSPEC_FROMTOP |
 			       PATHSPEC_LITERAL |
-			       PATHSPEC_GLOB);
+			       PATHSPEC_GLOB |
+			       PATHSPEC_ICASE);
 
 		for (i = 0; i < pathspec.nr; i++) {
 			const char *path = pathspec.items[i].match;
 			if (!seen[i] &&
-			    ((pathspec.items[i].magic & PATHSPEC_GLOB) ||
+			    ((pathspec.items[i].magic &
+			      (PATHSPEC_GLOB | PATHSPEC_ICASE)) ||
 			     !file_exists(path))) {
 				if (ignore_missing) {
 					int dtype = DT_UNKNOWN;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index feb4220..53b222d 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -538,7 +538,8 @@ int cmd_ls_files(int argc, const char **argv, const char *cmd_prefix)
 	parse_pathspec(&pathspec,
 		       PATHSPEC_FROMTOP |
 		       PATHSPEC_LITERAL |
-		       PATHSPEC_GLOB,
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE,
 		       PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
 		       prefix, argv);
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 25d0590..cf943dd 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -175,7 +175,8 @@ int cmd_ls_tree(int argc, const char **argv, const char *prefix)
 	parse_pathspec(&pathspec,
 		       PATHSPEC_FROMTOP |
 		       PATHSPEC_LITERAL |
-		       PATHSPEC_GLOB,
+		       PATHSPEC_GLOB |
+		       PATHSPEC_ICASE,
 		       0, prefix, argv + 1);
 	for (i = 0; i < pathspec.nr; i++)
 		pathspec.items[i].nowildcard_len = pathspec.items[i].len;
-- 
1.8.0.rc2.23.g1fb49df

^ permalink raw reply related	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2013-01-13 12:50 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-01-13 12:49 [PATCH/WIP 00/10] Fancy pathspec stuff Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 01/10] pathspec: allow to use alternate char for quoting long magic mnemonic Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 02/10] parse_pathspec: make sure the prefix part is wildcard-free Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 03/10] pathspec: support :(literal) syntax for noglob pathspec Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 04/10] parse_pathspec: save prefix information Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 05/10] pathspec: prepare for :(glob)path syntax Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 06/10] Enable :(glob)path syntax for a lot of commands Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 07/10] parse_pathspec: accept :(icase)path syntax Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 08/10] common_prefix/read_directory: treat PATHSPEC_ICASE like wildcards Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 09/10] pathspec: support icase in match_pathspec_depth and tree_entry_interesting Nguyễn Thái Ngọc Duy
2013-01-13 12:49 ` [PATCH/WIP 10/10] Enable ls-files and ls-tree for testing PATHSPEC_ICASE Nguyễn Thái Ngọc Duy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).