All of lore.kernel.org
 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.