[PATCH v4 0/2] git-multimail: a replacement for post-receive-email

2013-07-14 Thread Michael Haggerty
This is the fourth iteration submission of git-multimail to Git.  The
earlier submissions have all gotten a lot of good feedback, which has
mostly been implemented.  This submission differs from v3 in the
following ways:

* Renames the directory within the Git project from
  contrib/hooks/git-multimail/ to contrib/hooks/multimail/.  The
  git- seems redundant within the Git project [1].  I have no strong
  feelings either way.

* Includes the latest version of the upstream project.  Highlights:

  * A change in how git-multimail is configured via Python.  I wasn't
happy with the old method; concerns were not separated well
enough.  I wanted to get this right before more people start
writing against the internal API.  The new version uses mixin
classes, which is a technique that can easily be overdone.  But in
this case I was happy with the way that it permitted different
aspects of the configuration to be disentangled quite well.  (This
doesn't change how the script is configured externally via git
config; that has been stable for quite some time already.)

  * Fixes a scalability issue for repos with lots of refs that was
pointed out by Ævar Bjarmason.

  * Allows an arbitrary program to be substituted in place of
/usr/sbin/sendmail when using the SendMailer.

  * Improvements suggested by Ramkumar Ramachandra's code review
(thanks!).

  * Various documentation improvements.

* Adds a new file, README.Git, which explains the relationship between
  the Git and git-multimail projects, and documents the version of the
  upstream project that corresponds to the code being submitted to the
  Git project.

* Adds a notice to contrib/hooks/multimail/post-receive deprecating
  that script and pointing users to git-multimail.

The upstream project also now includes better tests.  Though I am not
including the tests in the code submitted to the Git project,
obviously the code benefits from them.

[1] I also got the feeling that Junio prefers the new directory name,
though there is a good chance that I read more into one of his
emails than he intended.

Michael Haggerty (2):
  git-multimail: an improved replacement for post-receive-email
  post-receive-email: deprecate script in favor of git-multimail

 contrib/hooks/multimail/README |  486 
 contrib/hooks/multimail/README.Git |   15 +
 .../README.migrate-from-post-receive-email |  146 ++
 contrib/hooks/multimail/git_multimail.py   | 2394 
 contrib/hooks/multimail/migrate-mailhook-config|  270 +++
 contrib/hooks/multimail/post-receive   |   90 +
 contrib/hooks/post-receive-email   |   17 +-
 7 files changed, 3414 insertions(+), 4 deletions(-)
 create mode 100644 contrib/hooks/multimail/README
 create mode 100644 contrib/hooks/multimail/README.Git
 create mode 100644 
contrib/hooks/multimail/README.migrate-from-post-receive-email
 create mode 100755 contrib/hooks/multimail/git_multimail.py
 create mode 100755 contrib/hooks/multimail/migrate-mailhook-config
 create mode 100755 contrib/hooks/multimail/post-receive

-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v4 2/2] post-receive-email: deprecate script in favor of git-multimail

2013-07-14 Thread Michael Haggerty
Add a notice to the top of post-receive-email explaining that the
script is no longer under active development and pointing the user to
git-multimail.

Signed-off-by: Michael Haggerty mhag...@alum.mit.edu
---
If you think this is premature or the wording is too strong; feel free
to change or omit this patch.  I think it's fine, but then I might be
biased...

 contrib/hooks/post-receive-email | 17 +
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/contrib/hooks/post-receive-email b/contrib/hooks/post-receive-email
index 0e5b72d..23d7783 100755
--- a/contrib/hooks/post-receive-email
+++ b/contrib/hooks/post-receive-email
@@ -2,10 +2,19 @@
 #
 # Copyright (c) 2007 Andy Parkins
 #
-# An example hook script to mail out commit update information.  This hook
-# sends emails listing new revisions to the repository introduced by the
-# change being reported.  The rule is that (for branch updates) each commit
-# will appear on one email and one email only.
+# An example hook script to mail out commit update information.
+#
+# ***NOTICE***: This script is no longer under active development.  It
+# has been superseded by git-multimail, which is more capable and
+# configurable and is largely backwards-compatible with this script;
+# please see contrib/hooks/multimail/.  For instructions on how to
+# migrate from post-receive-email to git-multimail, please see
+# README.migrate-from-post-receive-email in that directory.
+#
+# This hook sends emails listing new revisions to the repository
+# introduced by the change being reported.  The rule is that (for
+# branch updates) each commit will appear on one email and one email
+# only.
 #
 # This hook is stored in the contrib/hooks directory.  Your distribution
 # will have put this somewhere standard.  You should make this script
-- 
1.8.3.2

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 03/46] pathspec: i18n-ize error strings in pathspec parsing code

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/pathspec.c b/pathspec.c
index 133f8be..403095b 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -167,11 +167,11 @@ static const char *prefix_pathspec(const char *prefix, 
int prefixlen, const char
break;
}
if (ARRAY_SIZE(pathspec_magic) = i)
-   die(Invalid pathspec magic '%.*s' in '%s',
+   die(_(Invalid pathspec magic '%.*s' in '%s'),
(int) len, copyfrom, elt);
}
if (*copyfrom != ')')
-   die(Missing ')' at the end of pathspec magic in '%s', 
elt);
+   die(_(Missing ')' at the end of pathspec magic in 
'%s'), elt);
copyfrom++;
} else {
/* shorthand */
@@ -188,7 +188,7 @@ static const char *prefix_pathspec(const char *prefix, int 
prefixlen, const char
break;
}
if (ARRAY_SIZE(pathspec_magic) = i)
-   die(Unimplemented pathspec magic '%c' in '%s',
+   die(_(Unimplemented pathspec magic '%c' in 
'%s'),
ch, elt);
}
if (*copyfrom == ':')
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 02/46] Move struct pathspec and related functions to pathspec.[ch]

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 archive.c  |   1 +
 builtin/grep.c |   1 +
 builtin/ls-files.c |   1 +
 builtin/ls-tree.c  |   1 +
 builtin/update-index.c |   1 +
 cache.h|  22 +---
 diff.h |   1 +
 dir.c  |   1 +
 pathspec.c | 150 +
 pathspec.h |  21 +++
 preload-index.c|   1 +
 setup.c| 149 
 tree-walk.c|   1 +
 13 files changed, 182 insertions(+), 169 deletions(-)

diff --git a/archive.c b/archive.c
index d254fa5..c699a2d 100644
--- a/archive.c
+++ b/archive.c
@@ -5,6 +5,7 @@
 #include archive.h
 #include parse-options.h
 #include unpack-trees.h
+#include pathspec.h
 
 static char const * const archive_usage[] = {
N_(git archive [options] tree-ish [path...]),
diff --git a/builtin/grep.c b/builtin/grep.c
index 159e65d..4de49df 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -17,6 +17,7 @@
 #include grep.h
 #include quote.h
 #include dir.h
+#include pathspec.h
 
 static char const * const grep_usage[] = {
N_(git grep [options] [-e] pattern [rev...] [[--] path...]),
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 3a410c3..30357df 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -13,6 +13,7 @@
 #include parse-options.h
 #include resolve-undo.h
 #include string-list.h
+#include pathspec.h
 
 static int abbrev;
 static int show_deleted;
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index fb76e38..93fc3a0 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -10,6 +10,7 @@
 #include quote.h
 #include builtin.h
 #include parse-options.h
+#include pathspec.h
 
 static int line_termination = '\n';
 #define LS_RECURSIVE 1
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 5c7762e..b9c2bd0 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -11,6 +11,7 @@
 #include refs.h
 #include resolve-undo.h
 #include parse-options.h
+#include pathspec.h
 
 /*
  * Default to not allowing changes to the list of files. The
diff --git a/cache.h b/cache.h
index dd0fb33..fd0a6f8 100644
--- a/cache.h
+++ b/cache.h
@@ -189,6 +189,8 @@ struct cache_entry {
 #error CE_EXTENDED_FLAGS out of range
 #endif
 
+struct pathspec;
+
 /*
  * Copy the sha1 and stat state of a cache entry from one to
  * another. But we never change the name, or the hash state!
@@ -489,28 +491,8 @@ extern void *read_blob_data_from_index(struct index_state 
*, const char *, unsig
 extern int ie_match_stat(const struct index_state *, const struct cache_entry 
*, struct stat *, unsigned int);
 extern int ie_modified(const struct index_state *, const struct cache_entry *, 
struct stat *, unsigned int);
 
-#define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
-
-struct pathspec {
-   const char **raw; /* get_pathspec() result, not freed by 
free_pathspec() */
-   int nr;
-   unsigned int has_wildcard:1;
-   unsigned int recursive:1;
-   int max_depth;
-   struct pathspec_item {
-   const char *match;
-   int len;
-   int nowildcard_len;
-   int flags;
-   } *items;
-};
-
-extern int init_pathspec(struct pathspec *, const char **);
-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);
-
 #define HASH_WRITE_OBJECT 1
 #define HASH_FORMAT_CHECK 2
 extern int index_fd(unsigned char *sha1, int fd, struct stat *st, enum 
object_type type, const char *path, unsigned flags);
diff --git a/diff.h b/diff.h
index 78b4091..d1bc914 100644
--- a/diff.h
+++ b/diff.h
@@ -5,6 +5,7 @@
 #define DIFF_H
 
 #include tree-walk.h
+#include pathspec.h
 
 struct rev_info;
 struct diff_options;
diff --git a/dir.c b/dir.c
index 0480419..b0599dd 100644
--- a/dir.c
+++ b/dir.c
@@ -11,6 +11,7 @@
 #include dir.h
 #include refs.h
 #include wildmatch.h
+#include pathspec.h
 
 struct path_simplify {
int len;
diff --git a/pathspec.c b/pathspec.c
index 284f397..133f8be 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -99,3 +99,153 @@ void die_if_path_beyond_symlink(const char *path, const 
char *prefix)
die(_('%s' is beyond a symbolic link), path + len);
}
 }
+
+/*
+ * Magic pathspec
+ *
+ * NEEDSWORK: These need to be moved to dir.h or even to a new
+ * pathspec.h when we restructure get_pathspec() users to use the
+ * struct pathspec interface.
+ *
+ * Possible future magic semantics include stuff like:
+ *
+ * { PATHSPEC_NOGLOB, '!', noglob },
+ * { PATHSPEC_ICASE, '\0', icase },
+ * { PATHSPEC_RECURSIVE, '*', recursive },
+ * { PATHSPEC_REGEXP, '\0', regexp },
+ *
+ */
+#define PATHSPEC_FROMTOP(10)
+
+static struct pathspec_magic {
+   unsigned bit;
+   char mnemonic; /* 

[PATCH v2 01/46] clean: remove unused variable seen

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c | 11 ++-
 1 file changed, 2 insertions(+), 9 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 04e396b..f955a40 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -155,7 +155,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
struct exclude_list *el;
const char *qname;
-   char *seen = NULL;
struct option options[] = {
OPT__QUIET(quiet, N_(do not print names of files removed)),
OPT__DRY_RUN(dry_run, N_(dry run)),
@@ -214,9 +213,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
 
fill_directory(dir, pathspec);
 
-   if (pathspec)
-   seen = xmalloc(argc  0 ? argc : 1);
-
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
int len, pos;
@@ -250,11 +246,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (lstat(ent-name, st))
continue;
 
-   if (pathspec) {
-   memset(seen, 0, argc  0 ? argc : 1);
+   if (pathspec)
matches = match_pathspec(pathspec, ent-name, len,
-0, seen);
-   }
+0, NULL);
 
if (S_ISDIR(st.st_mode)) {
strbuf_addstr(directory, ent-name);
@@ -281,7 +275,6 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
}
}
}
-   free(seen);
 
strbuf_release(directory);
string_list_clear(exclude_list, 0);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 00/46] struct pathspec conversion and :(glob) and :(icase)

2013-07-14 Thread Nguyễn Thái Ngọc Duy
Compared to the last round [1] this series mainly fixes comments and
commit messages suggested by Eric and Junio. It also fixes a conflict
with cb/log-follow-with-combined (in master) and introduces :(icase)
mentioned in the last round.

[1] http://thread.gmane.org/gmane.comp.version-control.git/226892

Nguyễn Thái Ngọc Duy (46):
  clean: remove unused variable seen
  Move struct pathspec and related functions to pathspec.[ch]
  pathspec: i18n-ize error strings in pathspec parsing code
  pathspec: add copy_pathspec
  Add parse_pathspec() that converts cmdline args to struct pathspec
  parse_pathspec: save original pathspec for reporting
  parse_pathspec: add PATHSPEC_PREFER_{CWD,FULL}
  Convert some get_pathspec() calls to parse_pathspec()
  parse_pathspec: add special flag for max_depth feature
  parse_pathspec: support stripping submodule trailing slashes
  parse_pathspec: support stripping/checking submodule paths
  parse_pathspec: support prefixing original patterns
  Guard against new pathspec magic in pathspec matching code
  clean: convert to use parse_pathspec
  commit: convert to use parse_pathspec
  status: convert to use parse_pathspec
  rerere: convert to use parse_pathspec
  checkout: convert to use parse_pathspec
  rm: convert to use parse_pathspec
  ls-files: convert to use parse_pathspec
  archive: convert to use parse_pathspec
  check-ignore: convert to use parse_pathspec
  add: convert to use parse_pathspec
  reset: convert to use parse_pathspec
  line-log: convert to use parse_pathspec
  Convert read_cache_preload() to take struct pathspec
  Convert run_add_interactive to use struct pathspec
  Convert unmerge_cache to take struct pathspec
  checkout: convert read_tree_some to take struct pathspec
  Convert report_path_error to take struct pathspec
  Convert refresh_index to take struct pathspec
  Convert {read,fill}_directory to take struct pathspec
  Convert add_files_to_cache to take struct pathspec
  Convert common_prefix() to use struct pathspec
  Remove diff_tree_{setup,release}_paths
  Remove init_pathspec() in favor of parse_pathspec()
  Remove match_pathspec() in favor of match_pathspec_depth()
  tree-diff: remove the use of pathspec's raw[] in follow-rename codepath
  Rename field raw to _raw in struct pathspec
  parse_pathspec: make sure the prefix part is wildcard-free
  parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN
  Kill limit_pathspec_to_literal() as it's only used by parse_pathspec()
  pathspec: support :(literal) syntax for noglob pathspec
  pathspec: make --literal-pathspecs disable pathspec magic
  pathspec: support :(glob) syntax
  parse_pathspec: accept :(icase)path syntax

 Documentation/git.txt |  31 ++-
 Documentation/glossary-content.txt|  52 +++-
 Documentation/technical/api-setup.txt |  38 ++-
 archive.c |  18 +-
 archive.h |   4 +-
 builtin/add.c | 166 ++---
 builtin/blame.c   |  14 +-
 builtin/check-ignore.c|  35 ++-
 builtin/checkout.c|  40 +--
 builtin/clean.c   |  24 +-
 builtin/commit.c  |  37 ++-
 builtin/diff-files.c  |   2 +-
 builtin/diff-index.c  |   2 +-
 builtin/diff.c|   6 +-
 builtin/grep.c|  10 +-
 builtin/log.c |   2 +-
 builtin/ls-files.c|  75 +++---
 builtin/ls-tree.c |  13 +-
 builtin/mv.c  |  13 +-
 builtin/rerere.c  |   8 +-
 builtin/reset.c   |  33 ++-
 builtin/rm.c  |  24 +-
 builtin/update-index.c|   6 +-
 cache.h   |  35 +--
 combine-diff.c|   4 +-
 commit.h  |   2 +-
 diff-lib.c|   3 +-
 diff.h|   3 +-
 dir.c | 319 +---
 dir.h |  18 +-
 git.c |  12 +
 line-log.c|   2 +-
 merge-recursive.c |   2 +-
 notes-merge.c |   4 +-
 path.c|  15 +-
 pathspec.c| 449 +++---
 pathspec.h|  88 ++-
 preload-index.c   |  21 +-
 read-cache.c  |   5 +-
 rerere.c  |   7 +-
 rerere.h  |   4 +-
 resolve-undo.c|   4 +-
 resolve-undo.h|   2 +-
 revision.c|  11 +-
 setup.c   | 173 ++---
 t/t0008-ignores.sh|   8 +-
 

[PATCH v2 04/46] pathspec: add copy_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
Because free_pathspec wants to free items pointer in the pathspec
structure, a simple structure assignment is not enough if you want to
copy an existing pathspec into another.  Freeing the original will
damage the copy unless a deep copy is made.

Note that the strings in pathspec-items-match and the array
pathspec-raw[] are still shared between the original and the copy.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/mv.c | 13 +++--
 pathspec.c   |  8 
 pathspec.h   |  1 +
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/builtin/mv.c b/builtin/mv.c
index 034fec9..16ce99b 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -15,8 +15,9 @@ static const char * const builtin_mv_usage[] = {
NULL
 };
 
-static const char **copy_pathspec(const char *prefix, const char **pathspec,
- int count, int base_name)
+static const char **internal_copy_pathspec(const char *prefix,
+  const char **pathspec,
+  int count, int base_name)
 {
int i;
const char **result = xmalloc((count + 1) * sizeof(const char *));
@@ -81,17 +82,17 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
if (read_cache()  0)
die(_(index file corrupt));
 
-   source = copy_pathspec(prefix, argv, argc, 0);
+   source = internal_copy_pathspec(prefix, argv, argc, 0);
modes = xcalloc(argc, sizeof(enum update_mode));
-   dest_path = copy_pathspec(prefix, argv + argc, 1, 0);
+   dest_path = internal_copy_pathspec(prefix, argv + argc, 1, 0);
 
if (dest_path[0][0] == '\0')
/* special case: . was normalized to  */
-   destination = copy_pathspec(dest_path[0], argv, argc, 1);
+   destination = internal_copy_pathspec(dest_path[0], argv, argc, 
1);
else if (!lstat(dest_path[0], st) 
S_ISDIR(st.st_mode)) {
dest_path[0] = add_slash(dest_path[0]);
-   destination = copy_pathspec(dest_path[0], argv, argc, 1);
+   destination = internal_copy_pathspec(dest_path[0], argv, argc, 
1);
} else {
if (argc != 1)
die(destination '%s' is not a directory, 
dest_path[0]);
diff --git a/pathspec.c b/pathspec.c
index 403095b..8fe56cd 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -249,3 +249,11 @@ const char **get_pathspec(const char *prefix, const char 
**pathspec)
return NULL;
return pathspec;
 }
+
+void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
+{
+   *dst = *src;
+   dst-items = xmalloc(sizeof(struct pathspec_item) * dst-nr);
+   memcpy(dst-items, src-items,
+  sizeof(struct pathspec_item) * dst-nr);
+}
diff --git a/pathspec.h b/pathspec.h
index 7884068..a621676 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -18,6 +18,7 @@ struct pathspec {
 };
 
 extern int init_pathspec(struct pathspec *, const char **);
+extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
 extern void free_pathspec(struct pathspec *);
 
 extern int limit_pathspec_to_literal(void);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 07/46] parse_pathspec: add PATHSPEC_PREFER_{CWD,FULL}

2013-07-14 Thread Nguyễn Thái Ngọc Duy
We have two ways of dealing with empty pathspec:

1. limit it to current prefix
2. match the entire working directory

Some commands go with #1, some #2. get_pathspec() and parse_pathspec()
only support #1. Make parse_pathspec() reject empty pathspec by
default. #1 and #2 can be specified via new flags. This makes it more
expressive about default behavior at command level.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 13 -
 pathspec.h |  4 
 2 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/pathspec.c b/pathspec.c
index f94beb6..6d99a3d 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -271,10 +271,20 @@ void parse_pathspec(struct pathspec *pathspec,
if (!entry  !prefix)
return;
 
+   if ((flags  PATHSPEC_PREFER_CWD) 
+   (flags  PATHSPEC_PREFER_FULL))
+   die(BUG: PATHSPEC_PREFER_CWD and PATHSPEC_PREFER_FULL are 
incompatible);
+
/* No arguments with prefix - prefix pathspec */
if (!entry) {
static const char *raw[2];
 
+   if (flags  PATHSPEC_PREFER_FULL)
+   return;
+
+   if (!(flags  PATHSPEC_PREFER_CWD))
+   die(BUG: PATHSPEC_PREFER_CWD requires arguments);
+
pathspec-items = item = xmalloc(sizeof(*item));
memset(item, 0, sizeof(*item));
item-match = prefix;
@@ -340,7 +350,8 @@ const char **get_pathspec(const char *prefix, const char 
**pathspec)
struct pathspec ps;
parse_pathspec(ps,
   PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP,
-  0, prefix, pathspec);
+  PATHSPEC_PREFER_CWD,
+  prefix, pathspec);
return ps.raw;
 }
 
diff --git a/pathspec.h b/pathspec.h
index cc5841b..d630e8b 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -24,6 +24,10 @@ struct pathspec {
} *items;
 };
 
+/* parse_pathspec flags */
+#define PATHSPEC_PREFER_CWD (10) /* No args means match cwd */
+#define PATHSPEC_PREFER_FULL (11) /* No args means match everything */
+
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
   unsigned magic_mask,
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 08/46] Convert some get_pathspec() calls to parse_pathspec()

2013-07-14 Thread Nguyễn Thái Ngọc Duy
These call sites follow the pattern:

   paths = get_pathspec(prefix, argv);
   init_pathspec(pathspec, paths);

which can be converted into a single parse_pathspec() call.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/grep.c |  6 +++---
 builtin/ls-tree.c  | 10 +-
 builtin/update-index.c |  5 +++--
 revision.c |  4 ++--
 4 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 4de49df..1a6c028 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -631,7 +631,6 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
const char *show_in_pager = NULL, *default_pager = dummy;
struct grep_opt opt;
struct object_array list = OBJECT_ARRAY_INIT;
-   const char **paths = NULL;
struct pathspec pathspec;
struct string_list path_list = STRING_LIST_INIT_NODUP;
int i;
@@ -858,8 +857,9 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
verify_filename(prefix, argv[j], j == i);
}
 
-   paths = get_pathspec(prefix, argv + i);
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_CWD,
+  prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
 
diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index 93fc3a0..bdb03f3 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -167,7 +167,15 @@ int cmd_ls_tree(int argc, const char **argv, const char 
*prefix)
if (get_sha1(argv[0], sha1))
die(Not a valid object name %s, argv[0]);
 
-   init_pathspec(pathspec, get_pathspec(prefix, argv + 1));
+   /*
+* show_recursive() rolls its own matching code and is
+* generally ignorant of 'struct pathspec'. The magic mask
+* cannot be lifted until it is converted to use
+* match_pathspec_depth() or tree_entry_interesting()
+*/
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_CWD,
+  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/update-index.c b/builtin/update-index.c
index b9c2bd0..e795818 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -547,10 +547,11 @@ static int do_reupdate(int ac, const char **av,
 */
int pos;
int has_head = 1;
-   const char **paths = get_pathspec(prefix, av + 1);
struct pathspec pathspec;
 
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_CWD,
+  prefix, av + 1);
 
if (read_ref(HEAD, head_sha1))
/* If there is no HEAD, that means it is an initial
diff --git a/revision.c b/revision.c
index 2f0142f..cdc7f45 100644
--- a/revision.c
+++ b/revision.c
@@ -2120,8 +2120,8 @@ 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;
-   init_pathspec(revs-prune_data,
- get_pathspec(revs-prefix, prune_data.path));
+   parse_pathspec(revs-prune_data, 0, 0,
+  revs-prefix, prune_data.path);
}
 
if (revs-def == NULL)
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 09/46] parse_pathspec: add special flag for max_depth feature

2013-07-14 Thread Nguyễn Thái Ngọc Duy
match_pathspec_depth() and tree_entry_interesting() check max_depth
field in order to support git grep --max-depth. The feature
activation is tied to recursive field, which led to some unwanted
activation, e.g. 5c8eeb8 (diff-index: enable recursive pathspec
matching in unpack_trees - 2012-01-15).

This patch decouples the activation from recursive field, puts it in
magic field instead. This makes sure that only git grep can
activate this feature. And because parse_pathspec knows when the
feature is not used, it does not need to sort pathspec (required for
max_depth to work correctly). A small win for non-grep cases.

Even though a new magic flag is introduced, no magic syntax is. The
magic can be only enabled by parse_pathspec() caller. We might someday
want to support :(maxdepth:10)src. It all depends on actual use
cases.

max_depth feature cannot be enabled via init_pathspec() anymore. But
that's ok because init_pathspec() is on its way to /dev/null.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/grep.c | 3 ++-
 diff-lib.c | 1 -
 dir.c  | 8 ++--
 pathspec.c | 8 ++--
 pathspec.h | 6 +-
 tree-diff.c| 1 -
 tree-walk.c| 8 ++--
 7 files changed, 25 insertions(+), 10 deletions(-)

diff --git a/builtin/grep.c b/builtin/grep.c
index 1a6c028..4bc0754 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -858,7 +858,8 @@ int cmd_grep(int argc, const char **argv, const char 
*prefix)
}
 
parse_pathspec(pathspec, 0,
-  PATHSPEC_PREFER_CWD,
+  PATHSPEC_PREFER_CWD |
+  (opt.max_depth != -1 ? PATHSPEC_MAXDEPTH_VALID : 0),
   prefix, argv + i);
pathspec.max_depth = opt.max_depth;
pathspec.recursive = 1;
diff --git a/diff-lib.c b/diff-lib.c
index b6f4b21..d4e17f7 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -476,7 +476,6 @@ static int diff_cache(struct rev_info *revs,
opts.dst_index = NULL;
opts.pathspec = revs-diffopt.pathspec;
opts.pathspec-recursive = 1;
-   opts.pathspec-max_depth = -1;
 
init_tree_desc(t, tree-buffer, tree-size);
return unpack_trees(1, t, opts);
diff --git a/dir.c b/dir.c
index 308028e..e28bc0d 100644
--- a/dir.c
+++ b/dir.c
@@ -341,7 +341,9 @@ int match_pathspec_depth(const struct pathspec *ps,
int i, retval = 0;
 
if (!ps-nr) {
-   if (!ps-recursive || ps-max_depth == -1)
+   if (!ps-recursive ||
+   !(ps-magic  PATHSPEC_MAXDEPTH) ||
+   ps-max_depth == -1)
return MATCHED_RECURSIVELY;
 
if (within_depth(name, namelen, 0, ps-max_depth))
@@ -358,7 +360,9 @@ int match_pathspec_depth(const struct pathspec *ps,
if (seen  seen[i] == MATCHED_EXACTLY)
continue;
how = match_pathspec_item(ps-items+i, prefix, name, namelen);
-   if (ps-recursive  ps-max_depth != -1 
+   if (ps-recursive 
+   (ps-magic  PATHSPEC_MAXDEPTH) 
+   ps-max_depth != -1 
how  how != MATCHED_FNMATCH) {
int len = ps-items[i].len;
if (name[len] == '/')
diff --git a/pathspec.c b/pathspec.c
index 6d99a3d..06778fc 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -267,6 +267,9 @@ void parse_pathspec(struct pathspec *pathspec,
 
memset(pathspec, 0, sizeof(*pathspec));
 
+   if (flags  PATHSPEC_MAXDEPTH_VALID)
+   pathspec-magic |= PATHSPEC_MAXDEPTH;
+
/* No arguments, no prefix - no pathspec */
if (!entry  !prefix)
return;
@@ -322,8 +325,9 @@ void parse_pathspec(struct pathspec *pathspec,
pathspec-magic |= item[i].magic;
}
 
-   qsort(pathspec-items, pathspec-nr,
- sizeof(struct pathspec_item), pathspec_item_cmp);
+   if (pathspec-magic  PATHSPEC_MAXDEPTH)
+   qsort(pathspec-items, pathspec-nr,
+ sizeof(struct pathspec_item), pathspec_item_cmp);
 }
 
 /*
diff --git a/pathspec.h b/pathspec.h
index d630e8b..aa98597 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -3,7 +3,10 @@
 
 /* Pathspec magic */
 #define PATHSPEC_FROMTOP   (10)
-#define PATHSPEC_ALL_MAGIC PATHSPEC_FROMTOP
+#define PATHSPEC_MAXDEPTH  (11)
+#define PATHSPEC_ALL_MAGIC   \
+   (PATHSPEC_FROMTOP   | \
+PATHSPEC_MAXDEPTH)
 
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
@@ -27,6 +30,7 @@ struct pathspec {
 /* parse_pathspec flags */
 #define PATHSPEC_PREFER_CWD (10) /* No args means match cwd */
 #define PATHSPEC_PREFER_FULL (11) /* No args means match everything */
+#define PATHSPEC_MAXDEPTH_VALID (12) /* max_depth field is valid */
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
diff --git a/tree-diff.c b/tree-diff.c

[PATCH v2 13/46] Guard against new pathspec magic in pathspec matching code

2013-07-14 Thread Nguyễn Thái Ngọc Duy
GUARD_PATHSPEC() marks pathspec-sensitive code, basically all those
that touch anything in 'struct pathspec' except fields nr and
original. GUARD_PATHSPEC() is not supposed to fail. It's mainly to
help the designers catch unsupported codepaths.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/technical/api-setup.txt | 19 +++
 builtin/diff.c|  2 ++
 dir.c |  2 ++
 pathspec.h|  7 +++
 tree-diff.c   | 19 +++
 tree-walk.c   |  2 ++
 6 files changed, 51 insertions(+)

diff --git a/Documentation/technical/api-setup.txt 
b/Documentation/technical/api-setup.txt
index 90d1aff..540e455 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -28,3 +28,22 @@ parse_pathspec(). This function takes several arguments:
 - prefix and args come from cmd_* functions
 
 get_pathspec() is obsolete and should never be used in new code.
+
+parse_pathspec() helps catch unsupported features and reject them
+politely. At a lower level, different pathspec-related functions may
+not support the same set of features. Such pathspec-sensitive
+functions are guarded with GUARD_PATHSPEC(), which will die in an
+unfriendly way when an unsupported feature is requested.
+
+The command designers are supposed to make sure that GUARD_PATHSPEC()
+never dies. They have to make sure all unsupported features are caught
+by parse_pathspec(), not by GUARD_PATHSPEC. grepping GUARD_PATHSPEC()
+should give the designers all pathspec-sensitive codepaths and what
+features they support.
+
+A similar process is applied when a new pathspec magic is added. The
+designer lifts the GUARD_PATHSPEC restriction in the functions that
+support the new magic. At the same time (s)he has to make sure this
+new feature will be caught at parse_pathspec() in commands that cannot
+handle the new magic in some cases. grepping parse_pathspec() should
+help.
diff --git a/builtin/diff.c b/builtin/diff.c
index 9fc273d..6bb41af 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -367,6 +367,8 @@ 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);
if (!path)
path = rev.prune_data.items[0].match;
paths += rev.prune_data.nr;
diff --git a/dir.c b/dir.c
index e28bc0d..19978d3 100644
--- a/dir.c
+++ b/dir.c
@@ -340,6 +340,8 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
int i, retval = 0;
 
+   GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
if (!ps-nr) {
if (!ps-recursive ||
!(ps-magic  PATHSPEC_MAXDEPTH) ||
diff --git a/pathspec.h b/pathspec.h
index 2e427d7..6baf205 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -27,6 +27,13 @@ struct pathspec {
} *items;
 };
 
+#define GUARD_PATHSPEC(ps, mask) \
+   do { \
+   if ((ps)-magic  ~(mask)) \
+   die(BUG:%s:%d: unsupported magic %x,  \
+   __FILE__, __LINE__, (ps)-magic  ~(mask)); \
+   } while (0)
+
 /* parse_pathspec flags */
 #define PATHSPEC_PREFER_CWD (10) /* No args means match cwd */
 #define PATHSPEC_PREFER_FULL (11) /* No args means match everything */
diff --git a/tree-diff.c b/tree-diff.c
index 826512e..5a87614 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -198,6 +198,25 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
const char *paths[1];
int i;
 
+   /*
+* follow-rename code is very specific, we need exactly one
+* path. Magic that matches more than one path is not
+* supported.
+*/
+   GUARD_PATHSPEC(opt-pathspec, PATHSPEC_FROMTOP);
+#if 0
+   /*
+* We should reject wildcards as well. Unfortunately we
+* haven't got a reliable way to detect that 'foo\*bar' in
+* fact has no wildcards. nowildcard_len is merely a hint for
+* optimization. Let it slip for now until wildmatch is taught
+* about dry-run mode and returns wildcard info.
+*/
+   if (opt-pathspec.has_wildcard)
+   die(BUG:%s:%d: wildcards are not supported,
+   __FILE__, __LINE__);
+#endif
+
/* Remove the file creation entry from the diff queue, and remember it 
*/
choice = q-queue[0];
q-nr = 0;
diff --git a/tree-walk.c b/tree-walk.c
index d399ca9..37b157e 100644
--- a/tree-walk.c
+++ b/tree-walk.c
@@ -636,6 +636,8 @@ 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, 

[PATCH v2 10/46] parse_pathspec: support stripping submodule trailing slashes

2013-07-14 Thread Nguyễn Thái Ngọc Duy
This flag is equivalent to builtin/ls-files.c:strip_trailing_slashes()
and is intended to replace that function when ls-files is converted to
use parse_pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 9 +
 pathspec.h | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/pathspec.c b/pathspec.c
index 06778fc..1c07c23 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -205,6 +205,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
*raw = item-match = match;
item-original = elt;
item-len = strlen(item-match);
+
+   if ((flags  PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) 
+   (item-len = 1  item-match[item-len - 1] == '/') 
+   (i = cache_name_pos(item-match, item-len - 1)) = 0 
+   S_ISGITLINK(active_cache[i]-ce_mode)) {
+   item-len--;
+   match[item-len] = '\0';
+   }
+
if (limit_pathspec_to_literal())
item-nowildcard_len = item-len;
else
diff --git a/pathspec.h b/pathspec.h
index aa98597..5144851 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -31,6 +31,8 @@ struct pathspec {
 #define PATHSPEC_PREFER_CWD (10) /* No args means match cwd */
 #define PATHSPEC_PREFER_FULL (11) /* No args means match everything */
 #define PATHSPEC_MAXDEPTH_VALID (12) /* max_depth field is valid */
+/* strip the trailing slash if the given path is a gitlink */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (13)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 12/46] parse_pathspec: support prefixing original patterns

2013-07-14 Thread Nguyễn Thái Ngọc Duy
This makes 'original' suitable for passing to an external command
because all pathspec magic is left in place, provided that the
external command understands pathspec. The prefixing is needed because
we usually launch a subcommand at worktree's top directory and the
subcommand can no longer calculate the prefix itself.

This slightly affects the original purpose of 'original'
(i.e. reporting). We should report without prefixing. So only turn
this flag on when you know you are about to pass the result straight
away to an external command.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 12 +++-
 pathspec.h |  1 +
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/pathspec.c b/pathspec.c
index e2a4f91..ba6408a 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -203,7 +203,17 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
else
match = prefix_path(prefix, prefixlen, copyfrom);
*raw = item-match = match;
-   item-original = elt;
+   /*
+* Prefix the pathspec (keep all magic) and assign to
+* original. Useful for passing to another command.
+*/
+   if (flags  PATHSPEC_PREFIX_ORIGIN) {
+   struct strbuf sb = STRBUF_INIT;
+   strbuf_add(sb, elt, copyfrom - elt);
+   strbuf_addstr(sb, match);
+   item-original = strbuf_detach(sb, NULL);
+   } else
+   item-original = elt;
item-len = strlen(item-match);
 
if ((flags  PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) 
diff --git a/pathspec.h b/pathspec.h
index 450fc03..2e427d7 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -43,6 +43,7 @@ struct pathspec {
  * safer than _SLASH_CHEAP and also more expensive.
  */
 #define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (15)
+#define PATHSPEC_PREFIX_ORIGIN (16)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 06/46] parse_pathspec: save original pathspec for reporting

2013-07-14 Thread Nguyễn Thái Ngọc Duy
We usually use pathspec_item's match field for pathspec error
reporting. However match (or raw) does not show the magic part,
which will play more important role later on. Preserve exact user
input for reporting.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c  | 1 +
 pathspec.c | 2 ++
 pathspec.h | 1 +
 3 files changed, 4 insertions(+)

diff --git a/dir.c b/dir.c
index 5f86e46..308028e 100644
--- a/dir.c
+++ b/dir.c
@@ -1599,6 +1599,7 @@ int init_pathspec(struct pathspec *pathspec, const char 
**paths)
const char *path = paths[i];
 
item-match = path;
+   item-original = path;
item-len = strlen(path);
item-flags = 0;
if (limit_pathspec_to_literal()) {
diff --git a/pathspec.c b/pathspec.c
index ce942db..f94beb6 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -203,6 +203,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
else
match = prefix_path(prefix, prefixlen, copyfrom);
*raw = item-match = match;
+   item-original = elt;
item-len = strlen(item-match);
if (limit_pathspec_to_literal())
item-nowildcard_len = item-len;
@@ -277,6 +278,7 @@ void parse_pathspec(struct pathspec *pathspec,
pathspec-items = item = xmalloc(sizeof(*item));
memset(item, 0, sizeof(*item));
item-match = prefix;
+   item-original = prefix;
item-nowildcard_len = item-len = strlen(prefix);
raw[0] = prefix;
raw[1] = NULL;
diff --git a/pathspec.h b/pathspec.h
index 937ec91..cc5841b 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -16,6 +16,7 @@ struct pathspec {
int max_depth;
struct pathspec_item {
const char *match;
+   const char *original;
unsigned magic;
int len;
int nowildcard_len;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 05/46] Add parse_pathspec() that converts cmdline args to struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
Currently to fill a struct pathspec, we do:

   const char **paths;
   paths = get_pathspec(prefix, argv);
   ...
   init_pathspec(pathspec, paths);

paths can only carry bare strings, which loses information from
command line arguments such as pathspec magic or the prefix part's
length for each argument.

parse_pathspec() is introduced to combine the two calls into one. The
plan is gradually replace all get_pathspec() and init_pathspec() with
parse_pathspec(). get_pathspec() now becomes a thin wrapper of
parse_pathspec().

parse_pathspec() allows the caller to reject the pathspec magics that
it does not support. When a new pathspec magic is introduced, we can
enable it per command after making sure that all underlying code has no
problem with the new magic.

flags parameter is currently unused. But it would allow callers to
pass certain instructions to parse_pathspec, for example forcing
literal pathspec when no magic is used.

With the introduction of parse_pathspec, there are now two functions
that can initialize struct pathspec: init_pathspec and
parse_pathspec. Any semantic changes in struct pathspec must be
reflected in both functions. init_pathspec() will be phased out in
favor of parse_pathspec().

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/technical/api-setup.txt |  19 +++-
 dir.c |   4 +-
 dir.h |   2 +
 pathspec.c| 168 ++
 pathspec.h|  11 +++
 5 files changed, 163 insertions(+), 41 deletions(-)

diff --git a/Documentation/technical/api-setup.txt 
b/Documentation/technical/api-setup.txt
index 4f63a04..90d1aff 100644
--- a/Documentation/technical/api-setup.txt
+++ b/Documentation/technical/api-setup.txt
@@ -8,6 +8,23 @@ Talk about
 * is_inside_git_dir()
 * is_inside_work_tree()
 * setup_work_tree()
-* get_pathspec()
 
 (Dscho)
+
+Pathspec
+
+
+See glossary-context.txt for the syntax of pathspec. In memory, a
+pathspec set is represented by struct pathspec and is prepared by
+parse_pathspec(). This function takes several arguments:
+
+- magic_mask specifies what features that are NOT supported by the
+  following code. If a user attempts to use such a feature,
+  parse_pathspec() can reject it early.
+
+- flags specifies other things that the caller wants parse_pathspec to
+  perform.
+
+- prefix and args come from cmd_* functions
+
+get_pathspec() is obsolete and should never be used in new code.
diff --git a/dir.c b/dir.c
index b0599dd..5f86e46 100644
--- a/dir.c
+++ b/dir.c
@@ -381,7 +381,7 @@ int match_pathspec_depth(const struct pathspec *ps,
 /*
  * Return the length of the simple part of a path match limiter.
  */
-static int simple_length(const char *match)
+int simple_length(const char *match)
 {
int len = -1;
 
@@ -393,7 +393,7 @@ static int simple_length(const char *match)
}
 }
 
-static int no_wildcard(const char *string)
+int no_wildcard(const char *string)
 {
return string[simple_length(string)] == '\0';
 }
diff --git a/dir.h b/dir.h
index 3d6b80c..229ccc8 100644
--- a/dir.h
+++ b/dir.h
@@ -128,6 +128,8 @@ struct dir_struct {
 #define MATCHED_RECURSIVELY 1
 #define MATCHED_FNMATCH 2
 #define MATCHED_EXACTLY 3
+extern int simple_length(const char *match);
+extern int no_wildcard(const char *string);
 extern char *common_prefix(const char **pathspec);
 extern int match_pathspec(const char **pathspec, const char *name, int 
namelen, int prefix, char *seen);
 extern int match_pathspec_depth(const struct pathspec *pathspec,
diff --git a/pathspec.c b/pathspec.c
index 8fe56cd..ce942db 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -103,10 +103,6 @@ void die_if_path_beyond_symlink(const char *path, const 
char *prefix)
 /*
  * Magic pathspec
  *
- * NEEDSWORK: These need to be moved to dir.h or even to a new
- * pathspec.h when we restructure get_pathspec() users to use the
- * struct pathspec interface.
- *
  * Possible future magic semantics include stuff like:
  *
  * { PATHSPEC_NOGLOB, '!', noglob },
@@ -115,7 +111,6 @@ void die_if_path_beyond_symlink(const char *path, const 
char *prefix)
  * { PATHSPEC_REGEXP, '\0', regexp },
  *
  */
-#define PATHSPEC_FROMTOP(10)
 
 static struct pathspec_magic {
unsigned bit;
@@ -127,7 +122,7 @@ static struct pathspec_magic {
 
 /*
  * Take an element of a pathspec and check for magic signatures.
- * Append the result to the prefix.
+ * Append the result to the prefix. Return the magic bitmap.
  *
  * For now, we only parse the syntax and throw out anything other than
  * top magic.
@@ -138,10 +133,15 @@ static struct pathspec_magic {
  * the prefix part must always match literally, and a single stupid
  * string cannot express such a case.
  */
-static const char *prefix_pathspec(const char *prefix, int prefixlen, const 
char *elt)
+static unsigned prefix_pathspec(struct pathspec_item *item,
+   

[PATCH v2 11/46] parse_pathspec: support stripping/checking submodule paths

2013-07-14 Thread Nguyễn Thái Ngọc Duy
PATHSPEC_SYMLINK_LEADING_PATH and _STRIP_SUBMODULE_SLASH_EXPENSIVE are
respectively the alternate implementation of
pathspec.c:die_if_path_beyond_symlink() and
pathspec.c:check_path_for_gitlink(). They are intended to replace
those functions when builtin/add.c and builtin/check-ignore.c are
converted to use parse_pathspec.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 26 ++
 pathspec.h | 10 ++
 2 files changed, 36 insertions(+)

diff --git a/pathspec.c b/pathspec.c
index 1c07c23..e2a4f91 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -214,6 +214,26 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
match[item-len] = '\0';
}
 
+   if (flags  PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE)
+   for (i = 0; i  active_nr; i++) {
+   struct cache_entry *ce = active_cache[i];
+   int ce_len = ce_namelen(ce);
+
+   if (!S_ISGITLINK(ce-ce_mode))
+   continue;
+
+   if (item-len = ce_len || match[ce_len] != '/' ||
+   memcmp(ce-name, match, ce_len))
+   continue;
+   if (item-len == ce_len + 1) {
+   /* strip trailing slash */
+   item-len--;
+   match[item-len] = '\0';
+   } else
+   die (_(Pathspec '%s' is in submodule '%.*s'),
+elt, ce_len, ce-name);
+   }
+
if (limit_pathspec_to_literal())
item-nowildcard_len = item-len;
else
@@ -329,6 +349,12 @@ void parse_pathspec(struct pathspec *pathspec,
unsupported_magic(entry,
  item[i].magic  magic_mask,
  short_magic);
+
+   if ((flags  PATHSPEC_SYMLINK_LEADING_PATH) 
+   has_symlink_leading_path(item[i].match, item[i].len)) {
+   die(_(pathspec '%s' is beyond a symbolic link), 
entry);
+   }
+
if (item[i].nowildcard_len  item[i].len)
pathspec-has_wildcard = 1;
pathspec-magic |= item[i].magic;
diff --git a/pathspec.h b/pathspec.h
index 5144851..450fc03 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -33,6 +33,16 @@ struct pathspec {
 #define PATHSPEC_MAXDEPTH_VALID (12) /* max_depth field is valid */
 /* strip the trailing slash if the given path is a gitlink */
 #define PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP (13)
+/* die if a symlink is part of the given path's directory */
+#define PATHSPEC_SYMLINK_LEADING_PATH (14)
+/*
+ * This is like a combination of ..LEADING_PATH and .._SLASH_CHEAP
+ * (but not the same): it strips the trailing slash if the given path
+ * is a gitlink but also checks and dies if gitlink is part of the
+ * leading path (i.e. the given path goes beyond a submodule). It's
+ * safer than _SLASH_CHEAP and also more expensive.
+ */
+#define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (15)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 14/46] clean: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index f955a40..fdd4980 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -13,6 +13,7 @@
 #include refs.h
 #include string-list.h
 #include quote.h
+#include pathspec.h
 
 static int force = -1; /* unset */
 
@@ -150,7 +151,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
int rm_flags = REMOVE_DIR_KEEP_NESTED_GIT;
struct strbuf directory = STRBUF_INIT;
struct dir_struct dir;
-   static const char **pathspec;
+   struct pathspec pathspec;
struct strbuf buf = STRBUF_INIT;
struct string_list exclude_list = STRING_LIST_INIT_NODUP;
struct exclude_list *el;
@@ -209,9 +210,11 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
for (i = 0; i  exclude_list.nr; i++)
add_exclude(exclude_list.items[i].string, , 0, el, -(i+1));
 
-   pathspec = get_pathspec(prefix, argv);
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_CWD,
+  prefix, argv);
 
-   fill_directory(dir, pathspec);
+   fill_directory(dir, pathspec.raw);
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
@@ -246,9 +249,9 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
if (lstat(ent-name, st))
continue;
 
-   if (pathspec)
-   matches = match_pathspec(pathspec, ent-name, len,
-0, NULL);
+   if (pathspec.nr)
+   matches = match_pathspec_depth(pathspec, ent-name,
+  len, 0, NULL);
 
if (S_ISDIR(st.st_mode)) {
strbuf_addstr(directory, ent-name);
@@ -262,7 +265,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
}
strbuf_reset(directory);
} else {
-   if (pathspec  !matches)
+   if (pathspec.nr  !matches)
continue;
res = dry_run ? 0 : unlink(ent-name);
if (res) {
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 19/46] rm: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/rm.c | 24 
 1 file changed, 12 insertions(+), 12 deletions(-)

diff --git a/builtin/rm.c b/builtin/rm.c
index 06025a2..ee0ae4c 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -11,6 +11,7 @@
 #include parse-options.h
 #include string-list.h
 #include submodule.h
+#include pathspec.h
 
 static const char * const builtin_rm_usage[] = {
N_(git rm [options] [--] file...),
@@ -279,7 +280,7 @@ static struct option builtin_rm_options[] = {
 int cmd_rm(int argc, const char **argv, const char *prefix)
 {
int i, newfd;
-   const char **pathspec;
+   struct pathspec pathspec;
char *seen;
 
git_config(git_default_config, NULL);
@@ -312,31 +313,30 @@ int cmd_rm(int argc, const char **argv, const char 
*prefix)
}
}
 
-   pathspec = get_pathspec(prefix, argv);
-   refresh_index(the_index, REFRESH_QUIET, pathspec, NULL, NULL);
+   parse_pathspec(pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv);
+   refresh_index(the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
 
seen = NULL;
-   for (i = 0; pathspec[i] ; i++)
-   /* nothing */;
-   seen = xcalloc(i, 1);
+   seen = xcalloc(pathspec.nr, 1);
 
for (i = 0; i  active_nr; i++) {
struct cache_entry *ce = active_cache[i];
-   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, 
seen))
+   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, seen))
continue;
ALLOC_GROW(list.entry, list.nr + 1, list.alloc);
list.entry[list.nr].name = ce-name;
list.entry[list.nr++].is_submodule = S_ISGITLINK(ce-ce_mode);
}
 
-   if (pathspec) {
-   const char *match;
+   if (pathspec.nr) {
+   const char *original;
int seen_any = 0;
-   for (i = 0; (match = pathspec[i]) != NULL ; i++) {
+   for (i = 0; i  pathspec.nr; i++) {
+   original = pathspec.items[i].original;
if (!seen[i]) {
if (!ignore_unmatch) {
die(_(pathspec '%s' did not match any 
files),
-   match);
+   original);
}
}
else {
@@ -344,7 +344,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
}
if (!recursive  seen[i] == MATCHED_RECURSIVELY)
die(_(not removing '%s' recursively without 
-r),
-   *match ? match : .);
+   *original ? original : .);
}
 
if (! seen_any)
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 21/46] archive: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 archive.c | 19 +++
 archive.h |  4 +++-
 2 files changed, 14 insertions(+), 9 deletions(-)

diff --git a/archive.c b/archive.c
index c699a2d..99fadc8 100644
--- a/archive.c
+++ b/archive.c
@@ -5,7 +5,6 @@
 #include archive.h
 #include parse-options.h
 #include unpack-trees.h
-#include pathspec.h
 
 static char const * const archive_usage[] = {
N_(git archive [options] tree-ish [path...]),
@@ -152,7 +151,6 @@ int write_archive_entries(struct archiver_args *args,
struct archiver_context context;
struct unpack_trees_options opts;
struct tree_desc t;
-   struct pathspec pathspec;
int err;
 
if (args-baselen  0  args-base[args-baselen - 1] == '/') {
@@ -187,10 +185,8 @@ int write_archive_entries(struct archiver_args *args,
git_attr_set_direction(GIT_ATTR_INDEX, the_index);
}
 
-   init_pathspec(pathspec, args-pathspec);
-   err = read_tree_recursive(args-tree, , 0, 0, pathspec,
+   err = read_tree_recursive(args-tree, , 0, 0, args-pathspec,
  write_archive_entry, context);
-   free_pathspec(pathspec);
if (err == READ_TREE_RECURSIVE)
err = 0;
return err;
@@ -223,7 +219,7 @@ static int path_exists(struct tree *tree, const char *path)
struct pathspec pathspec;
int ret;
 
-   init_pathspec(pathspec, paths);
+   parse_pathspec(pathspec, 0, 0, , paths);
ret = read_tree_recursive(tree, , 0, 0, pathspec, reject_entry, 
NULL);
free_pathspec(pathspec);
return ret != 0;
@@ -232,11 +228,18 @@ static int path_exists(struct tree *tree, const char 
*path)
 static void parse_pathspec_arg(const char **pathspec,
struct archiver_args *ar_args)
 {
-   ar_args-pathspec = pathspec = get_pathspec(, pathspec);
+   /*
+* must be consistent with parse_pathspec in path_exists()
+* Also if pathspec patterns are dependent, we're in big
+* trouble as we test each one separately
+*/
+   parse_pathspec(ar_args-pathspec, 0,
+  PATHSPEC_PREFER_FULL,
+  , pathspec);
if (pathspec) {
while (*pathspec) {
if (**pathspec  !path_exists(ar_args-tree, 
*pathspec))
-   die(path not found: %s, *pathspec);
+   die(_(pathspec '%s' did not match any files), 
*pathspec);
pathspec++;
}
}
diff --git a/archive.h b/archive.h
index 895afcd..4a791e1 100644
--- a/archive.h
+++ b/archive.h
@@ -1,6 +1,8 @@
 #ifndef ARCHIVE_H
 #define ARCHIVE_H
 
+#include pathspec.h
+
 struct archiver_args {
const char *base;
size_t baselen;
@@ -8,7 +10,7 @@ struct archiver_args {
const unsigned char *commit_sha1;
const struct commit *commit;
time_t time;
-   const char **pathspec;
+   struct pathspec pathspec;
unsigned int verbose : 1;
unsigned int worktree_attributes : 1;
unsigned int convert : 1;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 16/46] status: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c |  9 +
 wt-status.c  | 16 +++-
 wt-status.h  |  2 +-
 3 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 530f0ed..64d1a3d 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1241,11 +1241,12 @@ 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;
-   if (*argv)
-   s.pathspec = get_pathspec(prefix, argv);
+   parse_pathspec(s.pathspec, 0,
+  PATHSPEC_PREFER_FULL,
+  prefix, argv);
 
-   read_cache_preload(s.pathspec);
-   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, 
NULL, NULL);
+   read_cache_preload(s.pathspec.raw);
+   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, 
s.pathspec.raw, NULL, NULL);
 
fd = hold_locked_index(index_lock, 0);
if (0 = fd)
diff --git a/wt-status.c b/wt-status.c
index 9c4d086..fae0c27 100644
--- a/wt-status.c
+++ b/wt-status.c
@@ -1,4 +1,5 @@
 #include cache.h
+#include pathspec.h
 #include wt-status.h
 #include object.h
 #include dir.h
@@ -438,7 +439,7 @@ static void wt_status_collect_changes_worktree(struct 
wt_status *s)
}
rev.diffopt.format_callback = wt_status_collect_changed_cb;
rev.diffopt.format_callback_data = s;
-   init_pathspec(rev.prune_data, s-pathspec);
+   copy_pathspec(rev.prune_data, s-pathspec);
run_diff_files(rev, 0);
 }
 
@@ -463,22 +464,20 @@ static void wt_status_collect_changes_index(struct 
wt_status *s)
rev.diffopt.detect_rename = 1;
rev.diffopt.rename_limit = 200;
rev.diffopt.break_opt = 0;
-   init_pathspec(rev.prune_data, s-pathspec);
+   copy_pathspec(rev.prune_data, s-pathspec);
run_diff_index(rev, 1);
 }
 
 static void wt_status_collect_changes_initial(struct wt_status *s)
 {
-   struct pathspec pathspec;
int i;
 
-   init_pathspec(pathspec, s-pathspec);
for (i = 0; i  active_nr; i++) {
struct string_list_item *it;
struct wt_status_change_data *d;
struct cache_entry *ce = active_cache[i];
 
-   if (!ce_path_match(ce, pathspec))
+   if (!ce_path_match(ce, s-pathspec))
continue;
it = string_list_insert(s-change, ce-name);
d = it-util;
@@ -493,7 +492,6 @@ static void wt_status_collect_changes_initial(struct 
wt_status *s)
else
d-index_status = DIFF_STATUS_ADDED;
}
-   free_pathspec(pathspec);
 }
 
 static void wt_status_collect_untracked(struct wt_status *s)
@@ -516,12 +514,12 @@ static void wt_status_collect_untracked(struct wt_status 
*s)
dir.flags |= DIR_SHOW_IGNORED_TOO;
setup_standard_excludes(dir);
 
-   fill_directory(dir, s-pathspec);
+   fill_directory(dir, s-pathspec.raw);
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec(s-pathspec, ent-name, ent-len, 0, NULL))
+   match_pathspec_depth(s-pathspec, ent-name, ent-len, 0, 
NULL))
string_list_insert(s-untracked, ent-name);
free(ent);
}
@@ -529,7 +527,7 @@ static void wt_status_collect_untracked(struct wt_status *s)
for (i = 0; i  dir.ignored_nr; i++) {
struct dir_entry *ent = dir.ignored[i];
if (cache_name_is_other(ent-name, ent-len) 
-   match_pathspec(s-pathspec, ent-name, ent-len, 0, NULL))
+   match_pathspec_depth(s-pathspec, ent-name, ent-len, 0, 
NULL))
string_list_insert(s-ignored, ent-name);
free(ent);
}
diff --git a/wt-status.h b/wt-status.h
index 4121bc2..8463672 100644
--- a/wt-status.h
+++ b/wt-status.h
@@ -44,7 +44,7 @@ struct wt_status {
int is_initial;
char *branch;
const char *reference;
-   const char **pathspec;
+   struct pathspec pathspec;
int verbose;
int amend;
enum commit_whence whence;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 17/46] rerere: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/rerere.c | 8 +---
 rerere.c | 9 +
 rerere.h | 4 +++-
 3 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/builtin/rerere.c b/builtin/rerere.c
index dc1708e..4e51add 100644
--- a/builtin/rerere.c
+++ b/builtin/rerere.c
@@ -6,6 +6,7 @@
 #include rerere.h
 #include xdiff/xdiff.h
 #include xdiff-interface.h
+#include pathspec.h
 
 static const char * const rerere_usage[] = {
N_(git rerere [clear | forget path... | status | remaining | diff | 
gc]),
@@ -68,11 +69,12 @@ int cmd_rerere(int argc, const char **argv, const char 
*prefix)
return rerere(flags);
 
if (!strcmp(argv[0], forget)) {
-   const char **pathspec;
+   struct pathspec pathspec;
if (argc  2)
warning('git rerere forget' without paths is 
deprecated);
-   pathspec = get_pathspec(prefix, argv + 1);
-   return rerere_forget(pathspec);
+   parse_pathspec(pathspec, 0, PATHSPEC_PREFER_CWD,
+  prefix, argv + 1);
+   return rerere_forget(pathspec);
}
 
fd = setup_rerere(merge_rr, flags);
diff --git a/rerere.c b/rerere.c
index 98e3e29..27afbfe 100644
--- a/rerere.c
+++ b/rerere.c
@@ -6,6 +6,7 @@
 #include resolve-undo.h
 #include ll-merge.h
 #include attr.h
+#include pathspec.h
 
 #define RESOLVED 0
 #define PUNTED 1
@@ -656,7 +657,7 @@ static int rerere_forget_one_path(const char *path, struct 
string_list *rr)
return 0;
 }
 
-int rerere_forget(const char **pathspec)
+int rerere_forget(struct pathspec *pathspec)
 {
int i, fd;
struct string_list conflict = STRING_LIST_INIT_DUP;
@@ -667,12 +668,12 @@ int rerere_forget(const char **pathspec)
 
fd = setup_rerere(merge_rr, RERERE_NOAUTOUPDATE);
 
-   unmerge_cache(pathspec);
+   unmerge_cache(pathspec-raw);
find_conflict(conflict);
for (i = 0; i  conflict.nr; i++) {
struct string_list_item *it = conflict.items[i];
-   if (!match_pathspec(pathspec, it-string, strlen(it-string),
-   0, NULL))
+   if (!match_pathspec_depth(pathspec, it-string, 
strlen(it-string),
+ 0, NULL))
continue;
rerere_forget_one_path(it-string, merge_rr);
}
diff --git a/rerere.h b/rerere.h
index 156d2aa..4aa06c9 100644
--- a/rerere.h
+++ b/rerere.h
@@ -3,6 +3,8 @@
 
 #include string-list.h
 
+struct pathspec;
+
 #define RERERE_AUTOUPDATE   01
 #define RERERE_NOAUTOUPDATE 02
 
@@ -16,7 +18,7 @@ extern void *RERERE_RESOLVED;
 extern int setup_rerere(struct string_list *, int);
 extern int rerere(int);
 extern const char *rerere_path(const char *hex, const char *file);
-extern int rerere_forget(const char **);
+extern int rerere_forget(struct pathspec *);
 extern int rerere_remaining(struct string_list *);
 extern void rerere_clear(struct string_list *);
 extern void rerere_gc(struct string_list *);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 20/46] ls-files: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/ls-files.c | 46 +-
 1 file changed, 13 insertions(+), 33 deletions(-)

diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 30357df..f1be425 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -31,7 +31,7 @@ static int debug_mode;
 static const char *prefix;
 static int max_prefix_len;
 static int prefix_len;
-static const char **pathspec;
+static struct pathspec pathspec;
 static int error_unmatch;
 static char *ps_matched;
 static const char *with_tree;
@@ -60,7 +60,7 @@ static void show_dir_entry(const char *tag, struct dir_entry 
*ent)
if (len = ent-len)
die(git ls-files: internal error - directory entry not 
superset of prefix);
 
-   if (!match_pathspec(pathspec, ent-name, ent-len, len, ps_matched))
+   if (!match_pathspec_depth(pathspec, ent-name, ent-len, len, 
ps_matched))
return;
 
fputs(tag, stdout);
@@ -135,7 +135,7 @@ static void show_ce_entry(const char *tag, struct 
cache_entry *ce)
if (len = ce_namelen(ce))
die(git ls-files: internal error - cache entry not superset of 
prefix);
 
-   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce), len, 
ps_matched))
+   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), len, 
ps_matched))
return;
 
if (tag  *tag  show_valid_bit 
@@ -191,7 +191,7 @@ static void show_ru_info(void)
len = strlen(path);
if (len  max_prefix_len)
continue; /* outside of the prefix */
-   if (!match_pathspec(pathspec, path, len, max_prefix_len, 
ps_matched))
+   if (!match_pathspec_depth(pathspec, path, len, max_prefix_len, 
ps_matched))
continue; /* uninterested */
for (i = 0; i  3; i++) {
if (!ui-mode[i])
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
 
/* For cached/deleted files we don't need to even do the readdir */
if (show_others || show_killed) {
-   fill_directory(dir, pathspec);
+   fill_directory(dir, pathspec.raw);
if (show_others)
show_other_files(dir);
if (show_killed)
@@ -284,21 +284,6 @@ static void prune_cache(const char *prefix)
active_nr = last;
 }
 
-static void strip_trailing_slash_from_submodules(void)
-{
-   const char **p;
-
-   for (p = pathspec; *p != NULL; p++) {
-   int len = strlen(*p), pos;
-
-   if (len  1 || (*p)[len - 1] != '/')
-   continue;
-   pos = cache_name_pos(*p, len - 1);
-   if (pos = 0  S_ISGITLINK(active_cache[pos]-ce_mode))
-   *p = xstrndup(*p, len - 1);
-   }
-}
-
 /*
  * Read the tree specified with --with-tree option
  * (typically, HEAD) into stage #1 and then
@@ -552,23 +537,18 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
if (require_work_tree  !is_inside_work_tree())
setup_work_tree();
 
-   pathspec = get_pathspec(prefix, argv);
-
-   /* be nice with submodule paths ending in a slash */
-   if (pathspec)
-   strip_trailing_slash_from_submodules();
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_CWD |
+  PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP,
+  prefix, argv);
 
/* Find common prefix for all pathspec's */
-   max_prefix = common_prefix(pathspec);
+   max_prefix = common_prefix(pathspec.raw);
max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
 
/* Treat unmatching pathspec elements as errors */
-   if (pathspec  error_unmatch) {
-   int num;
-   for (num = 0; pathspec[num]; num++)
-   ;
-   ps_matched = xcalloc(1, num);
-   }
+   if (pathspec.nr  error_unmatch)
+   ps_matched = xcalloc(1, pathspec.nr);
 
if ((dir.flags  DIR_SHOW_IGNORED)  !exc_given)
die(ls-files --ignored needs some exclude pattern);
@@ -595,7 +575,7 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
 
if (ps_matched) {
int bad;
-   bad = report_path_error(ps_matched, pathspec, prefix);
+   bad = report_path_error(ps_matched, pathspec.raw, prefix);
if (bad)
fprintf(stderr, Did you forget to 'git add'?\n);
 
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 22/46] check-ignore: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
check-ignore (at least the test suite) seems to rely on the pattern
order. PATHSPEC_KEEP_ORDER is introduced to explictly express this.
The lack of PATHSPEC_MAXDEPTH_VALID is sufficient because it's the
only flag that reorders pathspecs, but it's less obvious that way.

Cc: Adam Spiers g...@adamspiers.org
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/check-ignore.c | 35 ++-
 pathspec.c |  6 +-
 pathspec.h |  1 +
 t/t0008-ignores.sh |  8 
 4 files changed, 32 insertions(+), 18 deletions(-)

diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index 4a8fc70..d49c083 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -64,37 +64,45 @@ static void output_exclude(const char *path, struct exclude 
*exclude)
 }
 
 static int check_ignore(struct dir_struct *dir,
-   const char *prefix, const char **pathspec)
+   const char *prefix, int argc, const char **argv)
 {
-   const char *path, *full_path;
+   const char *full_path;
char *seen;
int num_ignored = 0, dtype = DT_UNKNOWN, i;
struct exclude *exclude;
+   struct pathspec pathspec;
 
-   if (!pathspec || !*pathspec) {
+   if (!argc) {
if (!quiet)
fprintf(stderr, no pathspec given.\n);
return 0;
}
 
/*
+* check-ignore just needs paths. Magic beyond :/ is really
+* irrelevant.
+*/
+   parse_pathspec(pathspec,
+  PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP,
+  PATHSPEC_SYMLINK_LEADING_PATH |
+  PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE |
+  PATHSPEC_KEEP_ORDER,
+  prefix, argv);
+
+   /*
 * look for pathspecs matching entries in the index, since these
 * should not be ignored, in order to be consistent with
 * 'git status', 'git add' etc.
 */
-   seen = find_pathspecs_matching_against_index(pathspec);
-   for (i = 0; pathspec[i]; i++) {
-   path = pathspec[i];
-   full_path = prefix_path(prefix, prefix
-   ? strlen(prefix) : 0, path);
-   full_path = check_path_for_gitlink(full_path);
-   die_if_path_beyond_symlink(full_path, prefix);
+   seen = find_pathspecs_matching_against_index(pathspec.raw);
+   for (i = 0; i  pathspec.nr; i++) {
+   full_path = pathspec.raw[i];
exclude = NULL;
if (!seen[i]) {
exclude = last_exclude_matching(dir, full_path, dtype);
}
if (!quiet  (exclude || show_non_matching))
-   output_exclude(path, exclude);
+   output_exclude(pathspec.items[i].original, exclude);
if (exclude)
num_ignored++;
}
@@ -120,7 +128,8 @@ static int check_ignore_stdin_paths(struct dir_struct *dir, 
const char *prefix)
strbuf_swap(buf, nbuf);
}
pathspec[0] = buf.buf;
-   num_ignored += check_ignore(dir, prefix, (const char 
**)pathspec);
+   num_ignored += check_ignore(dir, prefix,
+   1, (const char **)pathspec);
maybe_flush_or_die(stdout, check-ignore to stdout);
}
strbuf_release(buf);
@@ -166,7 +175,7 @@ int cmd_check_ignore(int argc, const char **argv, const 
char *prefix)
if (stdin_paths) {
num_ignored = check_ignore_stdin_paths(dir, prefix);
} else {
-   num_ignored = check_ignore(dir, prefix, argv);
+   num_ignored = check_ignore(dir, prefix, argc, argv);
maybe_flush_or_die(stdout, ignore to stdout);
}
 
diff --git a/pathspec.c b/pathspec.c
index ba6408a..5c9631a 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -370,9 +370,13 @@ void parse_pathspec(struct pathspec *pathspec,
pathspec-magic |= item[i].magic;
}
 
-   if (pathspec-magic  PATHSPEC_MAXDEPTH)
+
+   if (pathspec-magic  PATHSPEC_MAXDEPTH) {
+   if (flags  PATHSPEC_KEEP_ORDER)
+   die(BUG: PATHSPEC_MAXDEPTH_VALID and 
PATHSPEC_KEEP_ORDER are incompatible);
qsort(pathspec-items, pathspec-nr,
  sizeof(struct pathspec_item), pathspec_item_cmp);
+   }
 }
 
 /*
diff --git a/pathspec.h b/pathspec.h
index 6baf205..02dded3 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -51,6 +51,7 @@ struct pathspec {
  */
 #define PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE (15)
 #define PATHSPEC_PREFIX_ORIGIN (16)
+#define PATHSPEC_KEEP_ORDER (17)
 
 extern int init_pathspec(struct pathspec *, const char **);
 extern void parse_pathspec(struct pathspec *pathspec,
diff --git a/t/t0008-ignores.sh 

[PATCH v2 15/46] commit: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c | 18 +-
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 790e5ab..530f0ed 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -284,17 +284,17 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 {
int fd;
struct string_list partial;
-   const char **pathspec = NULL;
+   struct pathspec pathspec;
char *old_index_env = NULL;
int refresh_flags = REFRESH_QUIET;
 
if (is_status)
refresh_flags |= REFRESH_UNMERGED;
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_FULL,
+  prefix, argv);
 
-   if (*argv)
-   pathspec = get_pathspec(prefix, argv);
-
-   if (read_cache_preload(pathspec)  0)
+   if (read_cache_preload(pathspec.raw)  0)
die(_(index file corrupt));
 
if (interactive) {
@@ -336,9 +336,9 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 * (A) if all goes well, commit the real index;
 * (B) on failure, rollback the real index.
 */
-   if (all || (also  pathspec  *pathspec)) {
+   if (all || (also  pathspec.nr)) {
fd = hold_locked_index(index_lock, 1);
-   add_files_to_cache(also ? prefix : NULL, pathspec, 0);
+   add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_cache(fd, active_cache, active_nr) ||
@@ -357,7 +357,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 * and create commit from the_index.
 * We still need to refresh the index here.
 */
-   if (!only  (!pathspec || !*pathspec)) {
+   if (!only  !pathspec.nr) {
fd = hold_locked_index(index_lock, 1);
refresh_cache_or_die(refresh_flags);
if (active_cache_changed) {
@@ -402,7 +402,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 
memset(partial, 0, sizeof(partial));
partial.strdup_strings = 1;
-   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec))
+   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec.raw))
exit(1);
 
discard_cache();
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 18/46] checkout: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 34 +-
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 7fe0bff..6721de2 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -46,7 +46,7 @@ struct checkout_opts {
 
int branch_exists;
const char *prefix;
-   const char **pathspec;
+   struct pathspec pathspec;
struct tree *source_tree;
 };
 
@@ -257,20 +257,18 @@ static int checkout_paths(const struct checkout_opts 
*opts,
 
if (opts-patch_mode)
return run_add_interactive(revision, --patch=checkout,
-  opts-pathspec);
+  opts-pathspec.raw);
 
lock_file = xcalloc(1, sizeof(struct lock_file));
 
newfd = hold_locked_index(lock_file, 1);
-   if (read_cache_preload(opts-pathspec)  0)
+   if (read_cache_preload(opts-pathspec.raw)  0)
return error(_(corrupt index file));
 
if (opts-source_tree)
-   read_tree_some(opts-source_tree, opts-pathspec);
+   read_tree_some(opts-source_tree, opts-pathspec.raw);
 
-   for (pos = 0; opts-pathspec[pos]; pos++)
-   ;
-   ps_matched = xcalloc(1, pos);
+   ps_matched = xcalloc(1, opts-pathspec.nr);
 
/*
 * Make sure all pathspecs participated in locating the paths
@@ -304,12 +302,12 @@ static int checkout_paths(const struct checkout_opts 
*opts,
 * match_pathspec() for _all_ entries when
 * opts-source_tree != NULL.
 */
-   if (match_pathspec(opts-pathspec, ce-name, ce_namelen(ce),
+   if (match_pathspec_depth(opts-pathspec, ce-name, 
ce_namelen(ce),
   0, ps_matched))
ce-ce_flags |= CE_MATCHED;
}
 
-   if (report_path_error(ps_matched, opts-pathspec, opts-prefix)) {
+   if (report_path_error(ps_matched, opts-pathspec.raw, opts-prefix)) {
free(ps_matched);
return 1;
}
@@ -1002,7 +1000,7 @@ static int switch_unborn_to_new_branch(const struct 
checkout_opts *opts)
 static int checkout_branch(struct checkout_opts *opts,
   struct branch_info *new)
 {
-   if (opts-pathspec)
+   if (opts-pathspec.nr)
die(_(paths cannot be used with switching branches));
 
if (opts-patch_mode)
@@ -1154,9 +1152,19 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
}
 
if (argc) {
-   opts.pathspec = get_pathspec(prefix, argv);
+   /*
+* In patch mode (opts.patch_mode != 0), we pass the
+* pathspec to an external program, git-add--interactive.
+* Do not accept any kind of magic that that program
+* cannot handle. Magic mask is pretty safe to be
+* lifted for new magic when opts.patch_mode == 0.
+*/
+   parse_pathspec(opts.pathspec,
+  opts.patch_mode == 0 ? 0 :
+  (PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP),
+  0, prefix, argv);
 
-   if (!opts.pathspec)
+   if (!opts.pathspec.nr)
die(_(invalid path specification));
 
/*
@@ -1188,7 +1196,7 @@ int cmd_checkout(int argc, const char **argv, const char 
*prefix)
strbuf_release(buf);
}
 
-   if (opts.patch_mode || opts.pathspec)
+   if (opts.patch_mode || opts.pathspec.nr)
return checkout_paths(opts, new.name);
else
return checkout_branch(opts, new);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 31/46] Convert refresh_index to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c| 15 +++
 builtin/commit.c |  2 +-
 builtin/rm.c |  2 +-
 cache.h  |  2 +-
 read-cache.c |  5 +++--
 5 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index d039fc9..f5d6a33 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -226,19 +226,18 @@ static char *prune_directory(struct dir_struct *dir, 
const char **pathspec,
return seen;
 }
 
-static void refresh(int verbose, const char **pathspec)
+static void refresh(int verbose, const struct pathspec *pathspec)
 {
char *seen;
-   int i, specs;
+   int i;
 
-   for (specs = 0; pathspec[specs];  specs++)
-   /* nothing */;
-   seen = xcalloc(specs, 1);
+   seen = xcalloc(pathspec-nr, 1);
refresh_index(the_index, verbose ? REFRESH_IN_PORCELAIN : 
REFRESH_QUIET,
  pathspec, seen, _(Unstaged changes after refreshing the 
index:));
-   for (i = 0; i  specs; i++) {
+   for (i = 0; i  pathspec-nr; i++) {
if (!seen[i])
-   die(_(pathspec '%s' did not match any files), 
pathspec[i]);
+   die(_(pathspec '%s' did not match any files),
+   pathspec-items[i].match);
}
 free(seen);
 }
@@ -524,7 +523,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
}
 
if (refresh_only) {
-   refresh(verbose, pathspec.raw);
+   refresh(verbose, pathspec);
goto finish;
}
if (implicit_dot  prefix)
diff --git a/builtin/commit.c b/builtin/commit.c
index eaecf7c..d34baab 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -1244,7 +1244,7 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
   prefix, argv);
 
read_cache_preload(s.pathspec);
-   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, 
s.pathspec.raw, NULL, NULL);
+   refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, s.pathspec, 
NULL, NULL);
 
fd = hold_locked_index(index_lock, 0);
if (0 = fd)
diff --git a/builtin/rm.c b/builtin/rm.c
index ee0ae4c..f08561d 100644
--- a/builtin/rm.c
+++ b/builtin/rm.c
@@ -314,7 +314,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix)
}
 
parse_pathspec(pathspec, 0, PATHSPEC_PREFER_CWD, prefix, argv);
-   refresh_index(the_index, REFRESH_QUIET, pathspec.raw, NULL, NULL);
+   refresh_index(the_index, REFRESH_QUIET, pathspec, NULL, NULL);
 
seen = NULL;
seen = xcalloc(pathspec.nr, 1);
diff --git a/cache.h b/cache.h
index 42c9920..b294277 100644
--- a/cache.h
+++ b/cache.h
@@ -520,7 +520,7 @@ extern void fill_stat_cache_info(struct cache_entry *ce, 
struct stat *st);
 #define REFRESH_IGNORE_MISSING 0x0008  /* ignore non-existent */
 #define REFRESH_IGNORE_SUBMODULES  0x0010  /* ignore submodules */
 #define REFRESH_IN_PORCELAIN   0x0020  /* user friendly output, not needs 
update */
-extern int refresh_index(struct index_state *, unsigned int flags, const char 
**pathspec, char *seen, const char *header_msg);
+extern int refresh_index(struct index_state *, unsigned int flags, const 
struct pathspec *pathspec, char *seen, const char *header_msg);
 
 struct lock_file {
struct lock_file *next;
diff --git a/read-cache.c b/read-cache.c
index d5201f9..6ad2ff6 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1114,7 +1114,8 @@ static void show_file(const char * fmt, const char * 
name, int in_porcelain,
printf(fmt, name);
 }
 
-int refresh_index(struct index_state *istate, unsigned int flags, const char 
**pathspec,
+int refresh_index(struct index_state *istate, unsigned int flags,
+ const struct pathspec *pathspec,
  char *seen, const char *header_msg)
 {
int i;
@@ -1149,7 +1150,7 @@ int refresh_index(struct index_state *istate, unsigned 
int flags, const char **p
continue;
 
if (pathspec 
-   !match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, 
seen))
+   !match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, seen))
filtered = 1;
 
if (ce_stage(ce)) {
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 32/46] Convert {read,fill}_directory to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  |  4 +++-
 builtin/clean.c|  2 +-
 builtin/grep.c |  2 +-
 builtin/ls-files.c |  2 +-
 dir.c  | 16 +++-
 dir.h  |  4 ++--
 wt-status.c|  2 +-
 7 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index f5d6a33..34c9358 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -507,6 +507,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 
if (add_new_files) {
int baselen;
+   struct pathspec empty_pathspec;
 
/* Set up the default git porcelain excludes */
memset(dir, 0, sizeof(dir));
@@ -515,8 +516,9 @@ int cmd_add(int argc, const char **argv, const char *prefix)
setup_standard_excludes(dir);
}
 
+   memset(empty_pathspec, 0, sizeof(empty_pathspec));
/* This picks up the paths that are not tracked */
-   baselen = fill_directory(dir, implicit_dot ? NULL : 
pathspec.raw);
+   baselen = fill_directory(dir, implicit_dot ? empty_pathspec : 
pathspec);
if (pathspec.nr)
seen = prune_directory(dir, pathspec.raw, baselen,
implicit_dot ? WARN_IMPLICIT_DOT : 0);
diff --git a/builtin/clean.c b/builtin/clean.c
index fdd4980..d540ca4 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -214,7 +214,7 @@ int cmd_clean(int argc, const char **argv, const char 
*prefix)
   PATHSPEC_PREFER_CWD,
   prefix, argv);
 
-   fill_directory(dir, pathspec.raw);
+   fill_directory(dir, pathspec);
 
for (i = 0; i  dir.nr; i++) {
struct dir_entry *ent = dir.entries[i];
diff --git a/builtin/grep.c b/builtin/grep.c
index 4bc0754..76a6a60 100644
--- a/builtin/grep.c
+++ b/builtin/grep.c
@@ -523,7 +523,7 @@ static int grep_directory(struct grep_opt *opt, const 
struct pathspec *pathspec,
if (exc_std)
setup_standard_excludes(dir);
 
-   fill_directory(dir, pathspec-raw);
+   fill_directory(dir, pathspec);
for (i = 0; i  dir.nr; i++) {
const char *name = dir.entries[i]-name;
int namelen = strlen(name);
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 50e6edf..fa1a6be 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -216,7 +216,7 @@ static void show_files(struct dir_struct *dir)
 
/* For cached/deleted files we don't need to even do the readdir */
if (show_others || show_killed) {
-   fill_directory(dir, pathspec.raw);
+   fill_directory(dir, pathspec);
if (show_others)
show_other_files(dir);
if (show_killed)
diff --git a/dir.c b/dir.c
index 19978d3..290c7a3 100644
--- a/dir.c
+++ b/dir.c
@@ -142,7 +142,7 @@ char *common_prefix(const char **pathspec)
return len ? xmemdupz(*pathspec, len) : NULL;
 }
 
-int fill_directory(struct dir_struct *dir, const char **pathspec)
+int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
 {
size_t len;
 
@@ -150,10 +150,10 @@ int fill_directory(struct dir_struct *dir, const char 
**pathspec)
 * Calculate common prefix for the pathspec, and
 * use that to optimize the directory walk
 */
-   len = common_prefix_len(pathspec);
+   len = common_prefix_len(pathspec-raw);
 
/* Read the directory and prune it */
-   read_directory(dir, pathspec ? *pathspec : , len, pathspec);
+   read_directory(dir, pathspec-nr ? pathspec-raw[0] : , len, 
pathspec);
return len;
 }
 
@@ -1388,14 +1388,20 @@ static int treat_leading_path(struct dir_struct *dir,
return rc;
 }
 
-int read_directory(struct dir_struct *dir, const char *path, int len, const 
char **pathspec)
+int read_directory(struct dir_struct *dir, const char *path, int len, const 
struct pathspec *pathspec)
 {
struct path_simplify *simplify;
 
+   /*
+* Check out create_simplify()
+*/
+   if (pathspec)
+   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
if (has_symlink_leading_path(path, len))
return dir-nr;
 
-   simplify = create_simplify(pathspec);
+   simplify = create_simplify(pathspec ? pathspec-raw : NULL);
if (!len || treat_leading_path(dir, path, len, simplify))
read_directory_recursive(dir, path, len, 0, simplify);
free_simplify(simplify);
diff --git a/dir.h b/dir.h
index 229ccc8..076dd96 100644
--- a/dir.h
+++ b/dir.h
@@ -137,8 +137,8 @@ extern int match_pathspec_depth(const struct pathspec 
*pathspec,
int prefix, char *seen);
 extern int within_depth(const char *name, int namelen, int depth, int 
max_depth);
 
-extern int 

[PATCH v2 27/46] Convert run_add_interactive to use struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
This passes the pathspec, more or less unmodified, to
git-add--interactive. The command itself does not process pathspec. It
simply passes the pathspec to other builtin commands. So if all those
commands support pathspec, we're good.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  | 26 ++
 builtin/checkout.c |  9 -
 builtin/reset.c|  8 
 commit.h   |  2 +-
 4 files changed, 19 insertions(+), 26 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 9a7235e..d039fc9 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -244,16 +244,12 @@ static void refresh(int verbose, const char **pathspec)
 }
 
 int run_add_interactive(const char *revision, const char *patch_mode,
-   const char **pathspec)
+   const struct pathspec *pathspec)
 {
-   int status, ac, pc = 0;
+   int status, ac, i;
const char **args;
 
-   if (pathspec)
-   while (pathspec[pc])
-   pc++;
-
-   args = xcalloc(sizeof(const char *), (pc + 5));
+   args = xcalloc(sizeof(const char *), (pathspec-nr + 6));
ac = 0;
args[ac++] = add--interactive;
if (patch_mode)
@@ -261,11 +257,9 @@ int run_add_interactive(const char *revision, const char 
*patch_mode,
if (revision)
args[ac++] = revision;
args[ac++] = --;
-   if (pc) {
-   memcpy((args[ac]), pathspec, sizeof(const char *) * pc);
-   ac += pc;
-   }
-   args[ac] = NULL;
+   for (i = 0; i  pathspec-nr; i++)
+   /* pass original pathspec, to be re-parsed */
+   args[ac++] = pathspec-items[i].original;
 
status = run_command_v_opt(args, RUN_GIT_CMD);
free(args);
@@ -280,17 +274,17 @@ int interactive_add(int argc, const char **argv, const 
char *prefix, int patch)
 * git-add--interactive itself does not parse pathspec. It
 * simply passes the pathspec to other builtin commands. Let's
 * hope all of them support all magic, or we'll need to limit
-* the magic here. There is still a problem with prefix. But
-* that'll be worked on later on.
+* the magic here.
 */
parse_pathspec(pathspec, PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP,
   PATHSPEC_PREFER_FULL |
-  PATHSPEC_SYMLINK_LEADING_PATH,
+  PATHSPEC_SYMLINK_LEADING_PATH |
+  PATHSPEC_PREFIX_ORIGIN,
   prefix, argv);
 
return run_add_interactive(NULL,
   patch ? --patch : NULL,
-  pathspec.raw);
+  pathspec);
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
diff --git a/builtin/checkout.c b/builtin/checkout.c
index 2f0fb8d..5d31767 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -257,7 +257,7 @@ static int checkout_paths(const struct checkout_opts *opts,
 
if (opts-patch_mode)
return run_add_interactive(revision, --patch=checkout,
-  opts-pathspec.raw);
+  opts-pathspec);
 
lock_file = xcalloc(1, sizeof(struct lock_file));
 
@@ -1159,10 +1159,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,
-  opts.patch_mode == 0 ? 0 :
-  (PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP),
-  0, prefix, argv);
+   parse_pathspec(opts.pathspec, 0,
+  opts.patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0,
+  prefix, argv);
 
if (!opts.pathspec.nr)
die(_(invalid path specification));
diff --git a/builtin/reset.c b/builtin/reset.c
index 313b296..9bef869 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -219,9 +219,9 @@ static void parse_args(struct pathspec *pathspec,
}
}
*rev_ret = rev;
-   parse_pathspec(pathspec,
-  patch_mode ? PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP : 0,
-  PATHSPEC_PREFER_FULL,
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_FULL |
+  (patch_mode ? PATHSPEC_PREFIX_ORIGIN : 0),
   prefix, argv);
 }
 
@@ -299,7 +299,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (patch_mode) {
if (reset_type != NONE)
die(_(--patch is incompatible with 
--{hard,mixed,soft}));
-   return run_add_interactive(sha1_to_hex(sha1), 

[PATCH v2 24/46] reset: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/reset.c | 26 --
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/builtin/reset.c b/builtin/reset.c
index afa6e02..313b296 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -174,7 +174,10 @@ static void die_if_unmerged_cache(int reset_type)
 
 }
 
-static const char **parse_args(const char **argv, const char *prefix, const 
char **rev_ret)
+static void parse_args(struct pathspec *pathspec,
+  const char **argv, const char *prefix,
+  int patch_mode,
+  const char **rev_ret)
 {
const char *rev = HEAD;
unsigned char unused[20];
@@ -216,7 +219,10 @@ static const char **parse_args(const char **argv, const 
char *prefix, const char
}
}
*rev_ret = rev;
-   return argv[0] ? get_pathspec(prefix, argv) : NULL;
+   parse_pathspec(pathspec,
+  patch_mode ? PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP : 0,
+  PATHSPEC_PREFER_FULL,
+  prefix, argv);
 }
 
 static int update_refs(const char *rev, const unsigned char *sha1)
@@ -246,7 +252,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
int patch_mode = 0, unborn;
const char *rev;
unsigned char sha1[20];
-   const char **pathspec = NULL;
+   struct pathspec pathspec;
const struct option options[] = {
OPT__QUIET(quiet, N_(be quiet, only report errors)),
OPT_SET_INT(0, mixed, reset_type,
@@ -266,13 +272,13 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
 
argc = parse_options(argc, argv, prefix, options, git_reset_usage,
PARSE_OPT_KEEP_DASHDASH);
-   pathspec = parse_args(argv, prefix, rev);
+   parse_args(pathspec, argv, prefix, patch_mode, rev);
 
unborn = !strcmp(rev, HEAD)  get_sha1(HEAD, sha1);
if (unborn) {
/* reset on unborn branch: treat as reset to empty tree */
hashcpy(sha1, EMPTY_TREE_SHA1_BIN);
-   } else if (!pathspec) {
+   } else if (!pathspec.nr) {
struct commit *commit;
if (get_sha1_committish(rev, sha1))
die(_(Failed to resolve '%s' as a valid revision.), 
rev);
@@ -293,13 +299,13 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (patch_mode) {
if (reset_type != NONE)
die(_(--patch is incompatible with 
--{hard,mixed,soft}));
-   return run_add_interactive(sha1_to_hex(sha1), --patch=reset, 
pathspec);
+   return run_add_interactive(sha1_to_hex(sha1), --patch=reset, 
pathspec.raw);
}
 
/* git reset tree [--] paths... can be used to
 * load chosen paths from the tree into the index without
 * affecting the working tree nor HEAD. */
-   if (pathspec) {
+   if (pathspec.nr) {
if (reset_type == MIXED)
warning(_(--mixed with paths is deprecated; use 'git 
reset -- paths' instead.));
else if (reset_type != NONE)
@@ -326,7 +332,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int newfd = hold_locked_index(lock, 1);
if (reset_type == MIXED) {
-   if (read_from_tree(pathspec, sha1))
+   if (read_from_tree(pathspec.raw, sha1))
return 1;
} else {
int err = reset_index(sha1, reset_type, quiet);
@@ -347,7 +353,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
die(_(Could not write new index file.));
}
 
-   if (!pathspec  !unborn) {
+   if (!pathspec.nr  !unborn) {
/* Any resets without paths update HEAD to the head being
 * switched to, saving the previous head in ORIG_HEAD before. */
update_ref_status = update_refs(rev, sha1);
@@ -355,7 +361,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
if (reset_type == HARD  !update_ref_status  !quiet)
print_new_head_line(lookup_commit_reference(sha1));
}
-   if (!pathspec)
+   if (!pathspec.nr)
remove_branch_state();
 
return update_ref_status;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 26/46] Convert read_cache_preload() to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c   |  2 +-
 builtin/commit.c |  4 ++--
 builtin/diff-files.c |  2 +-
 builtin/diff-index.c |  2 +-
 builtin/diff.c   |  4 ++--
 cache.h  |  2 +-
 preload-index.c  | 20 +++-
 7 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 6721de2..2f0fb8d 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -262,7 +262,7 @@ static int checkout_paths(const struct checkout_opts *opts,
lock_file = xcalloc(1, sizeof(struct lock_file));
 
newfd = hold_locked_index(lock_file, 1);
-   if (read_cache_preload(opts-pathspec.raw)  0)
+   if (read_cache_preload(opts-pathspec)  0)
return error(_(corrupt index file));
 
if (opts-source_tree)
diff --git a/builtin/commit.c b/builtin/commit.c
index 64d1a3d..0344ec7 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -294,7 +294,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
   PATHSPEC_PREFER_FULL,
   prefix, argv);
 
-   if (read_cache_preload(pathspec.raw)  0)
+   if (read_cache_preload(pathspec)  0)
die(_(index file corrupt));
 
if (interactive) {
@@ -1245,7 +1245,7 @@ int cmd_status(int argc, const char **argv, const char 
*prefix)
   PATHSPEC_PREFER_FULL,
   prefix, argv);
 
-   read_cache_preload(s.pathspec.raw);
+   read_cache_preload(s.pathspec);
refresh_index(the_index, REFRESH_QUIET|REFRESH_UNMERGED, 
s.pathspec.raw, NULL, NULL);
 
fd = hold_locked_index(index_lock, 0);
diff --git a/builtin/diff-files.c b/builtin/diff-files.c
index 46085f8..9200069 100644
--- a/builtin/diff-files.c
+++ b/builtin/diff-files.c
@@ -61,7 +61,7 @@ int cmd_diff_files(int argc, const char **argv, const char 
*prefix)
(rev.diffopt.output_format  DIFF_FORMAT_PATCH))
rev.combine_merges = rev.dense_combined_merges = 1;
 
-   if (read_cache_preload(rev.diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(rev.diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/builtin/diff-index.c b/builtin/diff-index.c
index 1c737f7..ce15b23 100644
--- a/builtin/diff-index.c
+++ b/builtin/diff-index.c
@@ -43,7 +43,7 @@ int cmd_diff_index(int argc, const char **argv, const char 
*prefix)
usage(diff_cache_usage);
if (!cached) {
setup_work_tree();
-   if (read_cache_preload(rev.diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(rev.diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/builtin/diff.c b/builtin/diff.c
index 6bb41af..bb84ba0 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -140,7 +140,7 @@ static int builtin_diff_index(struct rev_info *revs,
usage(builtin_diff_usage);
if (!cached) {
setup_work_tree();
-   if (read_cache_preload(revs-diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(revs-diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
@@ -242,7 +242,7 @@ static int builtin_diff_files(struct rev_info *revs, int 
argc, const char **argv
revs-combine_merges = revs-dense_combined_merges = 1;
 
setup_work_tree();
-   if (read_cache_preload(revs-diffopt.pathspec.raw)  0) {
+   if (read_cache_preload(revs-diffopt.pathspec)  0) {
perror(read_cache_preload);
return -1;
}
diff --git a/cache.h b/cache.h
index fd0a6f8..0370546 100644
--- a/cache.h
+++ b/cache.h
@@ -449,7 +449,7 @@ extern int init_db(const char *template_dir, unsigned int 
flags);
 
 /* Initialize and use the cache information */
 extern int read_index(struct index_state *);
-extern int read_index_preload(struct index_state *, const char **pathspec);
+extern int read_index_preload(struct index_state *, const struct pathspec 
*pathspec);
 extern int read_index_from(struct index_state *, const char *path);
 extern int is_index_unborn(struct index_state *);
 extern int read_index_unmerged(struct index_state *);
diff --git a/preload-index.c b/preload-index.c
index cddfffa..8c44ceb 100644
--- a/preload-index.c
+++ b/preload-index.c
@@ -5,7 +5,8 @@
 #include pathspec.h
 
 #ifdef NO_PTHREADS
-static void preload_index(struct index_state *index, const char **pathspec)
+static void preload_index(struct index_state *index,
+ const struct pathspec *pathspec)
 {
; /* nothing */
 }
@@ -25,7 +26,7 @@ static void preload_index(struct index_state *index, const 
char **pathspec)
 struct thread_data {
pthread_t pthread;
struct index_state *index;
- 

[PATCH v2 23/46] add: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c | 103 +-
 pathspec.c|  43 
 2 files changed, 45 insertions(+), 101 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index f45d9d4..9a7235e 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -226,21 +226,6 @@ static char *prune_directory(struct dir_struct *dir, const 
char **pathspec,
return seen;
 }
 
-/*
- * Checks the index to see whether any path in pathspec refers to
- * something inside a submodule.  If so, dies with an error message.
- */
-static void treat_gitlinks(const char **pathspec)
-{
-   int i;
-
-   if (!pathspec || !*pathspec)
-   return;
-
-   for (i = 0; pathspec[i]; i++)
-   pathspec[i] = check_path_for_gitlink(pathspec[i]);
-}
-
 static void refresh(int verbose, const char **pathspec)
 {
char *seen;
@@ -258,25 +243,6 @@ static void refresh(int verbose, const char **pathspec)
 free(seen);
 }
 
-/*
- * Normalizes argv relative to prefix, via get_pathspec(), and then
- * runs die_if_path_beyond_symlink() on each path in the normalized
- * list.
- */
-static const char **validate_pathspec(const char **argv, const char *prefix)
-{
-   const char **pathspec = get_pathspec(prefix, argv);
-
-   if (pathspec) {
-   const char **p;
-   for (p = pathspec; *p; p++) {
-   die_if_path_beyond_symlink(*p, prefix);
-   }
-   }
-
-   return pathspec;
-}
-
 int run_add_interactive(const char *revision, const char *patch_mode,
const char **pathspec)
 {
@@ -308,17 +274,23 @@ int run_add_interactive(const char *revision, const char 
*patch_mode,
 
 int interactive_add(int argc, const char **argv, const char *prefix, int patch)
 {
-   const char **pathspec = NULL;
+   struct pathspec pathspec;
 
-   if (argc) {
-   pathspec = validate_pathspec(argv, prefix);
-   if (!pathspec)
-   return -1;
-   }
+   /*
+* git-add--interactive itself does not parse pathspec. It
+* simply passes the pathspec to other builtin commands. Let's
+* hope all of them support all magic, or we'll need to limit
+* the magic here. There is still a problem with prefix. But
+* that'll be worked on later on.
+*/
+   parse_pathspec(pathspec, PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP,
+  PATHSPEC_PREFER_FULL |
+  PATHSPEC_SYMLINK_LEADING_PATH,
+  prefix, argv);
 
return run_add_interactive(NULL,
   patch ? --patch : NULL,
-  pathspec);
+  pathspec.raw);
 }
 
 static int edit_patch(int argc, const char **argv, const char *prefix)
@@ -445,7 +417,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 {
int exit_status = 0;
int newfd;
-   const char **pathspec;
+   struct pathspec pathspec;
struct dir_struct dir;
int flags;
int add_new_files;
@@ -526,11 +498,19 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
fprintf(stderr, _(Maybe you wanted to say 'git add .'?\n));
return 0;
}
-   pathspec = validate_pathspec(argv, prefix);
 
if (read_cache()  0)
die(_(index file corrupt));
-   treat_gitlinks(pathspec);
+
+   /*
+* Check the pathspec '%s' did not match any files block
+* below before enabling new magic.
+*/
+   parse_pathspec(pathspec, 0,
+  PATHSPEC_PREFER_FULL |
+  PATHSPEC_SYMLINK_LEADING_PATH |
+  PATHSPEC_STRIP_SUBMODULE_SLASH_EXPENSIVE,
+  prefix, argv);
 
if (add_new_files) {
int baselen;
@@ -543,34 +523,40 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
}
 
/* This picks up the paths that are not tracked */
-   baselen = fill_directory(dir, implicit_dot ? NULL : pathspec);
-   if (pathspec)
-   seen = prune_directory(dir, pathspec, baselen,
+   baselen = fill_directory(dir, implicit_dot ? NULL : 
pathspec.raw);
+   if (pathspec.nr)
+   seen = prune_directory(dir, pathspec.raw, baselen,
implicit_dot ? WARN_IMPLICIT_DOT : 0);
}
 
if (refresh_only) {
-   refresh(verbose, pathspec);
+   refresh(verbose, pathspec.raw);
goto finish;
}
if (implicit_dot  prefix)
refresh_cache(REFRESH_QUIET);
 
-   if (pathspec) {
+   if (pathspec.nr) {
int i;
 
if (!seen)
-   

[PATCH v2 29/46] checkout: convert read_tree_some to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c | 9 +++--
 tree.c | 4 ++--
 tree.h | 2 +-
 3 files changed, 6 insertions(+), 9 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index 5d31767..c2f3571 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -83,12 +83,9 @@ static int update_some(const unsigned char *sha1, const char 
*base, int baselen,
return 0;
 }
 
-static int read_tree_some(struct tree *tree, const char **pathspec)
+static int read_tree_some(struct tree *tree, const struct pathspec *pathspec)
 {
-   struct pathspec ps;
-   init_pathspec(ps, pathspec);
-   read_tree_recursive(tree, , 0, 0, ps, update_some, NULL);
-   free_pathspec(ps);
+   read_tree_recursive(tree, , 0, 0, pathspec, update_some, NULL);
 
/* update the index with the given tree's info
 * for all args, expanding wildcards, and exit
@@ -266,7 +263,7 @@ static int checkout_paths(const struct checkout_opts *opts,
return error(_(corrupt index file));
 
if (opts-source_tree)
-   read_tree_some(opts-source_tree, opts-pathspec.raw);
+   read_tree_some(opts-source_tree, opts-pathspec);
 
ps_matched = xcalloc(1, opts-pathspec.nr);
 
diff --git a/tree.c b/tree.c
index 62fed63..ff72f67 100644
--- a/tree.c
+++ b/tree.c
@@ -47,7 +47,7 @@ static int read_one_entry_quick(const unsigned char *sha1, 
const char *base, int
 }
 
 static int read_tree_1(struct tree *tree, struct strbuf *base,
-  int stage, struct pathspec *pathspec,
+  int stage, const struct pathspec *pathspec,
   read_tree_fn_t fn, void *context)
 {
struct tree_desc desc;
@@ -116,7 +116,7 @@ static int read_tree_1(struct tree *tree, struct strbuf 
*base,
 
 int read_tree_recursive(struct tree *tree,
const char *base, int baselen,
-   int stage, struct pathspec *pathspec,
+   int stage, const struct pathspec *pathspec,
read_tree_fn_t fn, void *context)
 {
struct strbuf sb = STRBUF_INIT;
diff --git a/tree.h b/tree.h
index 69bcb5e..9dc90ba 100644
--- a/tree.h
+++ b/tree.h
@@ -25,7 +25,7 @@ typedef int (*read_tree_fn_t)(const unsigned char *, const 
char *, int, const ch
 
 extern int read_tree_recursive(struct tree *tree,
   const char *base, int baselen,
-  int stage, struct pathspec *pathspec,
+  int stage, const struct pathspec *pathspec,
   read_tree_fn_t fn, void *context);
 
 extern int read_tree(struct tree *tree, int stage, struct pathspec *pathspec);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 28/46] Convert unmerge_cache to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 rerere.c   | 2 +-
 resolve-undo.c | 4 ++--
 resolve-undo.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/rerere.c b/rerere.c
index 27afbfe..4105bca 100644
--- a/rerere.c
+++ b/rerere.c
@@ -668,7 +668,7 @@ int rerere_forget(struct pathspec *pathspec)
 
fd = setup_rerere(merge_rr, RERERE_NOAUTOUPDATE);
 
-   unmerge_cache(pathspec-raw);
+   unmerge_cache(pathspec);
find_conflict(conflict);
for (i = 0; i  conflict.nr; i++) {
struct string_list_item *it = conflict.items[i];
diff --git a/resolve-undo.c b/resolve-undo.c
index 639eb9c..4b78e6f 100644
--- a/resolve-undo.c
+++ b/resolve-undo.c
@@ -173,7 +173,7 @@ void unmerge_marked_index(struct index_state *istate)
}
 }
 
-void unmerge_index(struct index_state *istate, const char **pathspec)
+void unmerge_index(struct index_state *istate, const struct pathspec *pathspec)
 {
int i;
 
@@ -182,7 +182,7 @@ void unmerge_index(struct index_state *istate, const char 
**pathspec)
 
for (i = 0; i  istate-cache_nr; i++) {
struct cache_entry *ce = istate-cache[i];
-   if (!match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, 
NULL))
+   if (!match_pathspec_depth(pathspec, ce-name, ce_namelen(ce), 
0, NULL))
continue;
i = unmerge_index_entry_at(istate, i);
}
diff --git a/resolve-undo.h b/resolve-undo.h
index 7a30206..4630645 100644
--- a/resolve-undo.h
+++ b/resolve-undo.h
@@ -11,7 +11,7 @@ extern void resolve_undo_write(struct strbuf *, struct 
string_list *);
 extern struct string_list *resolve_undo_read(const char *, unsigned long);
 extern void resolve_undo_clear_index(struct index_state *);
 extern int unmerge_index_entry_at(struct index_state *, int);
-extern void unmerge_index(struct index_state *, const char **);
+extern void unmerge_index(struct index_state *, const struct pathspec *);
 extern void unmerge_marked_index(struct index_state *);
 
 #endif
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 25/46] line-log: convert to use parse_pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 line-log.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/line-log.c b/line-log.c
index 4bbb09b..843a334 100644
--- a/line-log.c
+++ b/line-log.c
@@ -747,7 +747,7 @@ void line_log_init(struct rev_info *rev, const char 
*prefix, struct string_list
r = r-next;
}
paths[count] = NULL;
-   init_pathspec(rev-diffopt.pathspec, paths);
+   parse_pathspec(rev-diffopt.pathspec, 0, 0, , paths);
free(paths);
}
 }
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 33/46] Convert add_files_to_cache to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c| 11 +++
 builtin/commit.c |  2 +-
 cache.h  |  2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 34c9358..a47aeb4 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -166,14 +166,16 @@ static void update_callback(struct diff_queue_struct *q,
}
 }
 
-static void update_files_in_cache(const char *prefix, const char **pathspec,
+static void update_files_in_cache(const char *prefix,
+ const struct pathspec *pathspec,
  struct update_callback_data *data)
 {
struct rev_info rev;
 
init_revisions(rev, prefix);
setup_revisions(0, NULL, rev, NULL);
-   init_pathspec(rev.prune_data, pathspec);
+   if (pathspec)
+   copy_pathspec(rev.prune_data, pathspec);
rev.diffopt.output_format = DIFF_FORMAT_CALLBACK;
rev.diffopt.format_callback = update_callback;
rev.diffopt.format_callback_data = data;
@@ -181,7 +183,8 @@ static void update_files_in_cache(const char *prefix, const 
char **pathspec,
run_diff_files(rev, DIFF_RACY_IS_MODIFIED);
 }
 
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags)
+int add_files_to_cache(const char *prefix,
+  const struct pathspec *pathspec, int flags)
 {
struct update_callback_data data;
 
@@ -571,7 +574,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
memset(pathspec, 0, sizeof(pathspec));
}
update_data.flags = flags  ~ADD_CACHE_IMPLICIT_DOT;
-   update_files_in_cache(prefix, pathspec.raw, update_data);
+   update_files_in_cache(prefix, pathspec, update_data);
 
exit_status |= !!update_data.add_errors;
if (add_new_files)
diff --git a/builtin/commit.c b/builtin/commit.c
index d34baab..3b4dd60 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -336,7 +336,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 */
if (all || (also  pathspec.nr)) {
fd = hold_locked_index(index_lock, 1);
-   add_files_to_cache(also ? prefix : NULL, pathspec.raw, 0);
+   add_files_to_cache(also ? prefix : NULL, pathspec, 0);
refresh_cache_or_die(refresh_flags);
update_main_cache_tree(WRITE_TREE_SILENT);
if (write_cache(fd, active_cache, active_nr) ||
diff --git a/cache.h b/cache.h
index b294277..b0ed117 100644
--- a/cache.h
+++ b/cache.h
@@ -1278,7 +1278,7 @@ void packet_trace_identity(const char *prog);
  * return 0 if success, 1 - if addition of a file failed and
  * ADD_FILES_IGNORE_ERRORS was specified in flags
  */
-int add_files_to_cache(const char *prefix, const char **pathspec, int flags);
+int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, 
int flags);
 
 /* diff.c */
 extern int diff_auto_refresh_index;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 34/46] Convert common_prefix() to use struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
The code now takes advantage of nowildcard_len field.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/commit.c   |  2 +-
 builtin/ls-files.c |  2 +-
 dir.c  | 31 +++
 dir.h  |  2 +-
 4 files changed, 18 insertions(+), 19 deletions(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 3b4dd60..4ee9ba6 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -199,7 +199,7 @@ static int list_paths(struct string_list *list, const char 
*with_tree,
m = xcalloc(1, pattern-nr);
 
if (with_tree) {
-   char *max_prefix = common_prefix(pattern-raw);
+   char *max_prefix = common_prefix(pattern);
overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : 
prefix);
free(max_prefix);
}
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index fa1a6be..c074e6f 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -546,7 +546,7 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
   prefix, argv);
 
/* Find common prefix for all pathspec's */
-   max_prefix = common_prefix(pathspec.raw);
+   max_prefix = common_prefix(pathspec);
max_prefix_len = max_prefix ? strlen(max_prefix) : 0;
 
/* Treat unmatching pathspec elements as errors */
diff --git a/dir.c b/dir.c
index 290c7a3..019ad09 100644
--- a/dir.c
+++ b/dir.c
@@ -103,26 +103,25 @@ static int fnmatch_icase_mem(const char *pattern, int 
patternlen,
return match_status;
 }
 
-static size_t common_prefix_len(const char **pathspec)
+static size_t common_prefix_len(const struct pathspec *pathspec)
 {
-   const char *n, *first;
+   int n;
size_t max = 0;
-   int literal = limit_pathspec_to_literal();
 
-   if (!pathspec)
-   return max;
-
-   first = *pathspec;
-   while ((n = *pathspec++)) {
-   size_t i, len = 0;
-   for (i = 0; first == n || i  max; i++) {
-   char c = n[i];
-   if (!c || c != first[i] || (!literal  
is_glob_special(c)))
+   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+
+   for (n = 0; n  pathspec-nr; n++) {
+   size_t i = 0, len = 0;
+   while (i  pathspec-items[n].nowildcard_len 
+  (n == 0 || i  max)) {
+   char c = pathspec-items[n].match[i];
+   if (c != pathspec-items[0].match[i])
break;
if (c == '/')
len = i + 1;
+   i++;
}
-   if (first == n || len  max) {
+   if (n == 0 || len  max) {
max = len;
if (!max)
break;
@@ -135,11 +134,11 @@ static size_t common_prefix_len(const char **pathspec)
  * Returns a copy of the longest leading path common among all
  * pathspecs.
  */
-char *common_prefix(const char **pathspec)
+char *common_prefix(const struct pathspec *pathspec)
 {
unsigned long len = common_prefix_len(pathspec);
 
-   return len ? xmemdupz(*pathspec, len) : NULL;
+   return len ? xmemdupz(pathspec-items[0].match, len) : NULL;
 }
 
 int fill_directory(struct dir_struct *dir, const struct pathspec *pathspec)
@@ -150,7 +149,7 @@ int fill_directory(struct dir_struct *dir, const struct 
pathspec *pathspec)
 * Calculate common prefix for the pathspec, and
 * use that to optimize the directory walk
 */
-   len = common_prefix_len(pathspec-raw);
+   len = common_prefix_len(pathspec);
 
/* Read the directory and prune it */
read_directory(dir, pathspec-nr ? pathspec-raw[0] : , len, 
pathspec);
diff --git a/dir.h b/dir.h
index 076dd96..ba40e69 100644
--- a/dir.h
+++ b/dir.h
@@ -130,7 +130,7 @@ struct dir_struct {
 #define MATCHED_EXACTLY 3
 extern int simple_length(const char *match);
 extern int no_wildcard(const char *string);
-extern char *common_prefix(const char **pathspec);
+extern char *common_prefix(const struct pathspec *pathspec);
 extern int match_pathspec(const char **pathspec, const char *name, int 
namelen, int prefix, char *seen);
 extern int match_pathspec_depth(const struct pathspec *pathspec,
const char *name, int namelen,
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 30/46] Convert report_path_error to take struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/checkout.c |  2 +-
 builtin/commit.c   | 14 ++
 builtin/ls-files.c | 19 +++
 cache.h|  2 +-
 4 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/builtin/checkout.c b/builtin/checkout.c
index c2f3571..7ea1100 100644
--- a/builtin/checkout.c
+++ b/builtin/checkout.c
@@ -304,7 +304,7 @@ static int checkout_paths(const struct checkout_opts *opts,
ce-ce_flags |= CE_MATCHED;
}
 
-   if (report_path_error(ps_matched, opts-pathspec.raw, opts-prefix)) {
+   if (report_path_error(ps_matched, opts-pathspec, opts-prefix)) {
free(ps_matched);
return 1;
}
diff --git a/builtin/commit.c b/builtin/commit.c
index 0344ec7..eaecf7c 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -188,20 +188,18 @@ static int commit_index_files(void)
  * and return the paths that match the given pattern in list.
  */
 static int list_paths(struct string_list *list, const char *with_tree,
- const char *prefix, const char **pattern)
+ const char *prefix, const struct pathspec *pattern)
 {
int i;
char *m;
 
-   if (!pattern)
+   if (!pattern-nr)
return 0;
 
-   for (i = 0; pattern[i]; i++)
-   ;
-   m = xcalloc(1, i);
+   m = xcalloc(1, pattern-nr);
 
if (with_tree) {
-   char *max_prefix = common_prefix(pattern);
+   char *max_prefix = common_prefix(pattern-raw);
overlay_tree_on_cache(with_tree, max_prefix ? max_prefix : 
prefix);
free(max_prefix);
}
@@ -212,7 +210,7 @@ static int list_paths(struct string_list *list, const char 
*with_tree,
 
if (ce-ce_flags  CE_UPDATE)
continue;
-   if (!match_pathspec(pattern, ce-name, ce_namelen(ce), 0, m))
+   if (!match_pathspec_depth(pattern, ce-name, ce_namelen(ce), 0, 
m))
continue;
item = string_list_insert(list, ce-name);
if (ce_skip_worktree(ce))
@@ -402,7 +400,7 @@ static char *prepare_index(int argc, const char **argv, 
const char *prefix,
 
memset(partial, 0, sizeof(partial));
partial.strdup_strings = 1;
-   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec.raw))
+   if (list_paths(partial, !current_head ? NULL : HEAD, prefix, 
pathspec))
exit(1);
 
discard_cache();
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index f1be425..50e6edf 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -346,15 +346,16 @@ void overlay_tree_on_cache(const char *tree_name, const 
char *prefix)
}
 }
 
-int report_path_error(const char *ps_matched, const char **pathspec, const 
char *prefix)
+int report_path_error(const char *ps_matched,
+ const struct pathspec *pathspec,
+ const char *prefix)
 {
/*
 * Make sure all pathspec matched; otherwise it is an error.
 */
struct strbuf sb = STRBUF_INIT;
-   const char *name;
int num, errors = 0;
-   for (num = 0; pathspec[num]; num++) {
+   for (num = 0; num  pathspec-nr; num++) {
int other, found_dup;
 
if (ps_matched[num])
@@ -362,13 +363,16 @@ int report_path_error(const char *ps_matched, const char 
**pathspec, const char
/*
 * The caller might have fed identical pathspec
 * twice.  Do not barf on such a mistake.
+* FIXME: parse_pathspec should have eliminated
+* duplicate pathspec.
 */
for (found_dup = other = 0;
-!found_dup  pathspec[other];
+!found_dup  other  pathspec-nr;
 other++) {
if (other == num || !ps_matched[other])
continue;
-   if (!strcmp(pathspec[other], pathspec[num]))
+   if (!strcmp(pathspec-items[other].original,
+   pathspec-items[num].original))
/*
 * Ok, we have a match already.
 */
@@ -377,9 +381,8 @@ int report_path_error(const char *ps_matched, const char 
**pathspec, const char
if (found_dup)
continue;
 
-   name = quote_path_relative(pathspec[num], -1, sb, prefix);
error(pathspec '%s' did not match any file(s) known to git.,
- name);
+ pathspec-items[num].original);
errors++;
}
strbuf_release(sb);
@@ -575,7 +578,7 @@ int cmd_ls_files(int argc, const char **argv, const char 
*cmd_prefix)
 
if (ps_matched) {
  

[PATCH v2 37/46] Remove match_pathspec() in favor of match_pathspec_depth()

2013-07-14 Thread Nguyễn Thái Ngọc Duy
match_pathspec_depth was created to replace match_pathspec (see
61cf282 (pathspec: add match_pathspec_depth() - 2010-12-15). It took
more than two years, but the replacement finally happens :-)

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  |  30 +++---
 builtin/check-ignore.c |   4 +-
 dir.c  | 107 -
 dir.h  |   1 -
 pathspec.c |  19 -
 pathspec.h |   4 +-
 6 files changed, 25 insertions(+), 140 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index a47aeb4..0b80fa8 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -195,23 +195,21 @@ int add_files_to_cache(const char *prefix,
 }
 
 #define WARN_IMPLICIT_DOT (1u  0)
-static char *prune_directory(struct dir_struct *dir, const char **pathspec,
+static char *prune_directory(struct dir_struct *dir, struct pathspec *pathspec,
 int prefix, unsigned flag)
 {
char *seen;
-   int i, specs;
+   int i;
struct dir_entry **src, **dst;
 
-   for (specs = 0; pathspec[specs];  specs++)
-   /* nothing */;
-   seen = xcalloc(specs, 1);
+   seen = xcalloc(pathspec-nr, 1);
 
src = dst = dir-entries;
i = dir-nr;
while (--i = 0) {
struct dir_entry *entry = *src++;
-   if (match_pathspec(pathspec, entry-name, entry-len,
-  prefix, seen))
+   if (match_pathspec_depth(pathspec, entry-name, entry-len,
+prefix, seen))
*dst++ = entry;
else if (flag  WARN_IMPLICIT_DOT)
/*
@@ -225,7 +223,7 @@ static char *prune_directory(struct dir_struct *dir, const 
char **pathspec,
warn_pathless_add();
}
dir-nr = dst - dir-entries;
-   add_pathspec_matches_against_index(pathspec, seen, specs);
+   add_pathspec_matches_against_index(pathspec, seen);
return seen;
 }
 
@@ -523,7 +521,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
/* This picks up the paths that are not tracked */
baselen = fill_directory(dir, implicit_dot ? empty_pathspec : 
pathspec);
if (pathspec.nr)
-   seen = prune_directory(dir, pathspec.raw, baselen,
+   seen = prune_directory(dir, pathspec, baselen,
implicit_dot ? WARN_IMPLICIT_DOT : 0);
}
 
@@ -538,23 +536,23 @@ int cmd_add(int argc, const char **argv, const char 
*prefix)
int i;
 
if (!seen)
-   seen = 
find_pathspecs_matching_against_index(pathspec.raw);
+   seen = find_pathspecs_matching_against_index(pathspec);
 
/*
 * file_exists() assumes exact match
 */
GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP);
 
-   for (i = 0; pathspec.raw[i]; i++) {
-   if (!seen[i]  pathspec.raw[i][0]
-!file_exists(pathspec.raw[i])) {
+   for (i = 0; i  pathspec.nr; i++) {
+   const char *path = pathspec.items[i].match;
+   if (!seen[i]  !file_exists(path)) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
-   if (is_excluded(dir, pathspec.raw[i], 
dtype))
-   dir_add_ignored(dir, 
pathspec.raw[i], strlen(pathspec.raw[i]));
+   if (is_excluded(dir, path, dtype))
+   dir_add_ignored(dir, path, 
pathspec.items[i].len);
} else
die(_(pathspec '%s' did not match any 
files),
-   pathspec.raw[i]);
+   pathspec.items[i].original);
}
}
free(seen);
diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c
index d49c083..70537c8 100644
--- a/builtin/check-ignore.c
+++ b/builtin/check-ignore.c
@@ -94,9 +94,9 @@ static int check_ignore(struct dir_struct *dir,
 * should not be ignored, in order to be consistent with
 * 'git status', 'git add' etc.
 */
-   seen = find_pathspecs_matching_against_index(pathspec.raw);
+   seen = find_pathspecs_matching_against_index(pathspec);
for (i = 0; i  pathspec.nr; i++) {
-   full_path = pathspec.raw[i];
+   full_path = pathspec.items[i].match;
exclude = NULL;
if (!seen[i]) {
exclude = last_exclude_matching(dir, full_path, dtype);
diff --git 

[PATCH v2 39/46] Rename field raw to _raw in struct pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy
This patch is essentially no-op. It helps catching new use of this
field though. This field is introduced as an intermediate step for the
pathspec conversion and will be removed eventually. At this stage no
more access sites should be introduced.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/ls-tree.c | 2 +-
 dir.c | 4 ++--
 pathspec.c| 6 +++---
 pathspec.h| 2 +-
 4 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c
index bdb03f3..1c4f48e 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -36,7 +36,7 @@ static int show_recursive(const char *base, int baselen, 
const char *pathname)
if (ls_options  LS_RECURSIVE)
return 1;
 
-   s = pathspec.raw;
+   s = pathspec._raw;
if (!s)
return 0;
 
diff --git a/dir.c b/dir.c
index 9423fbb..bf22498 100644
--- a/dir.c
+++ b/dir.c
@@ -152,7 +152,7 @@ int fill_directory(struct dir_struct *dir, const struct 
pathspec *pathspec)
len = common_prefix_len(pathspec);
 
/* Read the directory and prune it */
-   read_directory(dir, pathspec-nr ? pathspec-raw[0] : , len, 
pathspec);
+   read_directory(dir, pathspec-nr ? pathspec-_raw[0] : , len, 
pathspec);
return len;
 }
 
@@ -1293,7 +1293,7 @@ int read_directory(struct dir_struct *dir, const char 
*path, int len, const stru
if (has_symlink_leading_path(path, len))
return dir-nr;
 
-   simplify = create_simplify(pathspec ? pathspec-raw : NULL);
+   simplify = create_simplify(pathspec ? pathspec-_raw : NULL);
if (!len || treat_leading_path(dir, path, len, simplify))
read_directory_recursive(dir, path, len, 0, simplify);
free_simplify(simplify);
diff --git a/pathspec.c b/pathspec.c
index 3d1386d..da802e2 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -287,7 +287,7 @@ void parse_pathspec(struct pathspec *pathspec,
raw[0] = prefix;
raw[1] = NULL;
pathspec-nr = 1;
-   pathspec-raw = raw;
+   pathspec-_raw = raw;
return;
}
 
@@ -297,7 +297,7 @@ void parse_pathspec(struct pathspec *pathspec,
 
pathspec-nr = n;
pathspec-items = item = xmalloc(sizeof(*item) * n);
-   pathspec-raw = argv;
+   pathspec-_raw = argv;
prefixlen = prefix ? strlen(prefix) : 0;
 
for (i = 0; i  n; i++) {
@@ -357,7 +357,7 @@ const char **get_pathspec(const char *prefix, const char 
**pathspec)
   PATHSPEC_ALL_MAGIC  ~PATHSPEC_FROMTOP,
   PATHSPEC_PREFER_CWD,
   prefix, pathspec);
-   return ps.raw;
+   return ps._raw;
 }
 
 void copy_pathspec(struct pathspec *dst, const struct pathspec *src)
diff --git a/pathspec.h b/pathspec.h
index 31a9c96..0f6739d 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -11,7 +11,7 @@
 #define PATHSPEC_ONESTAR 1 /* the pathspec pattern sastisfies GFNM_ONESTAR 
*/
 
 struct pathspec {
-   const char **raw; /* get_pathspec() result, not freed by 
free_pathspec() */
+   const char **_raw; /* get_pathspec() result, not freed by 
free_pathspec() */
int nr;
unsigned int has_wildcard:1;
unsigned int recursive:1;
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 40/46] parse_pathspec: make sure the prefix part is wildcard-free

2013-07-14 Thread Nguyễn Thái Ngọc Duy
Prepending prefix to pathspec is a trick to workaround the fact that
commands can be executed in a subdirectory, but all git commands run
at worktree's root. The prefix part should always be treated as
literal string. Make it so.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 cache.h|  2 ++
 path.c | 15 ++-
 pathspec.c | 21 +
 pathspec.h |  2 +-
 setup.c| 24 
 5 files changed, 54 insertions(+), 10 deletions(-)

diff --git a/cache.h b/cache.h
index b0ed117..13e3c94 100644
--- a/cache.h
+++ b/cache.h
@@ -414,6 +414,7 @@ extern void setup_work_tree(void);
 extern const char *setup_git_directory_gently(int *);
 extern const char *setup_git_directory(void);
 extern char *prefix_path(const char *prefix, int len, const char *path);
+extern char *prefix_path_gently(const char *prefix, int len, int *remaining, 
const char *path);
 extern const char *prefix_filename(const char *prefix, int len, const char 
*path);
 extern int check_filename(const char *prefix, const char *name);
 extern void verify_filename(const char *prefix,
@@ -741,6 +742,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 04ff148..f4b49d6 100644
--- a/path.c
+++ b/path.c
@@ -492,8 +492,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;
 
@@ -568,11 +574,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/pathspec.c b/pathspec.c
index da802e2..71e5eaf 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -150,10 +150,14 @@ static unsigned prefix_pathspec(struct pathspec_item 
*item,
magic |= short_magic;
*p_short_magic = short_magic;
 
-   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, prefixlen, 
copyfrom);
+   if (!match)
+   die(_(%s: '%s' is outside repository), elt, copyfrom);
+   }
*raw = item-match = match;
/*
 * Prefix the pathspec (keep all magic) and assign to
@@ -167,6 +171,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
} else
item-original = elt;
item-len = strlen(item-match);
+   item-prefix = prefixlen;
 
if ((flags  PATHSPEC_STRIP_SUBMODULE_SLASH_CHEAP) 
(item-len = 1  item-match[item-len - 1] == '/') 
@@ -198,13 +203,20 @@ static unsigned prefix_pathspec(struct pathspec_item 
*item,
 
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;
+   }
item-flags = 0;
if (item-nowildcard_len  item-len 
item-match[item-nowildcard_len] == '*' 
no_wildcard(item-match + item-nowildcard_len + 1))
item-flags |= PATHSPEC_ONESTAR;
+
+   /* sanity checks, pathspec matchers assume these are sane */
+   assert(item-nowildcard_len = item-len 
+  item-prefix = item-len);
return magic;
 }
 
@@ -284,6 +296,7 @@ void 

[PATCH v2 35/46] Remove diff_tree_{setup,release}_paths

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/blame.c | 12 ++--
 builtin/reset.c |  9 +
 combine-diff.c  |  4 ++--
 diff.h  |  2 --
 notes-merge.c   |  4 ++--
 revision.c  |  5 +++--
 tree-diff.c | 18 --
 7 files changed, 22 insertions(+), 32 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 079dcd3..5bd721d 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -408,7 +408,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[0] = origin-path;
paths[1] = NULL;
 
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -458,7 +458,7 @@ static struct origin *find_origin(struct scoreboard *sb,
}
}
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
if (porigin) {
/*
 * Create a freestanding copy that is not part of
@@ -494,7 +494,7 @@ static struct origin *find_rename(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin-path;
paths[0] = NULL;
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -516,7 +516,7 @@ static struct origin *find_rename(struct scoreboard *sb,
}
}
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
return porigin;
 }
 
@@ -1079,7 +1079,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 
paths[0] = NULL;
-   diff_tree_setup_paths(paths, diff_opts);
+   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
/* Try find copies harder on new path if requested;
@@ -1162,7 +1162,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
}
reset_scanned_flag(sb);
diff_flush(diff_opts);
-   diff_tree_release_paths(diff_opts);
+   free_pathspec(diff_opts.pathspec);
return retval;
 }
 
diff --git a/builtin/reset.c b/builtin/reset.c
index 9bef869..86150d1 100644
--- a/builtin/reset.c
+++ b/builtin/reset.c
@@ -133,12 +133,13 @@ static void update_index_from_diff(struct 
diff_queue_struct *q,
}
 }
 
-static int read_from_tree(const char **pathspec, unsigned char *tree_sha1)
+static int read_from_tree(const struct pathspec *pathspec,
+ unsigned char *tree_sha1)
 {
struct diff_options opt;
 
memset(opt, 0, sizeof(opt));
-   diff_tree_setup_paths(pathspec, opt);
+   copy_pathspec(opt.pathspec, pathspec);
opt.output_format = DIFF_FORMAT_CALLBACK;
opt.format_callback = update_index_from_diff;
 
@@ -147,7 +148,7 @@ static int read_from_tree(const char **pathspec, unsigned 
char *tree_sha1)
return 1;
diffcore_std(opt);
diff_flush(opt);
-   diff_tree_release_paths(opt);
+   free_pathspec(opt.pathspec);
 
return 0;
 }
@@ -332,7 +333,7 @@ int cmd_reset(int argc, const char **argv, const char 
*prefix)
struct lock_file *lock = xcalloc(1, sizeof(struct lock_file));
int newfd = hold_locked_index(lock, 1);
if (reset_type == MIXED) {
-   if (read_from_tree(pathspec.raw, sha1))
+   if (read_from_tree(pathspec, sha1))
return 1;
} else {
int err = reset_index(sha1, reset_type, quiet);
diff --git a/combine-diff.c b/combine-diff.c
index 6dc0609..c973f5d 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -1305,7 +1305,7 @@ void diff_tree_combined(const unsigned char *sha1,
int i, num_paths, needsep, show_log_first, num_parent = parents-nr;
 
diffopts = *opt;
-   diff_tree_setup_paths(diffopts.pathspec.raw, diffopts);
+   copy_pathspec(diffopts.pathspec, opt-pathspec);
diffopts.output_format = DIFF_FORMAT_NO_OUTPUT;
DIFF_OPT_SET(diffopts, RECURSIVE);
DIFF_OPT_CLR(diffopts, ALLOW_EXTERNAL);
@@ -1377,7 +1377,7 @@ void diff_tree_combined(const unsigned char *sha1,
free(tmp);
}
 
-   diff_tree_release_paths(diffopts);
+   free_pathspec(diffopts.pathspec);
 }
 
 void diff_tree_combined_merge(const struct commit *commit, int dense,
diff --git a/diff.h b/diff.h
index d1bc914..b8df245 100644
--- a/diff.h
+++ b/diff.h
@@ -180,8 +180,6 @@ const char *diff_line_prefix(struct diff_options *);
 
 extern const char mime_boundary_leader[];
 
-extern void diff_tree_setup_paths(const char **paths, struct diff_options *);
-extern void 

[PATCH v2 41/46] parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN

2013-07-14 Thread Nguyễn Thái Ngọc Duy
The prefix length is passed from one command to another via the new
magic 'prefix'. The magic is for parse_pathspec's internal use only,
not visible to parse_pathspec's callers.

Prefix length is not preserved across commands when --literal-pathspecs
is specified (no magic is allowed, including 'prefix'). That's OK
because we know all paths are literal. No magic, no special treatment
regarding prefix. (This may be no longer true if we make :(glob)
default)

Other options to preserve the prefix include saving it to env variable
or quoting. Env var way (at least _one_ env var) is not suitable
because the prefix is not the same for all pathspecs. Pathspecs
starting with ../ will eat into the prefix part.

We could also preserve 'prefix' across commands by quoting the prefix
part, then dequoting on receiving. But it may not be 100% accurate, we
may dequote longer than the original prefix part, for example. That
may be good or not, but it's not the purpose.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 pathspec.c | 41 -
 1 file changed, 36 insertions(+), 5 deletions(-)

diff --git a/pathspec.c b/pathspec.c
index 71e5eaf..82ede57 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -92,9 +92,9 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
const char *elt)
 {
unsigned magic = 0, short_magic = 0;
-   const char *copyfrom = elt;
+   const char *copyfrom = elt, *long_magic_end = NULL;
char *match;
-   int i;
+   int i, pathspec_prefix = -1;
 
if (elt[0] != ':') {
; /* nothing to do */
@@ -112,18 +112,29 @@ static unsigned prefix_pathspec(struct pathspec_item 
*item,
nextat = copyfrom + len;
if (!len)
continue;
-   for (i = 0; i  ARRAY_SIZE(pathspec_magic); i++)
+   for (i = 0; i  ARRAY_SIZE(pathspec_magic); i++) {
if (strlen(pathspec_magic[i].name) == len 
!strncmp(pathspec_magic[i].name, copyfrom, 
len)) {
magic |= pathspec_magic[i].bit;
break;
}
+   if (!prefixcmp(copyfrom, prefix:)) {
+   char *endptr;
+   pathspec_prefix = strtol(copyfrom + 7,
+endptr, 10);
+   if (endptr - copyfrom != len)
+   die(_(invalid parameter for 
pathspec magic 'prefix'));
+   /* i would be wrong, but it does not 
matter */
+   break;
+   }
+   }
if (ARRAY_SIZE(pathspec_magic) = i)
die(_(Invalid pathspec magic '%.*s' in '%s'),
(int) len, copyfrom, elt);
}
if (*copyfrom != ')')
die(_(Missing ')' at the end of pathspec magic in 
'%s'), elt);
+   long_magic_end = copyfrom;
copyfrom++;
} else {
/* shorthand */
@@ -150,7 +161,14 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
magic |= short_magic;
*p_short_magic = short_magic;
 
-   if (magic  PATHSPEC_FROMTOP) {
+   if (pathspec_prefix = 0 
+   (prefixlen || (prefix  *prefix)))
+   die(BUG: 'prefix' magic is supposed to be used at worktree's 
root);
+
+   if (pathspec_prefix = 0) {
+   match = xstrdup(copyfrom);
+   prefixlen = pathspec_prefix;
+   } else if (magic  PATHSPEC_FROMTOP) {
match = xstrdup(copyfrom);
prefixlen = 0;
} else {
@@ -165,7 +183,20 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 */
if (flags  PATHSPEC_PREFIX_ORIGIN) {
struct strbuf sb = STRBUF_INIT;
-   strbuf_add(sb, elt, copyfrom - elt);
+   const char *start = elt;
+   if (prefixlen  !limit_pathspec_to_literal()) {
+   /* Preserve the actual prefix length of each pattern */
+   if (long_magic_end) {
+   strbuf_add(sb, start, long_magic_end - start);
+   strbuf_addf(sb, ,prefix:%d, prefixlen);
+   start = long_magic_end;
+   } else {
+   if (*start == ':')
+   start++;
+   strbuf_addf(sb, :(prefix:%d), prefixlen);
+   }
+   }
+ 

[PATCH v2 42/46] Kill limit_pathspec_to_literal() as it's only used by parse_pathspec()

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c  | 8 
 pathspec.c | 8 ++--
 pathspec.h | 2 --
 3 files changed, 6 insertions(+), 12 deletions(-)

diff --git a/dir.c b/dir.c
index bf22498..79465e7 100644
--- a/dir.c
+++ b/dir.c
@@ -1473,14 +1473,6 @@ int remove_path(const char *name)
return 0;
 }
 
-int limit_pathspec_to_literal(void)
-{
-   static int flag = -1;
-   if (flag  0)
-   flag = git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0);
-   return flag;
-}
-
 /*
  * Frees memory within dir which was allocated for exclude lists and
  * the exclude_stack.  Does not free dir itself.
diff --git a/pathspec.c b/pathspec.c
index 82ede57..b2e3a87 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -91,11 +91,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
const char *prefix, int prefixlen,
const char *elt)
 {
+   static int literal_global = -1;
unsigned magic = 0, short_magic = 0;
const char *copyfrom = elt, *long_magic_end = NULL;
char *match;
int i, pathspec_prefix = -1;
 
+   if (literal_global  0)
+   literal_global = 
git_env_bool(GIT_LITERAL_PATHSPECS_ENVIRONMENT, 0);
+
if (elt[0] != ':') {
; /* nothing to do */
} else if (elt[1] == '(') {
@@ -184,7 +188,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
if (flags  PATHSPEC_PREFIX_ORIGIN) {
struct strbuf sb = STRBUF_INIT;
const char *start = elt;
-   if (prefixlen  !limit_pathspec_to_literal()) {
+   if (prefixlen  !literal_global) {
/* Preserve the actual prefix length of each pattern */
if (long_magic_end) {
strbuf_add(sb, start, long_magic_end - start);
@@ -232,7 +236,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
 elt, ce_len, ce-name);
}
 
-   if (limit_pathspec_to_literal())
+   if (literal_global)
item-nowildcard_len = item-len;
else {
item-nowildcard_len = simple_length(item-match);
diff --git a/pathspec.h b/pathspec.h
index 2f3532e..7ef9896 100644
--- a/pathspec.h
+++ b/pathspec.h
@@ -61,8 +61,6 @@ extern void parse_pathspec(struct pathspec *pathspec,
 extern void copy_pathspec(struct pathspec *dst, const struct pathspec *src);
 extern void free_pathspec(struct pathspec *);
 
-extern int limit_pathspec_to_literal(void);
-
 extern char *find_pathspecs_matching_against_index(const struct pathspec 
*pathspec);
 extern void add_pathspec_matches_against_index(const struct pathspec 
*pathspec, char *seen);
 extern const char *check_path_for_gitlink(const char *path);
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 38/46] tree-diff: remove the use of pathspec's raw[] in follow-rename codepath

2013-07-14 Thread Nguyễn Thái Ngọc Duy
Put a checkpoint to guard unsupported pathspec features in future.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 tree-diff.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tree-diff.c b/tree-diff.c
index e1145c6..21a50d8 100644
--- a/tree-diff.c
+++ b/tree-diff.c
@@ -224,7 +224,7 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
DIFF_OPT_SET(diff_opts, RECURSIVE);
DIFF_OPT_SET(diff_opts, FIND_COPIES_HARDER);
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
-   diff_opts.single_follow = opt-pathspec.raw[0];
+   diff_opts.single_follow = opt-pathspec.items[0].match;
diff_opts.break_opt = opt-break_opt;
diff_opts.rename_score = opt-rename_score;
diff_setup_done(diff_opts);
@@ -243,7 +243,7 @@ static void try_to_follow_renames(struct tree_desc *t1, 
struct tree_desc *t2, co
 * the future!
 */
if ((p-status == 'R' || p-status == 'C') 
-   !strcmp(p-two-path, opt-pathspec.raw[0])) {
+   !strcmp(p-two-path, opt-pathspec.items[0].match)) {
const char *path[2];
 
/* Switch the file-pairs around */
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 43/46] pathspec: support :(literal) syntax for noglob pathspec

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/glossary-content.txt | 20 
 builtin/add.c  |  2 +-
 builtin/diff.c |  2 +-
 dir.c  | 15 ---
 pathspec.c | 11 ---
 pathspec.h |  4 +++-
 t/t6130-pathspec-noglob.sh | 18 ++
 tree-diff.c|  2 +-
 tree-walk.c|  5 -
 9 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index dba5062..ca9f20f 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -322,10 +322,22 @@ and a close parentheses `)`, and the remainder is the 
pattern to match
 against the path.
 +
 The magic signature consists of an ASCII symbol that is not
-alphanumeric. Currently only the slash `/` is recognized as a
-magic signature: it makes the pattern match from the root of
-the working tree, even when you are running the command from
-inside a subdirectory.
+alphanumeric.
++
+--
+top `/`;;
+   The magic word `top` (mnemonic: `/`) makes the pattern match
+   from the root of the working tree, even when you are running
+   the command from inside a subdirectory.
+
+literal;;
+   Wildcards in the pattern such as `*` or `?` are treated
+   as literal characters.
+--
++
+Currently only the slash `/` is recognized as the magic signature,
+but it is envisioned that we will support more types of magic in later
+versions of Git.
 +
 A pathspec with only a colon means there is no pathspec. This form
 should not be combined with other pathspec.
diff --git a/builtin/add.c b/builtin/add.c
index 0b80fa8..663ddd1 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -541,7 +541,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/diff.c b/builtin/diff.c
index bb84ba0..2fb8c5d 100644
--- a/builtin/diff.c
+++ b/builtin/diff.c
@@ -368,7 +368,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/dir.c b/dir.c
index 79465e7..50ec2f5 100644
--- a/dir.c
+++ b/dir.c
@@ -108,7 +108,10 @@ static size_t common_prefix_len(const struct pathspec 
*pathspec)
int n;
size_t max = 0;
 
-   GUARD_PATHSPEC(pathspec, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+   GUARD_PATHSPEC(pathspec,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_MAXDEPTH |
+  PATHSPEC_LITERAL);
 
for (n = 0; n  pathspec-nr; n++) {
size_t i = 0, len = 0;
@@ -232,7 +235,10 @@ int match_pathspec_depth(const struct pathspec *ps,
 {
int i, retval = 0;
 
-   GUARD_PATHSPEC(ps, PATHSPEC_FROMTOP | PATHSPEC_MAXDEPTH);
+   GUARD_PATHSPEC(ps,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_MAXDEPTH |
+  PATHSPEC_LITERAL);
 
if (!ps-nr) {
if (!ps-recursive ||
@@ -1288,7 +1294,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_MAXDEPTH);
+   GUARD_PATHSPEC(pathspec,
+  PATHSPEC_FROMTOP |
+  PATHSPEC_MAXDEPTH |
+  PATHSPEC_LITERAL);
 
if (has_symlink_leading_path(path, len))
return dir-nr;
diff --git a/pathspec.c b/pathspec.c
index b2e3a87..6a16938 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -70,6 +70,7 @@ static struct pathspec_magic {
const char *name;
 } pathspec_magic[] = {
{ PATHSPEC_FROMTOP, '/', top },
+   { PATHSPEC_LITERAL,   0, literal },
 };
 
 /*
@@ -92,13 +93,15 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
const char *elt)
 {
static int literal_global = -1;
-   unsigned magic = 0, short_magic = 0;
+   unsigned magic = 0, short_magic = 0, global_magic = 0;
const char *copyfrom = elt, *long_magic_end = NULL;
char *match;
int i, 

[PATCH v2 36/46] Remove init_pathspec() in favor of parse_pathspec()

2013-07-14 Thread Nguyễn Thái Ngọc Duy
While at there, move free_pathspec() to pathspec.c

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/blame.c|  8 +---
 builtin/log.c  |  2 +-
 builtin/ls-files.c | 11 +--
 diff-lib.c |  2 +-
 dir.c  | 58 --
 merge-recursive.c  |  2 +-
 pathspec.c |  6 ++
 pathspec.h |  1 -
 revision.c |  2 +-
 tree-diff.c| 10 +-
 10 files changed, 21 insertions(+), 81 deletions(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 5bd721d..56e3d6b 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -408,7 +408,7 @@ static struct origin *find_origin(struct scoreboard *sb,
paths[0] = origin-path;
paths[1] = NULL;
 
-   init_pathspec(diff_opts.pathspec, paths);
+   parse_pathspec(diff_opts.pathspec, PATHSPEC_ALL_MAGIC, 0, , paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -486,15 +486,12 @@ static struct origin *find_rename(struct scoreboard *sb,
struct origin *porigin = NULL;
struct diff_options diff_opts;
int i;
-   const char *paths[2];
 
diff_setup(diff_opts);
DIFF_OPT_SET(diff_opts, RECURSIVE);
diff_opts.detect_rename = DIFF_DETECT_RENAME;
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
diff_opts.single_follow = origin-path;
-   paths[0] = NULL;
-   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
if (is_null_sha1(origin-commit-object.sha1))
@@ -1064,7 +1061,6 @@ static int find_copy_in_parent(struct scoreboard *sb,
   int opt)
 {
struct diff_options diff_opts;
-   const char *paths[1];
int i, j;
int retval;
struct blame_list *blame_list;
@@ -1078,8 +1074,6 @@ static int find_copy_in_parent(struct scoreboard *sb,
DIFF_OPT_SET(diff_opts, RECURSIVE);
diff_opts.output_format = DIFF_FORMAT_NO_OUTPUT;
 
-   paths[0] = NULL;
-   init_pathspec(diff_opts.pathspec, paths);
diff_setup_done(diff_opts);
 
/* Try find copies harder on new path if requested;
diff --git a/builtin/log.c b/builtin/log.c
index e3222ed..873af69 100644
--- a/builtin/log.c
+++ b/builtin/log.c
@@ -503,7 +503,7 @@ int cmd_show(int argc, const char **argv, const char 
*prefix)
init_grep_defaults();
git_config(git_log_config, NULL);
 
-   init_pathspec(match_all, NULL);
+   memset(match_all, 0, sizeof(match_all));
init_revisions(rev, prefix);
rev.diff = 1;
rev.always_show_header = 1;
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index c074e6f..d3a0495 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -315,13 +315,12 @@ void overlay_tree_on_cache(const char *tree_name, const 
char *prefix)
}
 
if (prefix) {
-   static const char *(matchbuf[2]);
-   matchbuf[0] = prefix;
-   matchbuf[1] = NULL;
-   init_pathspec(pathspec, matchbuf);
-   pathspec.items[0].nowildcard_len = pathspec.items[0].len;
+   static const char *(matchbuf[1]);
+   matchbuf[0] = NULL;
+   parse_pathspec(pathspec, PATHSPEC_ALL_MAGIC,
+  PATHSPEC_PREFER_CWD, prefix, matchbuf);
} else
-   init_pathspec(pathspec, NULL);
+   memset(pathspec, 0, sizeof(pathspec));
if (read_tree(tree, 1, pathspec))
die(unable to read tree entries %s, tree_name);
 
diff --git a/diff-lib.c b/diff-lib.c
index d4e17f7..0a95763 100644
--- a/diff-lib.c
+++ b/diff-lib.c
@@ -501,7 +501,7 @@ int do_diff_cache(const unsigned char *tree_sha1, struct 
diff_options *opt)
struct rev_info revs;
 
init_revisions(revs, NULL);
-   init_pathspec(revs.prune_data, opt-pathspec.raw);
+   copy_pathspec(revs.prune_data, opt-pathspec);
revs.diffopt = *opt;
 
if (diff_cache(revs, tree_sha1, NULL, 1))
diff --git a/dir.c b/dir.c
index 019ad09..959e694 100644
--- a/dir.c
+++ b/dir.c
@@ -1580,64 +1580,6 @@ int remove_path(const char *name)
return 0;
 }
 
-static int pathspec_item_cmp(const void *a_, const void *b_)
-{
-   struct pathspec_item *a, *b;
-
-   a = (struct pathspec_item *)a_;
-   b = (struct pathspec_item *)b_;
-   return strcmp(a-match, b-match);
-}
-
-int init_pathspec(struct pathspec *pathspec, const char **paths)
-{
-   const char **p = paths;
-   int i;
-
-   memset(pathspec, 0, sizeof(*pathspec));
-   if (!p)
-   return 0;
-   while (*p)
-   p++;
-   pathspec-raw = paths;
-   pathspec-nr = p - paths;
-   if (!pathspec-nr)
-   return 0;
-
-   pathspec-items = xmalloc(sizeof(struct pathspec_item)*pathspec-nr);
-   for (i = 0; i  pathspec-nr; i++) {
-   struct pathspec_item *item 

[PATCH v2 44/46] pathspec: make --literal-pathspecs disable pathspec magic

2013-07-14 Thread Nguyễn Thái Ngọc Duy
--literal-pathspecs and its equivalent environment variable are
probably used for scripting. In that setting, pathspec magic may be
unwanted. Disabling globbing in individual pathspec can be done via
:(literal) magic.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git.txt  | 4 ++--
 pathspec.c | 2 +-
 t/t6130-pathspec-noglob.sh | 6 ++
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index b738a40..80139ae 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -450,8 +450,8 @@ help ...`.
linkgit:git-replace[1] for more information.
 
 --literal-pathspecs::
-   Treat pathspecs literally, rather than as glob patterns. This is
-   equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
+   Treat pathspecs literally (i.e. no globbing, no pathspec magic).
+   This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
variable to `1`.
 
 
diff --git a/pathspec.c b/pathspec.c
index 6a16938..b6d8e74 100644
--- a/pathspec.c
+++ b/pathspec.c
@@ -103,7 +103,7 @@ static unsigned prefix_pathspec(struct pathspec_item *item,
if (literal_global)
global_magic |= PATHSPEC_LITERAL;
 
-   if (elt[0] != ':') {
+   if (elt[0] != ':' || literal_global) {
; /* nothing to do */
} else if (elt[1] == '(') {
/* longhand */
diff --git a/t/t6130-pathspec-noglob.sh b/t/t6130-pathspec-noglob.sh
index 49c148e..8551b02 100755
--- a/t/t6130-pathspec-noglob.sh
+++ b/t/t6130-pathspec-noglob.sh
@@ -77,6 +77,12 @@ test_expect_success 'no-glob option matches literally 
(bracket)' '
test_cmp expect actual
 '
 
+test_expect_success 'no-glob option disables :(literal)' '
+   : expect 
+   git --literal-pathspecs log --format=%s -- :(literal)foo 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 
-- 
1.8.2.83.gc99314b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 45/46] pathspec: support :(glob) syntax

2013-07-14 Thread Nguyễn Thái Ngọc Duy
:(glob)path differs from plain pathspec that it uses wildmatch with
WM_PATHNAME while the other uses fnmatch without FNM_PATHNAME. The
difference lies in how '*' (and '**') is processed.

With the introduction of :(glob) and :(literal) and their global
options --[no]glob-pathspecs, the user can:

 - make everything literal by default via --noglob-pathspecs
   --literal-pathspecs cannot be used for this purpose as it
   disables _all_ pathspec magic.

 - individually turn on globbing with :(glob)

 - make everything globbing by default via --glob-pathspecs

 - individually turn off globbing with :(literal)

The implication behind this is, there is no way to gain the default
matching behavior (i.e. fnmatch without FNM_PATHNAME). You either get
new globbing or literal. The old fnmatch behavior is considered
deprecated and discouraged to use.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git.txt  | 19 
 Documentation/glossary-content.txt | 29 ++
 builtin/add.c  |  9 --
 builtin/ls-tree.c  |  2 +-
 cache.h|  2 ++
 dir.c  | 28 +
 dir.h  |  9 +++---
 git.c  |  8 +
 pathspec.c | 47 +---
 pathspec.h |  4 ++-
 t/t6130-pathspec-noglob.sh | 63 ++
 tree-walk.c|  9 +++---
 12 files changed, 198 insertions(+), 31 deletions(-)

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 80139ae..3571a1b 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -454,6 +454,17 @@ help ...`.
This is equivalent to setting the `GIT_LITERAL_PATHSPECS` environment
variable to `1`.
 
+--glob-pathspecs:
+   Add glob magic to all pathspec. This is equivalent to setting
+   the `GIT_GLOB_PATHSPECS` environment variable to `1`. Disabling
+   globbing on individual pathspecs can be done using pathspec
+   magic :(literal)
+
+--noglob-pathspecs:
+   Add literal magic to all pathspec. This is equivalent to setting
+   the `GIT_NOGLOB_PATHSPECS` environment variable to `1`. Enabling
+   globbing on individual pathspecs can be done using pathspec
+   magic :(glob)
 
 GIT COMMANDS
 
@@ -860,6 +871,14 @@ GIT_LITERAL_PATHSPECS::
literal paths to Git (e.g., paths previously given to you by
`git ls-tree`, `--raw` diff output, etc).
 
+GIT_GLOB_PATHSPECS::
+   Setting this variable to `1` will cause Git to treat all
+   pathspecs as glob patterns (aka glob magic).
+
+GIT_NOGLOB_PATHSPECS::
+   Setting this variable to `1` will cause Git to treat all
+   pathspecs as literal (aka literal magic).
+
 
 Discussion[[Discussion]]
 
diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index ca9f20f..a3d9029 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -333,6 +333,35 @@ top `/`;;
 literal;;
Wildcards in the pattern such as `*` or `?` are treated
as literal characters.
+
+glob;;
+   Git treats the pattern as a shell glob suitable for
+   consumption by fnmatch(3) with the FNM_PATHNAME flag:
+   wildcards in the pattern will not match a / in the pathname.
+   For example, Documentation/{asterisk}.html matches
+   Documentation/git.html but not Documentation/ppc/ppc.html
+   or tools/perf/Documentation/perf.html.
++
+Two consecutive asterisks (`**`) in patterns matched against
+full pathname may have special meaning:
+
+ - A leading `**` followed by a slash means match in all
+   directories. For example, `**/foo` matches file or directory
+   `foo` anywhere, the same as pattern `foo`. **/foo/bar
+   matches file or directory `bar` anywhere that is directly
+   under directory `foo`.
+
+ - A trailing /** matches everything inside. For example,
+   abc/** matches all files inside directory abc, relative
+   to the location of the `.gitignore` file, with infinite depth.
+
+ - A slash followed by two consecutive asterisks then a slash
+   matches zero or more directories. For example, `a/**/b`
+   matches `a/b`, `a/x/b`, `a/x/y/b` and so on.
+
+ - Other consecutive asterisks are considered invalid.
++
+Glob magic is incompatible with literal magic.
 --
 +
 Currently only the slash `/` is recognized as the magic signature,
diff --git a/builtin/add.c b/builtin/add.c
index 663ddd1..1dab246 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -541,11 +541,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,
+ 

[PATCH v2 46/46] parse_pathspec: accept :(icase)path syntax

2013-07-14 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/git.txt  |  8 
 Documentation/glossary-content.txt |  3 ++
 builtin/add.c  |  6 ++-
 builtin/ls-tree.c  |  2 +-
 cache.h|  1 +
 dir.c  | 74 -
 git.c  |  4 ++
 pathspec.c |  9 +++-
 pathspec.h | 22 -
 t/t6131-pathspec-icase.sh (new +x) | 97 ++
 tree-walk.c| 59 ++-
 11 files changed, 257 insertions(+), 28 deletions(-)
 create mode 100755 t/t6131-pathspec-icase.sh

diff --git a/Documentation/git.txt b/Documentation/git.txt
index 3571a1b..546eea4 100644
--- a/Documentation/git.txt
+++ b/Documentation/git.txt
@@ -466,6 +466,10 @@ help ...`.
globbing on individual pathspecs can be done using pathspec
magic :(glob)
 
+--icase-pathspecs:
+   Add icase magic to all pathspec. This is equivalent to setting
+   the `GIT_ICASE_PATHSPECS` environment variable to `1`.
+
 GIT COMMANDS
 
 
@@ -879,6 +883,10 @@ GIT_NOGLOB_PATHSPECS::
Setting this variable to `1` will cause Git to treat all
pathspecs as literal (aka literal magic).
 
+GIT_ICASE_PATHSPECS::
+   Setting this variable to `1` will cause Git to treat all
+   pathspeccs as case-insensitive.
+
 
 Discussion[[Discussion]]
 
diff --git a/Documentation/glossary-content.txt 
b/Documentation/glossary-content.txt
index a3d9029..13a64d3 100644
--- a/Documentation/glossary-content.txt
+++ b/Documentation/glossary-content.txt
@@ -334,6 +334,9 @@ literal;;
Wildcards in the pattern such as `*` or `?` are treated
as literal characters.
 
+icase;;
+   Case insensitive match.
+
 glob;;
Git treats the pattern as a shell glob suitable for
consumption by fnmatch(3) with the FNM_PATHNAME flag:
diff --git a/builtin/add.c b/builtin/add.c
index 1dab246..9d52fc7 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -544,12 +544,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-tree.c b/builtin/ls-tree.c
index 7882352..f6d8215 100644
--- a/builtin/ls-tree.c
+++ b/builtin/ls-tree.c
@@ -173,7 +173,7 @@ 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_GLOB,
+   parse_pathspec(pathspec, PATHSPEC_GLOB | PATHSPEC_ICASE,
   PATHSPEC_PREFER_CWD,
   prefix, argv + 1);
for (i = 0; i  pathspec.nr; i++)
diff --git a/cache.h b/cache.h
index dc4d2ee..3cff825 100644
--- a/cache.h
+++ b/cache.h
@@ -369,6 +369,7 @@ static inline enum object_type object_type(unsigned int 
mode)
 #define GIT_LITERAL_PATHSPECS_ENVIRONMENT GIT_LITERAL_PATHSPECS
 #define GIT_GLOB_PATHSPECS_ENVIRONMENT GIT_GLOB_PATHSPECS
 #define GIT_NOGLOB_PATHSPECS_ENVIRONMENT GIT_NOGLOB_PATHSPECS
+#define GIT_ICASE_PATHSPECS_ENVIRONMENT GIT_ICASE_PATHSPECS
 
 /*
  * This environment variable is expected to contain a boolean indicating
diff --git a/dir.c b/dir.c
index 076bd46..8543736 100644
--- a/dir.c
+++ b/dir.c
@@ -57,7 +57,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;
@@ -66,14 +66,18 @@ 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,
+ 

Re: [PATCH v2 46/46] parse_pathspec: accept :(icase)path syntax

2013-07-14 Thread Eric Sunshine
On Sun, Jul 14, 2013 at 4:36 AM, Nguyễn Thái Ngọc Duy pclo...@gmail.com wrote:
 diff --git a/Documentation/git.txt b/Documentation/git.txt
 index 3571a1b..546eea4 100644
 --- a/Documentation/git.txt
 +++ b/Documentation/git.txt
 @@ -879,6 +883,10 @@ GIT_NOGLOB_PATHSPECS::
 Setting this variable to `1` will cause Git to treat all
 pathspecs as literal (aka literal magic).

 +GIT_ICASE_PATHSPECS::
 +   Setting this variable to `1` will cause Git to treat all
 +   pathspeccs as case-insensitive.

s/pathspeccs/pathspecs/

 @@ -110,16 +114,27 @@ 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. In other words, only prefix is considered common
 +* prefix. If the pathspec is abc/foo abc/bar, running in
 +* subdir xyz, the common prefix is still xyz, not xuz/abc as

s/xuz/xyz/
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] .mailmap: Combine more (email, name) to individual persons

2013-07-14 Thread Stefan Beller
I got more responses from people regarding the .mailmap file.
All added persons gave permission to add them to the .mailmap file.

It's mostly email mappings again. However we also have Nick Stokoe,
who contributed as Nick Woolley. He changed his name, but kept the email.

Signed-off-by: Stefan Beller stefanbel...@googlemail.com
---
 .mailmap | 42 +++---
 1 file changed, 35 insertions(+), 7 deletions(-)

diff --git a/.mailmap b/.mailmap
index 22d3d70..9430d14 100644
--- a/.mailmap
+++ b/.mailmap
@@ -17,6 +17,7 @@ Alexey Shumkin alex.crez...@gmail.com zap...@mail.ru
 Anders Kaseorg ande...@mit.edu ande...@ksplice.com
 Anders Kaseorg ande...@mit.edu ande...@mit.edu
 Aneesh Kumar K.V aneesh.ku...@gmail.com
+Ben Walton bdwal...@gmail.com bwal...@artsci.utoronto.ca
 Bernt Hansen be...@norang.ca be...@alumni.uwaterloo.ca
 Brandon Casey draf...@gmail.com ca...@nrlssc.navy.mil
 Brian M. Carlson sand...@crustytoothpaste.ath.cx
@@ -24,6 +25,8 @@ Bryan Larsen br...@larsen.st bryan.lar...@gmail.com
 Bryan Larsen br...@larsen.st bryanlar...@yahoo.com
 Cheng Renquan crq...@gmail.com
 Chris Shoemaker c.shoema...@cox.net
+Chris Wright chr...@sous-sol.org chr...@osdl.org
+Csaba Henk cs...@gluster.com cs...@lowlife.hu
 Dan Johnson computerdr...@gmail.com
 Dana L. How dana...@gmail.com
 Dana L. How h...@deathvalley.cswitch.com
@@ -44,8 +47,11 @@ Florian Achleitner florian.achleitner.2.6...@gmail.com 
florian.achleitner2.6.
 Franck Bui-Huu vagabon@gmail.com fbui...@gmail.com
 Frank Lichtenheld fr...@lichtenheld.de dj...@debian.org
 Frank Lichtenheld fr...@lichtenheld.de flichtenh...@astaro.com
-Fredrik Kuivinen freku...@student.liu.se
+Fredrik Kuivinen fre...@gmail.com freku...@student.liu.se
 Frédéric Heitzmann frederic.heitzm...@gmail.com
+Garry Dolley gdol...@ucla.edu gdol...@arpnetworks.com
+Greg Price pr...@mit.edu pr...@mit.edu
+Greg Price pr...@mit.edu pr...@ksplice.com
 H. Merijn Brand h.m.br...@xs4all.nl H.Merijn Brand h.m.br...@xs4all.nl
 H. Peter Anvin h...@zytor.com h...@bonde.sc.orionmulti.com
 H. Peter Anvin h...@zytor.com h...@smyrno.hos.anvin.org
@@ -62,6 +68,7 @@ Jason Riedy e...@eecs.berkeley.edu e...@cs.berkeley.edu
 Jay Soffian jaysoff...@gmail.com jaysoffian+...@gmail.com
 Jeff King p...@peff.net p...@github.com
 Jeff Muizelaar jmuizel...@mozilla.com j...@infidigm.net
+Jim Meyering j...@meyering.net meyer...@redhat.com
 Joachim Berdal Haga cjh...@fys.uio.no
 Johannes Schindelin johannes.schinde...@gmx.de johannes.schinde...@gmx.de
 Johannes Sixt j...@kdbg.org j.s...@eudaptics.com
@@ -95,6 +102,7 @@ Kirill Smelkov k...@navytux.spb.ru k...@mns.spb.ru
 Knut Franke knut.fra...@gmx.de k.fra...@science-computing.de
 Lars Doelle lars.doelle@on-line ! de
 Lars Doelle lars.doe...@on-line.de
+Lars Noschinski l...@public.noschinski.de lars.noschin...@rwth-aachen.de
 Li Hong leeh...@pku.edu.cn
 Linus Torvalds torva...@linux-foundation.org torva...@evo.osdl.org
 Linus Torvalds torva...@linux-foundation.org torva...@g5.osdl.org
@@ -112,6 +120,7 @@ Martin Langhoff mar...@laptop.org mar...@catalyst.net.nz
 Martin von Zweigbergk martinv...@gmail.com martin.von.zweigbe...@gmail.com
 Matt Draisey m...@draisey.ca mattdrai...@sympatico.ca
 Matt Kraai kr...@ftbfs.org matt.kr...@amo.abbott.com
+Matt McCutchen m...@mattmccutchen.net hashprod...@gmail.com
 Matthias Kestenholz matth...@spinlock.ch m...@spinlock.ch
 Matthias Urlichs matth...@urlichs.de smurf@kiste.(none)
 Matthias Urlichs matth...@urlichs.de sm...@smurf.noris.de
@@ -120,6 +129,7 @@ Michael J Gruber g...@drmicha.warpmail.net 
michaeljgruber+gm...@fastmail.fm
 Michael W. Olson mwol...@gnu.org
 Michael Witten mfwit...@gmail.com mfwit...@mit.edu
 Michael Witten mfwit...@gmail.com mfwit...@mit.edu
+Michal Rokos michal.ro...@nextsoft.cz ro...@nextsoft.cz
 Michele Ballabio barra_c...@katamail.com
 Miklos Vajna vmik...@frugalware.org vmik...@suse.cz
 Namhyung Kim namhy...@gmail.com namhyung@lge.com
@@ -129,14 +139,19 @@ Nanako Shiraishi nana...@lavabit.com
 Nelson Elhage nelh...@mit.edu nelh...@mit.edu
 Nelson Elhage nelh...@mit.edu nelh...@ksplice.com
 Nguyễn Thái Ngọc Duy pclo...@gmail.com
+Nick Stokoe n...@noodlefactory.co.uk Nick Woolley n...@noodlefactory.co.uk
+Nick Stokoe n...@noodlefactory.co.uk Nick Woolley nickwool...@yahoo.co.uk
 Nicolas Morey-Chaisemartin devel-...@morey-chaisemartin.com 
nicolas.mo...@free.fr
 Nicolas Morey-Chaisemartin devel-...@morey-chaisemartin.com 
nmo...@kalray.eu
+Nicolas Sebrecht nicolas.s@gmx.fr n...@laposte.net
 Paolo Bonzini bonz...@gnu.org paolo.bonz...@lu.unisi.ch
 Pascal Obry pas...@obry.net pascal.o...@gmail.com
 Pascal Obry pas...@obry.net pascal.o...@wanadoo.fr
 Pat Notz patn...@gmail.com pkn...@sandia.gov
 Paul Mackerras pau...@samba.org paulus@dorrigo.(none)
 Paul Mackerras pau...@samba.org paulus@pogo.(none)
+Peter Baumann waste.mana...@gmx.de 
peter.b.baum...@stud.informatik.uni-erlangen.de
+Peter Baumann waste.mana...@gmx.de siprb...@stud.informatik.uni-erlangen.de
 Peter 

[PATCH] more mailmap entries

2013-07-14 Thread Stefan Beller
This patch goes on top of branch sb/mailmap-updates


Stefan Beller (1):
  .mailmap: Combine more (email, name) to individual persons

 .mailmap | 42 +++---
 1 file changed, 35 insertions(+), 7 deletions(-)

-- 
1.8.3.2.804.g0da7a53.dirty

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] send-email: squelch warning from Net::SMTP::SSL

2013-07-14 Thread Ramkumar Ramachandra
Torsten Bögershausen wrote:
 /usr/bin/perl -MIO::Socket::SSL -e 'print $IO::Socket::SSL::VERSION\n;'
 1.22

This is ancient!  (I have 1.84).  Is it not possible to do an
ssl-verify-peer in older versions (is it exported as something else)?
The older versions don't display the warning anyway, and this series
is about squelching the warning in newer versions.  Does

  require IO::Socket::SSL qw(SSL_VERIFY_NONE SSL_VERIFY_PEER) or print
warning: not using SSL_VERIFY_PEER due to outdated IO::Socket::SSL

sound reasonable?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] commit: Fix a memory leak in determine_author_info

2013-07-14 Thread Stefan Beller
The date variable is assigned new memory via xmemdupz and 2 lines later
it is assigned new memory again via xmalloc, but the first assignment
is never freed nor used.
---
 builtin/commit.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 790e5ab..00da83c 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -534,7 +534,6 @@ static void determine_author_info(struct strbuf 
*author_ident)
(lb - strlen( ) -
 (a + strlen(\nauthor ;
email = xmemdupz(lb + strlen(), rb - (lb + strlen()));
-   date = xmemdupz(rb + strlen( ), eol - (rb + strlen( )));
len = eol - (rb + strlen( ));
date = xmalloc(len + 2);
*date = '@';
-- 
1.8.3.2.806.gdee5b9b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread John Keeping
On Sat, Jul 13, 2013 at 01:08:09PM -0700, Junio C Hamano wrote:
 Junio C Hamano gits...@pobox.com writes:
 
  If --lockref automatically implies --allow-no-ff (the design in
  the reposted patch), you cannot express that combination.  But once
  you use --lockref in such a situation , for the push to succeed,
  you know that the push replaces not just _any_ ancestor of what you
  are pushing, but replaces the exact current value.  So I do not think
  your implicit introduction of --allow-no-ff via redefining the
  semantics of the plus prefix is not adding much value (if any),
  while making the common case less easy to use.
 
  No; --lockref only adds the check that the destination is at the
  expected revision, but does *NOT* override the no-ff check.
 
  You _could_ do it in that way, but that is less useful.
 
 Another issue I have with the proposal is that we close the door to
 force only this one convenience we have with +ref vs --force
 ref.  Assuming that it is useful to require lockref while still
 making sure that the usual must fast-forward rule is followed (if
 that is not the case, I do not see a reason why your proposal is any
 useful---am I missing something?), I would prefer to allow users a
 way to decorate this basic syntax to say:
 
 git push --lockref master jch pu
 
 things like
 
  (1) pu may not fast-forward and please override that must
  fast-forward check from it, while still keeping the lockref
  safety (e.g. +pu that does not --force, which is your
  proposal);
 
  (2) any of them may not fast-forward and please override that must
  fast-forward check from it, while still keeping the lockref
  safety (without adding --allow-no-ff, I do not see how it is
  possible with your proposal, short of forcing user to add +
  everywhere);
 
  (3) I know jch does not fast-forward so please override the must
  fast-forward, but still apply the lockref safety, pu may not
  even satisfy lockref safety so please force it (as the only
  force this one semantics is removed from +, I do not see how
  it is possible with your proposal).

I haven't been following this thread too closely, but I was assuming
that the interface would be something like this:

git push origin +master
git push --force origin master

mean the same thing and do what they do now.

git push origin *master
git push --lockref origin master

both mean the same thing: using the new compare-and-swap mode only
update master if the remote side corresponds to remotes/origin/master
[1].

git push origin *master:refs/heads/master:@{1}

means to push the local ref master to the remote ref refs/heads/master
if it currently points at @{1}.

In this scenario, giving both --lockref and --force should be an error
because the user is probably confused (the obvious interpretation is
that --force wins, but I don't think that's sensible).

I'm not sure what should happen with:

git push --force origin *master

where it appears that the user is asking for a compare-and-swap update
of master but the --force is overriding this.  I think we have to let
--force win because when the refspec comes from remote.name.push we
have to let the command-line --force override the specified behaviour.

I don't particularly like the name --lockref, the original --cas feels
more descriptive to me.


[1] In fact, I suspect this would have to be the ref that
refs/heads/master maps to using remote.origin.fetch.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] fixup! pull: require choice between rebase/merge on non-fast-forward pull

2013-07-14 Thread John Keeping
---
On Fri, Jun 28, 2013 at 03:41:34PM -0700, Junio C Hamano wrote:
 John Keeping j...@keeping.me.uk writes:
  I don't think git pull remote branch falls into the same category as
  plain git pull so I'm not convinced that defaulting to merge there is
  unreasonable.  The original message about this [1] did talk about only
  git pull with no arguments.
 
 If you want to limit the scope to only git pull (without any
 command line argument), I actually do not have strong preference for
 or against it either way.  Perhaps a follow-up patch to be squashed?

Here is that patch.  The test changes here are all reverting changes in
ae2dab2 (pull: require choice between rebase/merge on non-fast-forward
pull, 2013-06-27) - with this change to git-pull.sh the only change
needed in the tests is in t5524-pull-msg:

$ git diff ae2dab2^ -- t
diff --git a/t/t5524-pull-msg.sh b/t/t5524-pull-msg.sh
index 8cccecc..660714b 100755
--- a/t/t5524-pull-msg.sh
+++ b/t/t5524-pull-msg.sh
@@ -25,7 +25,7 @@ test_expect_success setup '
 test_expect_success pull '
 (
cd cloned 
-   git pull --log 
+   git pull --log --merge 
git log -2 
git cat-file commit HEAD result 
grep Dollar result

 git-pull.sh| 1 +
 t/annotate-tests.sh| 2 +-
 t/t4013-diff-various.sh| 2 --
 t/t4200-rerere.sh  | 2 --
 t/t5500-fetch-pack.sh  | 6 +-
 t/t5521-pull-options.sh| 2 --
 t/t5700-clone-reference.sh | 4 ++--
 t/t6022-merge-rename.sh| 2 --
 t/t6026-merge-attr.sh  | 2 +-
 t/t6029-merge-subtree.sh   | 1 -
 t/t6037-merge-ours-theirs.sh   | 2 --
 t/t9114-git-svn-dcommit-merge.sh   | 2 +-
 t/t9400-git-cvsserver-server.sh| 2 +-
 t/t9500-gitweb-standalone-no-errors.sh | 2 +-
 14 files changed, 9 insertions(+), 23 deletions(-)

diff --git a/git-pull.sh b/git-pull.sh
index 5ce67f9..0ff4a98 100755
--- a/git-pull.sh
+++ b/git-pull.sh
@@ -279,6 +279,7 @@ case $merge_head in
merge_head=${merge_head% }
if test -z $rebase$no_ff$ff_only${squash#--no-squash} 
test -n $orig_head 
+   test $# = 0 
! $(git merge-base --is-ancestor $orig_head $merge_head)
then
 echo 2 orig-head was $orig_head
diff --git a/t/annotate-tests.sh b/t/annotate-tests.sh
index af02c6d..c56a77d 100644
--- a/t/annotate-tests.sh
+++ b/t/annotate-tests.sh
@@ -79,7 +79,7 @@ test_expect_success \
 
 test_expect_success \
 'merge-setup part 3' \
-'git pull --merge . branch1'
+'git pull . branch1'
 
 test_expect_success \
 'Two lines blamed on A, one on B, two on B1, one on B2' \
diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh
index 1ee2198..e77c09c 100755
--- a/t/t4013-diff-various.sh
+++ b/t/t4013-diff-various.sh
@@ -12,8 +12,6 @@ LF='
 
 test_expect_success setup '
 
-   git config pull.rebase false 
-
GIT_AUTHOR_DATE=2006-06-26 00:00:00 + 
GIT_COMMITTER_DATE=2006-06-26 00:00:00 + 
export GIT_AUTHOR_DATE GIT_COMMITTER_DATE 
diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh
index 0563357..7ff 100755
--- a/t/t4200-rerere.sh
+++ b/t/t4200-rerere.sh
@@ -25,8 +25,6 @@ test_description='git rerere
 . ./test-lib.sh
 
 test_expect_success 'setup' '
-   git config pull.rebase false 
-
cat a1 -\EOF 
Some title
==
diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh
index 4be8877..fd2598e 100755
--- a/t/t5500-fetch-pack.sh
+++ b/t/t5500-fetch-pack.sh
@@ -143,11 +143,7 @@ test_expect_success 'clone shallow depth 1 with fsck' '
 '
 
 test_expect_success 'clone shallow' '
-   git clone --no-single-branch --depth 2 file://$(pwd)/. shallow 
-   (
-   cd shallow 
-   git config pull.rebase false
-   )
+   git clone --no-single-branch --depth 2 file://$(pwd)/. shallow
 '
 
 test_expect_success 'clone shallow depth count' '
diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh
index d821fab..453aba5 100755
--- a/t/t5521-pull-options.sh
+++ b/t/t5521-pull-options.sh
@@ -91,8 +91,6 @@ test_expect_success 'git pull --force' '
[branch master]
remote = two
merge = refs/heads/master
-   [pull]
-   rebase = false
EOF
git pull two 
test_commit A 
diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh
index 306badf..6537911 100755
--- a/t/t5700-clone-reference.sh
+++ b/t/t5700-clone-reference.sh
@@ -94,7 +94,7 @@ cd $base_dir
 
 test_expect_success 'pulling changes from origin' \
 'cd C 
-git pull --merge origin'
+git pull origin'
 
 cd $base_dir
 
@@ -109,7 +109,7 @@ cd $base_dir
 
 test_expect_success 'pulling changes from origin' \
 'cd D 
-git pull --merge origin'
+git pull origin'
 
 cd $base_dir
 
diff --git 

Re: [PATCH] test-lib.sh - cygwin does not have usable FIFOs

2013-07-14 Thread Mark Levedahl

On 07/13/2013 08:57 PM, Jonathan Nieder wrote:
I'm not sure I follow. Are you saying Windows users would never want 
to access Subversion repositories? Thanks, Jonathan 
Quite the contrary. SVN and git both work on Windows without having 
POSIX FIFOs  - Windows does have FIFOS, but the semantics are different 
than POSIX and this is why Cygwin's do not work as needed. There is no 
problem having a subprocess with stdin and stdout redirected via 
anonymous pipes to the parent: this is how git runs sub commands and 
works fine. I'm just questioning why this same construct cannot be used 
for the test harness.


Mark
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] Cygwin has trustable filemode

2013-07-14 Thread Mark Levedahl
The supported Cygwin distribution on supported Windows versions provides
complete support for POSIX filemodes, so enable this by default. git as
distributed by the Cygwin project is configured this way.

This fixes one testsuite failure:
t3300 test 17 (diff-index -M -p with mode change quotes funny filename)

Historical notes: Earlier versions of Cygwin (version 1.5 and prior) had 
various methods for supporting posix file modes on different file systems, 
often using extended attributes, and this support was optional.  Such 
versions of Cygwin are not available on any public mirror and are not 
supported by the Cygwin project. The currently available Cygwin supports 
POSIX file modes without exception - this is not an optional 
configuration. The support does depend upon the underlying file system 
(neither Linux nor Cygwin can set an execute bit on a FAT file system as 
FAT has no such support), but as this is no different than Linux, the
default should not treat Cygwin differently than Linux.  

Users who desire the non-POSIX mode of operation must explicitly set 
core.filemode=False, accepting non-interoperability with Linux.  

Signed-off-by: Mark Levedahl mleved...@gmail.com
---
 config.mak.uname | 1 -
 1 file changed, 1 deletion(-)

diff --git a/config.mak.uname b/config.mak.uname
index 7ac541e..779d06a 100644
--- a/config.mak.uname
+++ b/config.mak.uname
@@ -163,7 +163,6 @@ ifeq ($(uname_O),Cygwin)
NO_THREAD_SAFE_PREAD = YesPlease
NEEDS_LIBICONV = YesPlease
NO_FAST_WORKING_DIRECTORY = UnfortunatelyYes
-   NO_TRUSTABLE_FILEMODE = UnfortunatelyYes
NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease
# There are conflicting reports about this.
# On some boxes NO_MMAP is needed, and not so elsewhere.
-- 
1.8.3.2.0.13

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC/PATCH v2 1/1] cygwin: Add fast_lstat() and fast_fstat() functions

2013-07-14 Thread Mark Levedahl

On 07/10/2013 04:23 PM, Ramsay Jones wrote:

Commit adbc0b6b (cygwin: Use native Win32 API for stat, 30-09-2008)
added a Win32 specific implementation of the stat functions. In order
to handle absolute paths, cygwin mount points and symbolic links, this
implementation may fall back on the standard cygwin l/stat() functions.
Also, the choice of cygwin or Win32 functions is made lazily (by the
first call(s) to l/stat) based on the state of some config variables.

Unfortunately, this schizophrenic stat implementation has been the
source of many problems ever since. For example, see commits 7faee6b8,
79748439, 452993c2, 085479e7, b8a97333, 924aaf3e, 05bab3ea and 0117c2f0.

In order to limit the adverse effects caused by this implementation,
we provide a new fast stat interface, which allows us to use this
only for interactions with the index (i.e. the cached stat data).

Signed-off-by: Ramsay Jones ram...@ramsay1.demon.co.uk
---


I've tested this on Cygwin 1.7 on WIndows 7 , comparing to the results 
using your prior patch (removing the Cygwin specific lstat entirely) and 
get the same results with both, so this seems ok from me.


My comparison point was created by reverting your current patch from pu, 
then reapplying your earlier patch on top, so the only difference was 
which approach was used to address the stat functions.


Caveats:
1) I don't find any speed improvement of the current patch over the 
previous one (the tests actually ran faster with the earlier patch, 
though the difference was less than 1%).
2) I still question this whole approach, especially having this 
non-POSIX compliant mode be the default. Running in this mode breaks 
interoperability with Linux, but providing a Linux environment is the 
*primary* goal of Cygwin.


Mark
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 0/6] Update to janitorial work on hook templates

2013-07-14 Thread Richard Hartmann
Dear all,

I worked Jeff's and Junio's feedback into this patch series, referencing
the old commits.

As stated earlier, you are welcome to drop 1/6, but 2/6 depends on it.
Your choice, both is fine by me.

Thanks,
Richard

Richard Hartmann (6):
  templates: Use heredoc in pre-commit hook
  templates: Reformat pre-commit hook's message
  templates: Fix spelling in pre-commit hook
  Documentation: Update manpage for pre-commit hook
  templates: Fix ASCII art in pre-rebase hook
  template: Fix comment indentation in pre-rebase hook

 Documentation/githooks.txt |3 ++-
 templates/hooks--pre-commit.sample |   27 +--
 templates/hooks--pre-rebase.sample |   26 +-
 3 files changed, 28 insertions(+), 28 deletions(-)

-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/6] Documentation: Update manpage for pre-commit hook

2013-07-14 Thread Richard Hartmann
Verbatim copy of 4b8234b2693af634a77ea059331d1658e070f6d7 in original
patch series from 2013-06-10.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 Documentation/githooks.txt |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt
index b9003fe..1276730 100644
--- a/Documentation/githooks.txt
+++ b/Documentation/githooks.txt
@@ -80,7 +80,8 @@ causes the 'git commit' to abort.
 
 The default 'pre-commit' hook, when enabled, catches introduction
 of lines with trailing whitespaces and aborts the commit when
-such a line is found.
+such a line is found. It will also prevent addition of non-ASCII
+file names.
 
 All the 'git commit' hooks are invoked with the environment
 variable `GIT_EDITOR=:` if the command will not bring up an editor
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 6/6] template: Fix comment indentation in pre-rebase hook

2013-07-14 Thread Richard Hartmann
The other hooks use two whitespace for indentation instead of tabs
to signify code in the example/echo output.
Follow the same layout in templates/hooks--pre-rebase.sample

Based on d153a68bebfabc1db5241d02ee75fa5cb4538ab0 in original patch
series from 2013-06-10.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 templates/hooks--pre-rebase.sample |   10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/templates/hooks--pre-rebase.sample 
b/templates/hooks--pre-rebase.sample
index b74cd1d..cec3474 100755
--- a/templates/hooks--pre-rebase.sample
+++ b/templates/hooks--pre-rebase.sample
@@ -157,13 +157,13 @@ B to be deleted.
 
 To compute (1):
 
-   git rev-list ^master ^topic next
-   git rev-list ^masternext
+  git rev-list ^master ^topic next
+  git rev-list ^masternext
 
-   if these match, topic has not merged in next at all.
+if these match, topic has not merged in next at all.
 
 To compute (2):
 
-   git rev-list master..topic
+  git rev-list master..topic
 
-   if this is empty, it is fully merged to master.
+if this is empty, it is fully merged to master.
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Richard Hartmann
Spawning a new subprocess for every line printed is inefficient.
Use heredoc, instead.

Based on 98770971aef8d1cbc78876d9023d10aa25df0526 in original patch
series from 2013-06-10.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 templates/hooks--pre-commit.sample |   25 +
 1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/templates/hooks--pre-commit.sample 
b/templates/hooks--pre-commit.sample
index 18c4829..889967c 100755
--- a/templates/hooks--pre-commit.sample
+++ b/templates/hooks--pre-commit.sample
@@ -31,18 +31,19 @@ if [ $allownonascii != true ] 
test $(git diff --cached --name-only --diff-filter=A -z $against |
  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
 then
-   echo Error: Attempt to add a non-ascii file name.
-   echo
-   echo This can cause problems if you want to work
-   echo with people on other platforms.
-   echo
-   echo To be portable it is advisable to rename the file ...
-   echo
-   echo If you know what you are doing you can disable this
-   echo check using:
-   echo
-   echo   git config hooks.allownonascii true
-   echo
+   cat -EOF
+Error: Attempt to add a non-ascii file name.
+
+This can cause problems if you want to work
+with people on other platforms.
+
+To be portable it is advisable to rename the file.
+
+If you know what you are doing you can disable this
+check using:
+
+  git config hooks.allownonascii true
+EOF
exit 1
 fi
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/6] templates: Reformat pre-commit hook's message

2013-07-14 Thread Richard Hartmann
Now that we're using heredoc, the message can span the full 80 chars.

Verbatim copy of 634709b489bb3db79f59127fd6bf79c5fd9b5ddf in original
patch series from 2013-06-10.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 templates/hooks--pre-commit.sample |6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/templates/hooks--pre-commit.sample 
b/templates/hooks--pre-commit.sample
index 889967c..e09cf89 100755
--- a/templates/hooks--pre-commit.sample
+++ b/templates/hooks--pre-commit.sample
@@ -34,13 +34,11 @@ then
cat -EOF
 Error: Attempt to add a non-ascii file name.
 
-This can cause problems if you want to work
-with people on other platforms.
+This can cause problems if you want to work with people on other platforms.
 
 To be portable it is advisable to rename the file.
 
-If you know what you are doing you can disable this
-check using:
+If you know what you are doing you can disable this check using:
 
   git config hooks.allownonascii true
 EOF
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/6] templates: Fix spelling in pre-commit hook

2013-07-14 Thread Richard Hartmann
Based on 0b9b01276553de8097442c3c996b7a49367dd234 in original patch
series.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 templates/hooks--pre-commit.sample |6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/templates/hooks--pre-commit.sample 
b/templates/hooks--pre-commit.sample
index e09cf89..78baef6 100755
--- a/templates/hooks--pre-commit.sample
+++ b/templates/hooks--pre-commit.sample
@@ -15,13 +15,13 @@ else
against=4b825dc642cb6eb9a060e54bf8d69288fbee4904
 fi
 
-# If you want to allow non-ascii filenames set this variable to true.
+# If you want to allow non-ASCII filenames set this variable to true.
 allownonascii=$(git config hooks.allownonascii)
 
 # Redirect output to stderr.
 exec 12
 
-# Cross platform projects tend to avoid non-ascii filenames; prevent
+# Cross platform projects tend to avoid non-ASCII filenames; prevent
 # them from being added to the repository. We exploit the fact that the
 # printable range starts at the space character and ends with tilde.
 if [ $allownonascii != true ] 
@@ -32,7 +32,7 @@ if [ $allownonascii != true ] 
  LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
 then
cat -EOF
-Error: Attempt to add a non-ascii file name.
+Error: Attempt to add a non-ASCII file name.
 
 This can cause problems if you want to work with people on other platforms.
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 5/6] templates: Fix ASCII art in pre-rebase hook

2013-07-14 Thread Richard Hartmann
The example assumes 8-char wide tabs and breaks for people with
4-char wide tabs. Convert all of those tabs to whitespace, instead.

Verbatim copy of 11edd8a05778700382e6a21cfc0a6b5b72eff852 in original
patch series from 2013-06-10.

Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
---
 templates/hooks--pre-rebase.sample |   16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/templates/hooks--pre-rebase.sample 
b/templates/hooks--pre-rebase.sample
index 053f111..b74cd1d 100755
--- a/templates/hooks--pre-rebase.sample
+++ b/templates/hooks--pre-rebase.sample
@@ -132,14 +132,14 @@ With this workflow, you would want to know:
 
 Let's look at this example:
 
-  o---o---o---o---o---o---o---o---o---o next
- /   /   /   /
-/   a---a---b A /   /
-   /   /   /   /
-  /   /   c---c---c---c B /
- /   /   / \ /
-/   /   /   b---b C \   /
-   /   /   /   / \ /
+   o---o---o---o---o---o---o---o---o---o next
+  /   /   /   /
+ /   a---a---b A /   /
+/   /   /   /
+   /   /   c---c---c---c B /
+  /   /   / \ /
+ /   /   /   b---b C \   /
+/   /   /   / \ /
 ---o---o---o---o---o---o---o---o---o---o---o master
 
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] send-email: squelch warning from Net::SMTP::SSL

2013-07-14 Thread brian m. carlson
On Sun, Jul 14, 2013 at 07:19:10PM +0530, Ramkumar Ramachandra wrote:
 Torsten Bögershausen wrote:
  /usr/bin/perl -MIO::Socket::SSL -e 'print $IO::Socket::SSL::VERSION\n;'
  1.22
 
 This is ancient!  (I have 1.84).  Is it not possible to do an
 ssl-verify-peer in older versions (is it exported as something else)?
 The older versions don't display the warning anyway, and this series
 is about squelching the warning in newer versions.  Does
 
   require IO::Socket::SSL qw(SSL_VERIFY_NONE SSL_VERIFY_PEER) or print
 warning: not using SSL_VERIFY_PEER due to outdated IO::Socket::SSL

require doesn't take a list of symbols to import, and the import dies if
it fails.  You need:

require IO::Socket::SSL;
eval {
IO::Socket::SSL-import(qw(SSL_VERIFY_NONE SSL_VERIFY_PEER));
};
if ($@) {
warn Not using SSL_VERIFY_PEER due to outdated IO::Socket::SSL\n;
# Do something different here.
}

I didn't stick the require in the eval because git-send-email will fail
in this case anyway if you don't have it, since Net::SMTP::SSL requires
it.  Let me know if you want a patch for this on top of the existing two
in this series and I'll provide one.

-- 
brian m. carlson / brian with sandals: Houston, Texas, US
+1 832 623 2791 | http://www.crustytoothpaste.net/~bmc | My opinion only
OpenPGP: RSA v4 4096b: 88AC E9B2 9196 305B A994 7552 F1BA 225C 0223 B187


signature.asc
Description: Digital signature


Re: [PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Jonathan Nieder
Hi,

Richard Hartmann wrote:

 Spawning a new subprocess for every line printed is inefficient.
 Use heredoc, instead.

I think this makes sense as a code clarity, simplicity, and
internationalizability improvement, but don't like the precedent of
eliminating 'echo' for the sake of fork removal (unless we have
measurements showing it's worthwhile, which would be included here).

Maybe a simpler commit message could sidestep the issue?

Use a heredoc instead of an echo for each line.

 Based on 98770971aef8d1cbc78876d9023d10aa25df0526 in original patch
 series from 2013-06-10.

Please don't include this.  The audience for the commit message
doesn't have that commit to compare to.

If you want to preserve the original date, the way to do that is
a Date: field at the top of the message body.

Date: Fri, 28 Jun 2013 21:16:19 +0530

Spawning a new subprocess for ...

[...]
 --- a/templates/hooks--pre-commit.sample
 +++ b/templates/hooks--pre-commit.sample
 @@ -31,18 +31,19 @@ if [ $allownonascii != true ] 
   test $(git diff --cached --name-only --diff-filter=A -z $against |
 LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
  then
 - echo Error: Attempt to add a non-ascii file name.
 - echo
 - echo This can cause problems if you want to work
 - echo with people on other platforms.
 - echo
 - echo
 - echo If you know what you are doing you can disable this
 - echo check using:
 - echo
 - echo   git config hooks.allownonascii true
 - echo
 + cat -EOF
 +Error: Attempt to add a non-ascii file name.

Using

cat \EOF

would make reading easier since the reader then doesn't have to worry
about whether the text being cat'ed is indented or uses variable
substitutions.

 - echo To be portable it is advisable to rename the file ...
 +To be portable it is advisable to rename the file.

Yes, nice.

With the above nits addressed, this change looks to be going in the
right direction.  Thanks.

Hope that helps,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/6] templates: Reformat pre-commit hook's message

2013-07-14 Thread Jonathan Nieder
Richard Hartmann wrote:

 Now that we're using heredoc, the message can span the full 80 chars.

The output is going to a console and not an email, so makes sense. :)

 Verbatim copy of 634709b489bb3db79f59127fd6bf79c5fd9b5ddf in original
 patch series from 2013-06-10.

As in patch 1, please drop this.  I'll stop mentioning that for the
later patches, but the same comment applies there.

Thanks,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/6] Documentation: Update manpage for pre-commit hook

2013-07-14 Thread Jonathan Nieder
Richard Hartmann wrote:

 --- a/Documentation/githooks.txt
 +++ b/Documentation/githooks.txt
 @@ -80,7 +80,8 @@ causes the 'git commit' to abort.
  
  The default 'pre-commit' hook, when enabled, catches introduction
  of lines with trailing whitespaces and aborts the commit when
 -such a line is found.
 +such a line is found. It will also prevent addition of non-ASCII
 +file names.

The tenses are inconsistent here (catches versus will also).

It also seems odd to call the sample hooks default hooks, but that's
a wider problem and should probably be fixed by one commit all at once
(maybe imitating the wording of the prepare-commit-message
description).  Previously enabling them was a matter of a chmod +x
and the wording made more sense.

How about:

The default 'pre-commit' hook, when enabled, prevents introduction
of lines with trailing whitespace and prevents introduction of
files with non-ASCII filenames unless the hooks.allowNonAscii
configuration variable is true.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 5/6] templates: Fix ASCII art in pre-rebase hook

2013-07-14 Thread Jonathan Nieder
Richard Hartmann wrote:

 The example assumes 8-char wide tabs and breaks for people with
 4-char wide tabs. Convert all of those tabs to whitespace, instead.

Makes sense --- we cannot assume much about the end-user's editor
setup used to look at sample hooks.

Thanks.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] git-clone.txt: remove the restriction on pushing from a shallow clone

2013-07-14 Thread Junio C Hamano
Duy Nguyen pclo...@gmail.com writes:

 On Sun, Jul 14, 2013 at 4:25 AM, Jonathan Nieder jrnie...@gmail.com wrote:
 Hi,

 Nguyễn Thái Ngọc Duy wrote:

 Since 52fed6e (receive-pack: check connectivity before concluding git
 push - 2011-09-02), receive-pack is prepared to deal with broken
 push, a shallow push can't cause any corruption. Update the document
 to reflect that.

 Hmm, what happens when pushing to servers without that commit?  Do you
 think it should be applied to Debian squeeze for server operators that
 haven't upgraded yet to the current stable release?

 This is pushing _from_ a shallow repo, where the sender repo's old
 objects is a subset of the receiver's.

The subset assumption does not necessarily hold, does it?  The
receiver may have rewound its tips and pruned since then.

Also, the sender may have cloned from the receiver (fully) and then
fetched a different history shallowly from elsewhere.  The receiver
may have no commit on that history, including the shallow-bottom.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/6] template: Fix comment indentation in pre-rebase hook

2013-07-14 Thread Jonathan Nieder
Richard Hartmann wrote:

 The other hooks use two whitespace for indentation instead of tabs
 to signify code in the example/echo output.
 Follow the same layout in templates/hooks--pre-rebase.sample

I don't understand the point of this one.  Is it just consistency for
the sake of consistency?  Aren't other parts of git inconsistent in
this area?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Junio C Hamano
Johannes Sixt j...@kdbg.org writes:

 All you have been saying is that you find your

git push --lockref there topic

 is more useful than my

git push --lockref there +topic

 You are trading crystal clear semantics to save users ONE character to
 type. IMO, it's a bad deal.

Think how you would explain the option in a tutorial for those who
use the push.default=simple semantics.


You usually do

$ git pull [--rebase]

to integrate with the shared branch and push it back with

$ git push

Sometimes the project wants to rewind the tip of such a
shared branch (perhaps a bad commit included inappropriate
material that should not be in the history).  You cordinate
the decision to do such a rewinding with others in the
project, you git rebase [-i] to prepare a replacement
history, and then try to push tthe result out.  However

$ git push

will fail, because this does not fast-forward.  But you and
your colleagues agreed that the project wants this new
history!

With older Git, the only way to make this push go through
was to --force it.  That will risk losing work of other
people who were not aware of the collective decision to
rewind this shared branch [discussion of lockref safety
comes here].  Instead you can use

$ git push --lockref



How does the last line look with your --lockref does not override
must-fast-forward proposal?



If your current branch is configured to push to update the
branch 'frotz' of the remote 'origin' (replace these two
appropriately for your situation), you would say:

$ git push --lockref origin +HEAD:frotz



How is that crystal clear?  You are just making things more complex
and harder to learn (I was tempted to add for no good reason here,
but I'd assume that probably you haven't explained your reasons well
enough to be heard).

 The crystal clear semantics would be:

  - to override no-ff safety, use +refspec;

  - to override mismatch safety, do not use --lockref/use --no-lockref;

  - do not use --force unless you know the consequences.

Alternatively, this is also crystal clear

 - to use the full safety, do not use anything funky

 - to push a history that does not fast-forward safely, use
   --lockref

 - do not use --force unless you know the consequences.

and that is what the patch does.

 I actually think that by implying allow-no-ff in --lockref, you are
 hurting users who have configured a push refspec without a + prefix:
 They suddenly do not get the push denied when it is not a fast-forward
 anymore.

Of course, that is why you should not use --lockref when you do not
have to.  It is a tool to loosen must fast-forward in a more
controlled way than the traditional --force.

 For example, when you have

 [remote ko]
 push = master
 push = +pu

 and you accidentally rewound master before the point that is already
 published, then

git push --lockref ko

 will happily push the rewound master.

Yes, and I am not (and I do expect nobody is) stupid to use --lockref
in such a situation where there is no need to do so.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Junio C Hamano
Richard Hartmann richih.mailingl...@gmail.com writes:

 Spawning a new subprocess for every line printed is inefficient.

This is not a valid justification at all, is it?  

Shells on modern distros and platforms have echo built-in, so this
patch replaces series of writes internal to the shell with a fork to
cat with heredoc (which often is implemented with a temporary file).




 Use heredoc, instead.

 Based on 98770971aef8d1cbc78876d9023d10aa25df0526 in original patch
 series from 2013-06-10.

 Signed-off-by: Richard Hartmann richih.mailingl...@gmail.com
 ---
  templates/hooks--pre-commit.sample |   25 +
  1 file changed, 13 insertions(+), 12 deletions(-)

 diff --git a/templates/hooks--pre-commit.sample 
 b/templates/hooks--pre-commit.sample
 index 18c4829..889967c 100755
 --- a/templates/hooks--pre-commit.sample
 +++ b/templates/hooks--pre-commit.sample
 @@ -31,18 +31,19 @@ if [ $allownonascii != true ] 
   test $(git diff --cached --name-only --diff-filter=A -z $against |
 LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
  then
 - echo Error: Attempt to add a non-ascii file name.
 - echo
 - echo This can cause problems if you want to work
 - echo with people on other platforms.
 - echo
 - echo To be portable it is advisable to rename the file ...
 - echo
 - echo If you know what you are doing you can disable this
 - echo check using:
 - echo
 - echo   git config hooks.allownonascii true
 - echo
 + cat -EOF
 +Error: Attempt to add a non-ascii file name.
 +
 +This can cause problems if you want to work
 +with people on other platforms.
 +
 +To be portable it is advisable to rename the file.
 +
 +If you know what you are doing you can disable this
 +check using:
 +
 +  git config hooks.allownonascii true
 +EOF
   exit 1
  fi
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Richard Hartmann
On Sun, Jul 14, 2013 at 9:20 PM, Junio C Hamano gits...@pobox.com wrote:

 Shells on modern distros and platforms have echo built-in, so this
 patch replaces series of writes internal to the shell with a fork to
 cat with heredoc (which often is implemented with a temporary file).

True; fwiw, I replaced my one single echo with heredoc as you
suggested I do that. I don't mind undoing that, or I can drop it from
this series altogether.

Guidance would be appreciated. :)


Richard
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Johannes Sixt
Am 14.07.2013 21:17, schrieb Junio C Hamano:
 Johannes Sixt j...@kdbg.org writes:
 I actually think that by implying allow-no-ff in --lockref, you are
 hurting users who have configured a push refspec without a + prefix:
 They suddenly do not get the push denied when it is not a fast-forward
 anymore.
 
 Of course, that is why you should not use --lockref when you do not
 have to.  It is a tool to loosen must fast-forward in a more
 controlled way than the traditional --force.

Sorry, IMO, this goes into a totally wrong direction, in particular, I
think that this is going to close to door to make --lockref the default
some day in a way that helps everyone.

I think I have not understood your motivations for this feature, and I
am not able spend more mindwidth on arguing back and forth to make it
more usable (again: IMO).

So, I bow out, and I appologize to have wasted so much of your time.

-- Hannes

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Jonathan Nieder
Richard Hartmann wrote:

   fwiw, I replaced my one single echo with heredoc as you
 suggested I do that. I don't mind undoing that, or I can drop it from
 this series altogether.

 Guidance would be appreciated. :)

Thanks for your work, and no problem.

Both Junio's and my responses were about the (confusing and false)
commit message.  Code is not the only thing that matters when
submitting a patch --- commit messages become part of the product,
too, and are especially important as documentation that guides future
contributors.

So my advice is to fix the commit message, prepare improvements to
later patches in the series with help from reviewers where needed,
and then resubmit.

My review also included some advice about the code.  Naturally I
would be happy if that was of use, too. ;-)

Hope that helps,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Jonathan Nieder
Johannes Sixt wrote:

 Sorry, IMO, this goes into a totally wrong direction, in particular, I
 think that this is going to close to door to make --lockref the default
 some day in a way that helps everyone.

Would a '*' that acts like --lockref on a per ref basis address your
concerns?

I realize that that design would hurt a project of making '+' use
lockref automatically some day.  I think that's ok, and that '+'
meaning push whatever I have, regardless of what's on the other end,
and I mean it would be better semantics in the long term (which
doesn't match the current behavior either :/).

Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Jonathan Nieder
Jonathan Nieder wrote:
 Johannes Sixt wrote:

 Sorry, IMO, this goes into a totally wrong direction, in particular, I
 think that this is going to close to door to make --lockref the default
 some day in a way that helps everyone.

 Would a '*' that acts like --lockref on a per ref basis address your
 concerns?

(Aside: '*' is not a great character for that.  * is already taken in
refspec syntax.  There's no clash but the two uses would be confusing.

*:
*:*

Some other single-character prefix could work, such as '.' or '~'.)
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Johannes Sixt
Am 14.07.2013 22:34, schrieb Jonathan Nieder:
 Johannes Sixt wrote:
 
 Sorry, IMO, this goes into a totally wrong direction, in particular, I
 think that this is going to close to door to make --lockref the default
 some day in a way that helps everyone.
 
 Would a '*' that acts like --lockref on a per ref basis address your
 concerns?

No, because I think that new syntax is not necessary.

But admittedly, I haven't spent any time to think about push.default
modes other than 'matching'. In particular, I wonder how Junio's last
example with push.default=simple can work today:

   $ git pull --rebase  # not a merge
   $ git push

because it is not a fast-forward. I am assuming that a +refspec must be
in the game somehow. Why would we then need that --lockref implies
allow-no-ff when we already have +refspec that already means allow-no-ff?

But as I said, I'm not familiar with push.default other than matching
and my assumption may be wrong.

-- Hannes

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 1/4] daemon.c:handle: Remove unneeded check for null pointer.

2013-07-14 Thread Stefan Beller
addr doesn't need to be checked at that line as it it already accessed
7 lines before in the if (addr-sa_family).

Signed-off-by: Stefan Beller stefanbel...@googlemail.com
---
 daemon.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/daemon.c b/daemon.c
index 6aeddcb..5e48c1e 100644
--- a/daemon.c
+++ b/daemon.c
@@ -754,19 +754,19 @@ static void handle(int incoming, struct sockaddr *addr, 
socklen_t addrlen)
}
 
if (addr-sa_family == AF_INET) {
struct sockaddr_in *sin_addr = (void *) addr;
inet_ntop(addr-sa_family, sin_addr-sin_addr, addrbuf + 12,
sizeof(addrbuf) - 12);
snprintf(portbuf, sizeof(portbuf), REMOTE_PORT=%d,
ntohs(sin_addr-sin_port));
 #ifndef NO_IPV6
-   } else if (addr  addr-sa_family == AF_INET6) {
+   } else if (addr-sa_family == AF_INET6) {
struct sockaddr_in6 *sin6_addr = (void *) addr;
 
char *buf = addrbuf + 12;
*buf++ = '['; *buf = '\0'; /* stpcpy() is cool */
inet_ntop(AF_INET6, sin6_addr-sin6_addr, buf,
sizeof(addrbuf) - 13);
strcat(buf, ]);
 
snprintf(portbuf, sizeof(portbuf), REMOTE_PORT=%d,
-- 
1.8.3.2.806.gdee5b9b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/4] diff-no-index: Remove unused variable.

2013-07-14 Thread Stefan Beller
Signed-off-by: Stefan Beller stefanbel...@googlemail.com
---
 diff-no-index.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/diff-no-index.c b/diff-no-index.c
index e66fdf3..842add4 100644
--- a/diff-no-index.c
+++ b/diff-no-index.c
@@ -181,19 +181,18 @@ static int queue_diff(struct diff_options *o,
}
 }
 
 void diff_no_index(struct rev_info *revs,
   int argc, const char **argv,
   int nongit, const char *prefix)
 {
int i, prefixlen;
int no_index = 0;
-   unsigned options = 0;
const char *paths[2];
 
/* Were we asked to do --no-index explicitly? */
for (i = 1; i  argc; i++) {
if (!strcmp(argv[i], --)) {
i++;
break;
}
if (!strcmp(argv[i], --no-index))
@@ -218,22 +217,20 @@ void diff_no_index(struct rev_info *revs,
if (argc != i + 2)
usagef(git diff %s path path,
   no_index ? --no-index : [--no-index]);
 
diff_setup(revs-diffopt);
for (i = 1; i  argc - 2; ) {
int j;
if (!strcmp(argv[i], --no-index))
i++;
-   else if (!strcmp(argv[i], -q)) {
-   options |= DIFF_SILENT_ON_REMOVED;
+   else if (!strcmp(argv[i], -q))
i++;
-   }
else if (!strcmp(argv[i], --))
i++;
else {
j = diff_opt_parse(revs-diffopt, argv + i, argc - i);
if (!j)
die(invalid diff option/value: %s, argv[i]);
i += j;
}
}
-- 
1.8.3.2.806.gdee5b9b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 2/4] commit: Fix a memory leak in determine_author_info

2013-07-14 Thread Stefan Beller
The date variable is assigned new memory via xmemdupz and 2 lines later
it is assigned new memory again via xmalloc, but the first assignment
is never freed nor used.

Signed-off-by: Stefan Beller stefanbel...@googlemail.com
---
 builtin/commit.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/builtin/commit.c b/builtin/commit.c
index 790e5ab..00da83c 100644
--- a/builtin/commit.c
+++ b/builtin/commit.c
@@ -528,19 +528,18 @@ static void determine_author_info(struct strbuf 
*author_ident)
 
if (lb == a + strlen(\nauthor ))
/* \nauthor f...@example.com */
name = xcalloc(1, 1);
else
name = xmemdupz(a + strlen(\nauthor ),
(lb - strlen( ) -
 (a + strlen(\nauthor ;
email = xmemdupz(lb + strlen(), rb - (lb + strlen()));
-   date = xmemdupz(rb + strlen( ), eol - (rb + strlen( )));
len = eol - (rb + strlen( ));
date = xmalloc(len + 2);
*date = '@';
memcpy(date + 1, rb + strlen( ), len);
date[len + 1] = '\0';
}
 
if (force_author) {
const char *lb = strstr(force_author,  );
-- 
1.8.3.2.806.gdee5b9b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/4] diff.c: Do not initialize a variable, which gets reassigned anyway.

2013-07-14 Thread Stefan Beller
Signed-off-by: Stefan Beller stefanbel...@googlemail.com
---
 diff.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/diff.c b/diff.c
index e53ddad..24382d7 100644
--- a/diff.c
+++ b/diff.c
@@ -1677,21 +1677,19 @@ static void show_stats(struct diffstat_t *data, struct 
diff_options *options)
}
 
/*
 * scale the add/delete
 */
add = added;
del = deleted;
 
if (graph_width = max_change) {
-   int total = add + del;
-
-   total = scale_linear(add + del, graph_width, 
max_change);
+   int total = scale_linear(add + del, graph_width, 
max_change);
if (total  2  add  del)
/* width = 2 due to the sanity check */
total = 2;
if (add  del) {
add = scale_linear(add, graph_width, 
max_change);
del = total - add;
} else {
del = scale_linear(del, graph_width, 
max_change);
add = total - del;
-- 
1.8.3.2.806.gdee5b9b

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/4] daemon.c:handle: Remove unneeded check for null pointer.

2013-07-14 Thread Jonathan Nieder
Hi,

Stefan Beller wrote:

 addr doesn't need to be checked at that line as it it already accessed
 7 lines before in the if (addr-sa_family).

Good catch.  This asymmetry has been present since the lines were first
introduced (all guarded by if (addr)) in v1.4.1-rc1~3^2~4 (Log peer
address when git-daemon called from inetd, 2006-06-20).

 --- a/daemon.c
 +++ b/daemon.c
 @@ -754,19 +754,19 @@ static void handle(int incoming, struct sockaddr *addr, 
 socklen_t addrlen)
   }
  
   if (addr-sa_family == AF_INET) {
   struct sockaddr_in *sin_addr = (void *) addr;
   inet_ntop(addr-sa_family, sin_addr-sin_addr, addrbuf + 12,
   sizeof(addrbuf) - 12);
   snprintf(portbuf, sizeof(portbuf), REMOTE_PORT=%d,
   ntohs(sin_addr-sin_port));
  #ifndef NO_IPV6
 - } else if (addr  addr-sa_family == AF_INET6) {
 + } else if (addr-sa_family == AF_INET6) {

At this point 'addr' is ss.sa from service_loop, so it really cannot
be NULL.

So fwiw, I like this patch.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 2/4] commit: Fix a memory leak in determine_author_info

2013-07-14 Thread Jonathan Nieder
Stefan Beller wrote:

 Signed-off-by: Stefan Beller stefanbel...@googlemail.com

Thanks.  That was quick. :)

Reviewed-by: Jonathan Nieder jrnie...@gmail.com
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] send-email: squelch warning from Net::SMTP::SSL

2013-07-14 Thread Ramkumar Ramachandra
brian m. carlson wrote:
 I didn't stick the require in the eval because git-send-email will fail
 in this case anyway if you don't have it, since Net::SMTP::SSL requires
 it.  Let me know if you want a patch for this on top of the existing two
 in this series and I'll provide one.

Yeah, that'd be nice.  I'm not enjoying this Perl-wrestling very much.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 3/4] diff-no-index: Remove unused variable.

2013-07-14 Thread Jonathan Nieder
Stefan Beller wrote:

 [Subject: diff-no-index: Remove unused variable.]
[...]
 --- a/diff-no-index.c
 +++ b/diff-no-index.c
[...]
 - else if (!strcmp(argv[i], -q)) {
 + else if (!strcmp(argv[i], -q))
 - options |= DIFF_SILENT_ON_REMOVED;
   i++;
 - }

This feature was obviously never tested with --no-index, so I agree it
makes sense to remove it.  Probably the commit message and a comment
should say so, though.  E.g.:

diff --no-index: remove nonfunctional -q handling

Before v1.5.6-rc1~41^2~2, the option parsing for diff --no-index
and git diff-files shared code.  In git diff-files, -q means
to be silent about removed files.  In git diff --no-index, in
various versions it has been an error, an infinite loop, or a no-op.

Simplify the code to clarify that it is now a no-op, continuing to
accept and ignore the -q option in git diff --no-index to avoid
breaking scripts.

I wouldn't mind removing support for -q altogether, by the way (as a
separate change).

Hope that helps,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 4/4] diff.c: Do not initialize a variable, which gets reassigned anyway.

2013-07-14 Thread Jonathan Nieder
Stefan Beller wrote:

 Signed-off-by: Stefan Beller stefanbel...@googlemail.com
 ---
  diff.c | 4 +---
  1 file changed, 1 insertion(+), 3 deletions(-)
[...]
 --- a/diff.c
 +++ b/diff.c
 @@ -1677,21 +1677,19 @@ static void show_stats(struct diffstat_t *data, 
 struct diff_options *options)
   }
  
   /*
* scale the add/delete
*/
   add = added;
   del = deleted;
  
   if (graph_width = max_change) {
 - int total = add + del;
 -
 - total = scale_linear(add + del, graph_width, 
 max_change);
 + int total = scale_linear(add + del, graph_width, 
 max_change);

Yeah, we should have caught this in review.

Thanks for reporting.
Reviewed-by: Jonathan Nieder jrnie...@gmail.com
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] gitweb: Ensure OPML text fits inside its box.

2013-07-14 Thread Jonathan Nieder
Tony Finch wrote:

 The rss_logo CSS style has a fixed width which is too narrow for
 the string OPML. Replace the fixed width with horizontal padding
 so the text fits with nice margins.

Sounds sensible.  Can we have your sign-off?  (Likewise for the next
patch.)

Thanks,
Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] git-clone.txt: remove the restriction on pushing from a shallow clone

2013-07-14 Thread Duy Nguyen
On Mon, Jul 15, 2013 at 1:52 AM, Junio C Hamano gits...@pobox.com wrote:
 Duy Nguyen pclo...@gmail.com writes:

 On Sun, Jul 14, 2013 at 4:25 AM, Jonathan Nieder jrnie...@gmail.com wrote:
 Hi,

 Nguyễn Thái Ngọc Duy wrote:

 Since 52fed6e (receive-pack: check connectivity before concluding git
 push - 2011-09-02), receive-pack is prepared to deal with broken
 push, a shallow push can't cause any corruption. Update the document
 to reflect that.

 Hmm, what happens when pushing to servers without that commit?  Do you
 think it should be applied to Debian squeeze for server operators that
 haven't upgraded yet to the current stable release?

 This is pushing _from_ a shallow repo, where the sender repo's old
 objects is a subset of the receiver's.

 The subset assumption does not necessarily hold, does it?  The
 receiver may have rewound its tips and pruned since then.

 Also, the sender may have cloned from the receiver (fully) and then
 fetched a different history shallowly from elsewhere.  The receiver
 may have no commit on that history, including the shallow-bottom.


Hmm.. right. And the receiver needs to setup proper graft to seal the
shallow bottom. So it's really not safe to do pushing from a shallow
repo without 52fed6e
--
Duy
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] mailmap: Testing the single letter name case.

2013-07-14 Thread Eric Sunshine
On Sat, Jul 13, 2013 at 4:20 PM, Junio C Hamano gits...@pobox.com wrote:
 Stefan Beller stefanbel...@googlemail.com writes:

 Indeed the patch tests for both bugs unintentionally.

 I was puzzled because I do not think that is what is happening with
 the posted patch.

 The off-by-one fix seems to be correct from code inspection, but the
 new test does not seem to demonstrate a case where the code before
 the fix misbehaves.

I've written tests which check for the two bugs which Junio's patches
fix. I'll be sending them along with a re-roll of Junio's series along
with a few other fixes to mailmap's debug mode.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 1/2] send-email: squelch warning from Net::SMTP::SSL

2013-07-14 Thread Torsten Bögershausen
On 2013-07-14 19.03, brian m. carlson wrote:
 On Sun, Jul 14, 2013 at 07:19:10PM +0530, Ramkumar Ramachandra wrote:
 Torsten Bögershausen wrote:
 /usr/bin/perl -MIO::Socket::SSL -e 'print $IO::Socket::SSL::VERSION\n;'
 1.22

 This is ancient!  (I have 1.84).  Is it not possible to do an
 ssl-verify-peer in older versions (is it exported as something else)?
 The older versions don't display the warning anyway, and this series
 is about squelching the warning in newer versions.  Does

   require IO::Socket::SSL qw(SSL_VERIFY_NONE SSL_VERIFY_PEER) or print
 warning: not using SSL_VERIFY_PEER due to outdated IO::Socket::SSL
 
 require doesn't take a list of symbols to import, and the import dies if
 it fails.  You need:
 
 require IO::Socket::SSL;
 eval {
   IO::Socket::SSL-import(qw(SSL_VERIFY_NONE SSL_VERIFY_PEER));
 };
 if ($@) {
   warn Not using SSL_VERIFY_PEER due to outdated IO::Socket::SSL\n;
   # Do something different here.
 }
 
 I didn't stick the require in the eval because git-send-email will fail
 in this case anyway if you don't have it, since Net::SMTP::SSL requires
 it.  Let me know if you want a patch for this on top of the existing two
 in this series and I'll provide one.
 
Please send a patch if possible.
I can volonteer to test it here, but it can take a couple of days to respond.



--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/6] templates: Use heredoc in pre-commit hook

2013-07-14 Thread Junio C Hamano
Jonathan Nieder jrnie...@gmail.com writes:

 Based on 98770971aef8d1cbc78876d9023d10aa25df0526 in original patch
 series from 2013-06-10.

 Please don't include this.  The audience for the commit message
 doesn't have that commit to compare to.

 If you want to preserve the original date, the way to do that is
 a Date: field at the top of the message body.

   Date: Fri, 28 Jun 2013 21:16:19 +0530

And you generally should not do that, either.

The first date of the publication of _this_ version is recorded on
the Date: header of this message, not the original path series
that this round which is _based on_ (meaning, different from) that
old one.  We do not want to see the date of the old one, either.


   Spawning a new subprocess for ...

 [...]
 --- a/templates/hooks--pre-commit.sample
 +++ b/templates/hooks--pre-commit.sample
 @@ -31,18 +31,19 @@ if [ $allownonascii != true ] 
  test $(git diff --cached --name-only --diff-filter=A -z $against |
LC_ALL=C tr -d '[ -~]\0' | wc -c) != 0
  then
 -echo Error: Attempt to add a non-ascii file name.
 -echo
 -echo This can cause problems if you want to work
 -echo with people on other platforms.
 -echo
 -echo
 -echo If you know what you are doing you can disable this
 -echo check using:
 -echo
 -echo   git config hooks.allownonascii true
 -echo
 +cat -EOF
 +Error: Attempt to add a non-ascii file name.

 Using

   cat \EOF

 would make reading easier since the reader then doesn't have to worry
 about whether the text being cat'ed is indented or uses variable
 substitutions.

 -echo To be portable it is advisable to rename the file ...
 +To be portable it is advisable to rename the file.

 Yes, nice.

 With the above nits addressed, this change looks to be going in the
 right direction.  Thanks.

 Hope that helps,
 Jonathan
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 1/7] cat-file: disable object/refname ambiguity check for batch mode

2013-07-14 Thread Junio C Hamano
Jeff King p...@peff.net writes:

 To cat-file we could add an option like --sha1-only or --literal or
 --no-dwim (... better names are failing me) which would skip *all*
 dwimming of 40-character strings.  It would also assume that any shorter
 strings are abbreviated SHA-1s and fail if they are not.  This would be
 a nice feature by itself (these are object names, dammit, and don't try
 to tell me differently!) and would have the additional small advantage
 of speeding up lookups of abbreviated SHA-1s, which (regardless of your
 patch) otherwise go through the whole DWIM process.

 I can see in theory that somebody might want that, but I am having a
 hard time thinking of a practical use.

Would it be a good alternative to call get_sha1_hex() to catch the
most common case (reading from rev-list output, for example) and
then let the more general get_sha1() to let extended SHA-1 to be
handled?

 IOW, it seems like a poor default, and we are choosing it only because
 of backwards compatibility. I guess another option is to switch the
 default with the usual deprecation dance.

I agree that did you mean the unreadable refname or 40-hex object?
turned on everywhere get_sha1() is called is a very poor default.  I
wonder if we can limit it only to the end-user input somehow at the
API level.
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Junio C Hamano
Johannes Sixt j...@kdbg.org writes:

 Am 14.07.2013 21:17, schrieb Junio C Hamano:
 Johannes Sixt j...@kdbg.org writes:
 I actually think that by implying allow-no-ff in --lockref, you are
 hurting users who have configured a push refspec without a + prefix:
 They suddenly do not get the push denied when it is not a fast-forward
 anymore.
 
 Of course, that is why you should not use --lockref when you do not
 have to.  It is a tool to loosen must fast-forward in a more
 controlled way than the traditional --force.

 Sorry, IMO, this goes into a totally wrong direction, in particular, I
 think that this is going to close to door to make --lockref the default
 some day in a way that helps everyone.

I would presume that you would force that reverse tracking
short-hand as the expected value, as default will not have other
sources of information.

I think the use of reverse tracking is way overrated.  It is
probably the only default value that we could use, if the user is
too lazy not to specify it, but I do not think it is particularly a
sensible or safe default.

The following does not discuss should --lockref automatically
disable the 'must fast-forward' check?.  The problem highlighted is
the same, regardless of the answer to that question.

After rebasing beyond what is already published, you try the
lockref push, e.g. (we assume you work on master and push back to
update master at your origin):

$ git fetch
$ git rebase -i @{u}~4 ;# rebase beyond what is there
$ git push ;# of course this will not fast-forward
$ git push --lockref
... or with your must-fast-forward is independent
$ git push --lockref origin +master
... or also with your --lockref is default
$ git push origin +master

If somebody else pushed while you are working on the rebase, the
last step (one of the above push) will fail due to stale
expectation.  What now?

The user would want to keep the updated tip, so the first thing that
happens will always be

$ git fetch
$ git log ..@{u} ;# what will we be losing?

The right thing to do at this point is to rebase your 'master' again
on top of @{u}

$ git rebase -i @{u}

before attempting to push back again.  If you do that, then you can
do another lockref push.

But the thing is, a novice who does not know what he is doing will
likely to do this:

$ git push --lockref
... or with your must-fast-forward is independent
$ git push --lockref origin +master
... or also with your --lockref is default
$ git push origin +master

... rejected due to stale expectation
$ git fetch

You just have updated the lockref base, so if you did, without doing
anything else, 

$ git push origin +master

then you will lose the updated contents.

The conclusion?  It does not make sense to make lockref the
default.

The --lockref mechanism is necessary _only_ when you want to break
the usual must fast-forward safety, and the user needs to be made
very aware of what he is doing.  Making it default and making it
appear easy to invoke with a single +, is totally going in a wrong
direction.  Besides, by making it the default and turning + into
only defeat 'must fast-forward, you will break existing setting of
people who have remote.*.push = +ref configured, without having a
remote-tracking for that ref.

So it will not happen; lockref will not be on by default, even if
it is made independent of must fast-forward.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v3] config: add support for http.url.* settings

2013-07-14 Thread Junio C Hamano
Kyle J. McKay mack...@gmail.com writes:

 On Jul 12, 2013, at 13:58, Aaron Schrab wrote:
 ...
 This should guarantee a match in the scenario Aaron proposes above and
 still has pretty much the same easy explanation to the user.

 Shall I go ahead and add that to the next patch version?

 Or proceed with what's there right now (there are a few pending
 updates from reviewers) and then, as Junio says above, adjust it later
 if needed?

I have been assuming that strictly textual match will be a subset
of the matching semantics Aaron and Peff suggested.  That is, if we
include your version in the upcoming release, the user writes the
http.URLpattern.variable configuration so that the entries match
what they want them to match, the enhanced URL matcher Aaron and
Peff suggested will still make them match.

Am I mistaken?  Will there be some URLpattern that will not match
with the same URL literally?

Assuming that Aaron and Peff's enhancement will not be a backward
incompatible update, my preference is to take the posted matching
semantics as-is (you may have some other changes that does not
change the strictly textual match semantics).

I do not have strong opinion but Aaron and Peff seem to know what
they are talking about, so they will be a better guide to work with
you and polish such enhancement on top of what you have now, as a
separate change that may need more time to mature.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 7/7] push: document --lockref

2013-07-14 Thread Junio C Hamano
Jonathan Nieder jrnie...@gmail.com writes:

   (4) gitk @{u}@{1}..@{u}; # Is the change good?

   (5a) git pull --rebase; git push; # Yes, put my change on top of it
   (5b) git push --force; # No, my change is better!

 So far so good.  But what if yet another change is made upstream
 between step (3) and (5)?

 If following approach (5a), that's fine.  We notice the new
 intervening change and react accordingly, again.  There is a
 possibility of starvation, but no other harm done.

 In case (5b), it may be a serious problem.  I don't know about the
 intervening change until I read the git push output, and in the
 usual case I just won't notice.  The new lockref UI is meant to
 address this problem.  So in the new world order, in case (5b) it
 sounds like I should have instead used

   (5b') git push --allow-non-ff

t is clear you want to allow-no-ff in this case (otherwise the push
will not go through), and that is what the --force option meant in
the old world.  The compare-and-swap safety is to help this case by
letting you say

git push --lockref

which is a weaker form of --force.  We ignore fast-forward-ness,
like the current --force does, but replace it with another form of
safety we know replacing this old value with what we are pushing is
OK---if somebody updated the ref in the meantime, then the push is
not OK, so please fail.

 Suppose I am writing a script that is meant to set the remote
 repository to a known state.  Other contributors are only using
 fast-forward updates so once my change goes in they will act
 appropriately.  I just need to get my ref update in, without being
 blocked by other ref updates.

 Then I will use

   (5c) git push --force

 which means not to use this new lockref trick that looks at my
 remote-tracking branch and instead to just force the ref update.

I am not sure I follow.  Do other contributors update this remote
repository?  They are only using fast-forward updates, so their
updates may not lose anything we pushed, but with --force, aren't
you losing their work on top of yours?
--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] http.c: fix parsing of http.sslCertPasswordProtected variable

2013-07-14 Thread Junio C Hamano
Mark Lodato loda...@gmail.com writes:

 On Fri, Jul 12, 2013 at 3:52 PM, Junio C Hamano gits...@pobox.com wrote:

 Jonathan Nieder jrnie...@gmail.com writes:

  FWIW the GIT_SSL_CERT_PASSWORD_PROTECTED envvar has a similar can
  only enable behavior, but since it's documented, that's not as big
  of a problem.  Do you remember why it was written that way?

 Not me ;-).

 Because that's how GIT_NO_VERIFY, GIT_CURL_FTP_NO_EPSV, and

s/GIT_NO_VERIFY/GIT_SSL_NO_VERIFY/, I think.

 GIT_CURL_VERBOSE (and perhaps others) work.  That said, I agree that
 parsing the variable's value as a boolean would make much more sense.
 Perhaps this is how all of those variables should work?

I think you are probably right.

--
To unsubscribe from this list: send the line unsubscribe git in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >