Re: [PATCH v2 2/2] grep: stop looking at random places for .gitattributes

2012-10-15 Thread Johannes Sixt
Am 10/14/2012 6:29, schrieb Junio C Hamano:
 Johannes Sixt j.s...@viscovery.net writes:
 
 It might be worth it. We already have a similar special case in
 write_or_die.c:maybe_flush_or_die() for Windows, although it is not about
 a colon in a path name.

 Perhaps like this.
 
 Hrm, the we already have one b2f5e26 (Windows: Work around an
 oddity when a pipe with no reader is written to., 2007-08-17) was
 what you added while I was looking the other way ;-) as a part of
 Windows specific pull.
 
 That change, and this patch, seem to cover the cases to be ignored
 with a bit too wide a net to my taste.  On other systems, and even
 on Windows if the path does not have any colon, EINVAL is something
 we would want to noticbbe and report, as a potential problem, no?

For fopen(), EINVAL should occur only if the mode argument is wrong, which
it isn't. For fflush() (as in write_or_die.c), EINVAL is not even listed
as possible error code. Therefore, catching EINVAL wholesale should not be
a problem, IMO, at least not on other systems.

On Windows, it is more problematic because there is a table of customary
Windows API error codes, which are mapped to errno values, and EINVAL is
used for all other Windows error codes (and for a few listed ones), and
ignoring EINVAL might indeed miss something worth to be reported.

Sooo... I don't mind if you do not pick up this patch because it handles a
rather theoretic case, i.e., where a project with strange paths somehow
ended up on a Windows drive.

But reverting the EINVAL check from write_or_die.c is out of question,
because that handles a real case.

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


nd/attr-match-more-optim, nd/wildmatch and as/check-ignore

2012-10-15 Thread Nguyễn Thái Ngọc Duy
I promise I won't send anything dir.c-related till the end of this
month :) These three series all touch the same code in dir.c and cause
a bunch of conflicts. So I rebase nd/wildmatch and as/check-ignore
on top of nd/attr-match-more-optim and resolve all conflicts.

nd/attr-match-more-optim


A lot of refactoring in dir.c leads to a cleaner last patch to port
many exclude optimizations to attr. We can extend EXC_FLAGS_ENDSWITH
optimization further, from ^*.[ch] to path/to/*.[ch], but not in
this series.

Nguyễn Thái Ngọc Duy (6):
  exclude: stricten a length check in EXC_FLAG_ENDSWITH case
  exclude: split basename matching code into a separate function
  exclude: fix a bug in prefix compare optimization
  exclude: split pathname matching code into a separate function
  gitignore: make pattern parsing code a separate function
  attr: more matching optimizations from .gitignore

 Documentation/gitattributes.txt|   1 +
 attr.c |  52 ++
 dir.c  | 192 -
 dir.h  |  13 ++-
 t/t0003-attributes.sh  |  10 ++
 t/t3001-ls-files-others-exclude.sh |   6 ++
 6 files changed, 186 insertions(+), 88 deletions(-)

nd/wildmatch


new ctype patches that no longer introduce sane_ctype2[]. I also
re-indent wildmatch.c to follow Git's coding style with the intention
of making more changes in future (e.g. case insensitive support in
pathspec means we cannot rely on GNU extension FNM_CASEFOLD). Thanks
to nd/attr-match-more-optim we don't need to make any changes to
attr.c.

Depends on nd/attr-match-more-optim.

Nguyễn Thái Ngọc Duy (13):
  ctype: make sane_ctype[] const array
  ctype: support iscntrl, ispunct, isxdigit and isprint
  Import wildmatch from rsync
  wildmatch: remove unnecessary functions
  wildmatch: follow Git's coding convention
  Integrate wildmatch to git
  t3070: disable unreliable fnmatch tests
  wildmatch: make wildmatch's return value compatible with fnmatch
  wildmatch: remove static variable force_lower_case
  wildmatch: fix case-insensitive matching
  wildmatch: adjust ** behavior
  wildmatch: make /**/ match zero or more directories
  Support ** wildcard in .gitignore and .gitattributes

 .gitignore |   1 +
 Documentation/gitignore.txt|  19 +++
 Makefile   |   3 +
 ctype.c|  15 ++-
 dir.c  |   4 +-
 git-compat-util.h  |  15 ++-
 t/t0003-attributes.sh  |  37 ++
 t/t3001-ls-files-others-exclude.sh |  18 +++
 t/t3070-wildmatch.sh   | 195 +++
 test-wildmatch.c   |  14 +++
 wildmatch.c| 234 +
 wildmatch.h|   9 ++
 12 files changed, 556 insertions(+), 8 deletions(-)
 create mode 100755 t/t3070-wildmatch.sh
 create mode 100644 test-wildmatch.c
 create mode 100644 wildmatch.c
 create mode 100644 wildmatch.h

as/check-ignore
---

Conflict resolution and cleanups. A lot of matching code sharing
between exclude and attr means we might be able to bring check-ignore
functionality to check-attr. But let's leave it for now.

Depends on nd/attr-match-more-optim.

Adam Spiers (12):
  dir.c: rename cryptic 'which' variable to more consistent name
  dir.c: rename path_excluded() to is_path_excluded()
  dir.c: rename excluded_from_list() to is_excluded_from_list()
  dir.c: rename excluded() to is_excluded()
  dir.c: refactor is_excluded_from_list()
  dir.c: refactor is_excluded()
  dir.c: refactor is_path_excluded()
  dir.c: keep track of where patterns came from
  dir.c: refactor treat_gitlinks()
  pathspec.c: move reusable code from builtin/add.c
  dir.c: provide free_directory() for reclaiming dir_struct memory
  Add git-check-ignore sub-command

 .gitignore|   1 +
 Documentation/git-check-ignore.txt|  85 
 Documentation/gitignore.txt   |   6 +-
 Documentation/technical/api-directory-listing.txt |   2 +
 Makefile  |   3 +
 attr.c|   2 +-
 builtin.h |   1 +
 builtin/add.c |  84 +---
 builtin/check-ignore.c| 170 +++
 builtin/clean.c   |   2 +-
 builtin/ls-files.c|   5 +-
 command-list.txt  |   1 +
 contrib/completion/git-completion.bash|   1 +
 dir.c | 185 +--
 dir.h |  21 +-
 git.c |   1 +
 pathspec.c|  98 

[PATCH 1/6] exclude: stricten a length check in EXC_FLAG_ENDSWITH case

2012-10-15 Thread Nguyễn Thái Ngọc Duy
This block of code deals with the basename part only, which has the
length of pathlen - (basename - pathname). Stricten the length check
and remove pathname from the main expression to avoid confusion.

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

diff --git a/dir.c b/dir.c
index 0015cc5..b0ae417 100644
--- a/dir.c
+++ b/dir.c
@@ -534,8 +534,9 @@ int excluded_from_list(const char *pathname,
if (!strcmp_icase(exclude, basename))
return to_exclude;
} else if (x-flags  EXC_FLAG_ENDSWITH) {
-   if (x-patternlen - 1 = pathlen 
-   !strcmp_icase(exclude + 1, pathname + 
pathlen - x-patternlen + 1))
+   int len = pathlen - (basename - pathname);
+   if (x-patternlen - 1 = len 
+   !strcmp_icase(exclude + 1, basename + len - 
x-patternlen + 1))
return to_exclude;
} else {
if (fnmatch_icase(exclude, basename, 0) == 0)
-- 
1.8.0.rc0.29.g1fdd78f

--
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] exclude: split basename matching code into a separate function

2012-10-15 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/dir.c b/dir.c
index b0ae417..d9b5561 100644
--- a/dir.c
+++ b/dir.c
@@ -503,6 +503,25 @@ static void prep_exclude(struct dir_struct *dir, const 
char *base, int baselen)
dir-basebuf[baselen] = '\0';
 }
 
+static int match_basename(const char *basename, int basenamelen,
+ const char *pattern, int prefix, int patternlen,
+ int flags)
+{
+   if (prefix == patternlen) {
+   if (!strcmp_icase(pattern, basename))
+   return 1;
+   } else if (flags  EXC_FLAG_ENDSWITH) {
+   if (patternlen - 1 = basenamelen 
+   !strcmp_icase(pattern + 1,
+ basename + basenamelen - patternlen + 1))
+   return 1;
+   } else {
+   if (fnmatch_icase(pattern, basename, 0) == 0)
+   return 1;
+   }
+   return 0;
+}
+
 /* Scan the list and let the last match determine the fate.
  * Return 1 for exclude, 0 for include and -1 for undecided.
  */
@@ -529,19 +548,11 @@ int excluded_from_list(const char *pathname,
}
 
if (x-flags  EXC_FLAG_NODIR) {
-   /* match basename */
-   if (prefix == x-patternlen) {
-   if (!strcmp_icase(exclude, basename))
-   return to_exclude;
-   } else if (x-flags  EXC_FLAG_ENDSWITH) {
-   int len = pathlen - (basename - pathname);
-   if (x-patternlen - 1 = len 
-   !strcmp_icase(exclude + 1, basename + len - 
x-patternlen + 1))
-   return to_exclude;
-   } else {
-   if (fnmatch_icase(exclude, basename, 0) == 0)
-   return to_exclude;
-   }
+   if (match_basename(basename,
+  pathlen - (basename - pathname),
+  exclude, prefix, x-patternlen,
+  x-flags))
+   return to_exclude;
continue;
}
 
-- 
1.8.0.rc0.29.g1fdd78f

--
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] exclude: fix a bug in prefix compare optimization

2012-10-15 Thread Nguyễn Thái Ngọc Duy
When namelen becomes zero at this stage, we have matched the fixed
part, but whether it actually matches the pattern still depends on the
pattern in exclude. As demonstrated in t3001, path three/a.3
exists and it matches the three/a.3 part in pattern three/a.3[abc],
but that does not mean a true match.

Don't be too optimistic and let fnmatch() do the job.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c  | 2 +-
 t/t3001-ls-files-others-exclude.sh | 6 ++
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/dir.c b/dir.c
index d9b5561..22d0b7b 100644
--- a/dir.c
+++ b/dir.c
@@ -585,7 +585,7 @@ int excluded_from_list(const char *pathname,
namelen -= prefix;
}
 
-   if (!namelen || !fnmatch_icase(exclude, name, FNM_PATHNAME))
+   if (!fnmatch_icase(exclude, name, FNM_PATHNAME))
return to_exclude;
}
return -1; /* undecided */
diff --git a/t/t3001-ls-files-others-exclude.sh 
b/t/t3001-ls-files-others-exclude.sh
index c8fe978..dc2f045 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -214,4 +214,10 @@ test_expect_success 'subdirectory ignore (l1)' '
test_cmp expect actual
 '
 
+test_expect_success 'pattern matches prefix completely' '
+   : expect 
+   git ls-files -i -o --exclude /three/a.3[abc] actual 
+   test_cmp expect actual
+'
+
 test_done
-- 
1.8.0.rc0.29.g1fdd78f

--
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] gitignore: make pattern parsing code a separate function

2012-10-15 Thread Nguyễn Thái Ngọc Duy
This function can later be reused by attr.c. Also turn to_exclude
field into a flag.

Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 71 ++-
 dir.h |  2 +-
 2 files changed, 50 insertions(+), 23 deletions(-)

diff --git a/dir.c b/dir.c
index 32d1c90..c4e64a5 100644
--- a/dir.c
+++ b/dir.c
@@ -308,42 +308,69 @@ static int no_wildcard(const char *string)
return string[simple_length(string)] == '\0';
 }
 
+static void parse_exclude_pattern(const char **pattern,
+ int *patternlen,
+ int *flags,
+ int *nowildcardlen)
+{
+   const char *p = *pattern;
+   size_t i, len;
+
+   *flags = 0;
+   if (*p == '!') {
+   *flags |= EXC_FLAG_NEGATIVE;
+   p++;
+   }
+   len = strlen(p);
+   if (len  p[len - 1] == '/') {
+   len--;
+   *flags |= EXC_FLAG_MUSTBEDIR;
+   }
+   for (i = 0; i  len; i++) {
+   if (p[i] == '/')
+   break;
+   }
+   if (i == len)
+   *flags |= EXC_FLAG_NODIR;
+   *nowildcardlen = simple_length(p);
+   /*
+* we should have excluded the trailing slash from 'p' too,
+* but that's one more allocation. Instead just make sure
+* nowildcardlen does not exceed real patternlen
+*/
+   if (*nowildcardlen  len)
+   *nowildcardlen = len;
+   if (*p == '*'  no_wildcard(p + 1))
+   *flags |= EXC_FLAG_ENDSWITH;
+   *pattern = p;
+   *patternlen = len;
+}
+
 void add_exclude(const char *string, const char *base,
 int baselen, struct exclude_list *which)
 {
struct exclude *x;
-   size_t len;
-   int to_exclude = 1;
-   int flags = 0;
+   int patternlen;
+   int flags;
+   int nowildcardlen;
 
-   if (*string == '!') {
-   to_exclude = 0;
-   string++;
-   }
-   len = strlen(string);
-   if (len  string[len - 1] == '/') {
+   parse_exclude_pattern(string, patternlen, flags, nowildcardlen);
+   if (flags  EXC_FLAG_MUSTBEDIR) {
char *s;
-   x = xmalloc(sizeof(*x) + len);
+   x = xmalloc(sizeof(*x) + patternlen + 1);
s = (char *)(x+1);
-   memcpy(s, string, len - 1);
-   s[len - 1] = '\0';
-   string = s;
+   memcpy(s, string, patternlen);
+   s[patternlen] = '\0';
x-pattern = s;
-   flags = EXC_FLAG_MUSTBEDIR;
} else {
x = xmalloc(sizeof(*x));
x-pattern = string;
}
-   x-to_exclude = to_exclude;
-   x-patternlen = strlen(string);
+   x-patternlen = patternlen;
+   x-nowildcardlen = nowildcardlen;
x-base = base;
x-baselen = baselen;
x-flags = flags;
-   if (!strchr(string, '/'))
-   x-flags |= EXC_FLAG_NODIR;
-   x-nowildcardlen = simple_length(string);
-   if (*string == '*'  no_wildcard(string+1))
-   x-flags |= EXC_FLAG_ENDSWITH;
ALLOC_GROW(which-excludes, which-nr + 1, which-alloc);
which-excludes[which-nr++] = x;
 }
@@ -584,7 +611,7 @@ int excluded_from_list(const char *pathname,
for (i = el-nr - 1; 0 = i; i--) {
struct exclude *x = el-excludes[i];
const char *exclude = x-pattern;
-   int to_exclude = x-to_exclude;
+   int to_exclude = x-flags  EXC_FLAG_NEGATIVE ? 0 : 1;
int prefix = x-nowildcardlen;
 
if (x-flags  EXC_FLAG_MUSTBEDIR) {
diff --git a/dir.h b/dir.h
index 893465a..41ea32d 100644
--- a/dir.h
+++ b/dir.h
@@ -11,6 +11,7 @@ struct dir_entry {
 #define EXC_FLAG_NODIR 1
 #define EXC_FLAG_ENDSWITH 4
 #define EXC_FLAG_MUSTBEDIR 8
+#define EXC_FLAG_NEGATIVE 16
 
 struct exclude_list {
int nr;
@@ -21,7 +22,6 @@ struct exclude_list {
int nowildcardlen;
const char *base;
int baselen;
-   int to_exclude;
int flags;
} **excludes;
 };
-- 
1.8.0.rc0.29.g1fdd78f

--
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] attr: more matching optimizations from .gitignore

2012-10-15 Thread Nguyễn Thái Ngọc Duy
.gitattributes and .gitignore share the same pattern syntax but has
separate matching implementation. Over the years, ignore's
implementation accumulates more optimizations while attr's stays the
same.

This patch reuses the core matching functions that are also used by
excluded_from_list. excluded_from_list and path_matches can't be
merged due to differences in exclude and attr, for example:

* !pattern syntax is forbidden in .gitattributes.  As an attribute
  can be unset (i.e. set to a special value false) or made back to
  unspecified (i.e. not even set to false), !pattern attr is unclear
  which one it means.

* we support attaching attributes to directories, but git-core
  internally does not currently make use of attributes on
  directories.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/gitattributes.txt |  1 +
 attr.c  | 52 -
 dir.c   | 22 -
 dir.h   | 11 +
 t/t0003-attributes.sh   | 10 
 5 files changed, 64 insertions(+), 32 deletions(-)

diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt
index 80120ea..b7c0e65 100644
--- a/Documentation/gitattributes.txt
+++ b/Documentation/gitattributes.txt
@@ -56,6 +56,7 @@ When more than one pattern matches the path, a later line
 overrides an earlier line.  This overriding is done per
 attribute.  The rules how the pattern matches paths are the
 same as in `.gitignore` files; see linkgit:gitignore[5].
+Unlike `.gitignore`, negative patterns are forbidden.
 
 When deciding what attributes are assigned to a path, git
 consults `$GIT_DIR/info/attributes` file (which has the highest
diff --git a/attr.c b/attr.c
index e7caee4..2fc6353 100644
--- a/attr.c
+++ b/attr.c
@@ -115,6 +115,13 @@ struct attr_state {
const char *setto;
 };
 
+struct pattern {
+   const char *pattern;
+   int patternlen;
+   int nowildcardlen;
+   int flags;  /* EXC_FLAG_* */
+};
+
 /*
  * One rule, as from a .gitattributes file.
  *
@@ -131,7 +138,7 @@ struct attr_state {
  */
 struct match_attr {
union {
-   char *pattern;
+   struct pattern pat;
struct git_attr *attr;
} u;
char is_macro;
@@ -241,9 +248,16 @@ static struct match_attr *parse_attr_line(const char 
*line, const char *src,
if (is_macro)
res-u.attr = git_attr_internal(name, namelen);
else {
-   res-u.pattern = (char *)(res-state[num_attr]);
-   memcpy(res-u.pattern, name, namelen);
-   res-u.pattern[namelen] = 0;
+   char *p = (char *)(res-state[num_attr]);
+   memcpy(p, name, namelen);
+   res-u.pat.pattern = p;
+   parse_exclude_pattern(res-u.pat.pattern,
+ res-u.pat.patternlen,
+ res-u.pat.flags,
+ res-u.pat.nowildcardlen);
+   if (res-u.pat.flags  EXC_FLAG_NEGATIVE)
+   die(_(Negative patterns are forbidden in git 
attributes\n
+ Use '\\!' for literal leading exclamation.));
}
res-is_macro = is_macro;
res-num_attr = num_attr;
@@ -640,25 +654,21 @@ static void prepare_attr_stack(const char *path)
 
 static int path_matches(const char *pathname, int pathlen,
const char *basename,
-   const char *pattern,
+   const struct pattern *pat,
const char *base, int baselen)
 {
-   if (!strchr(pattern, '/')) {
-   return (fnmatch_icase(pattern, basename, 0) == 0);
+   const char *pattern = pat-pattern;
+   int prefix = pat-nowildcardlen;
+
+   if (pat-flags  EXC_FLAG_NODIR) {
+   return match_basename(basename,
+ pathlen - (basename - pathname),
+ pattern, prefix,
+ pat-patternlen, pat-flags);
}
-   /*
-* match with FNM_PATHNAME; the pattern has base implicitly
-* in front of it.
-*/
-   if (*pattern == '/')
-   pattern++;
-   if (pathlen  baselen ||
-   (baselen  pathname[baselen] != '/') ||
-   strncmp(pathname, base, baselen))
-   return 0;
-   if (baselen != 0)
-   baselen++;
-   return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;
+   return match_pathname(pathname, pathlen,
+ base, baselen,
+ pattern, prefix, pat-patternlen, pat-flags);
 }
 
 static int macroexpand_one(int attr_nr, int rem);
@@ -696,7 +706,7 @@ static int fill(const char *path, int pathlen, const char 
*basename,
if (a-is_macro)
 

[PATCH 01/13] ctype: make sane_ctype[] const array

2012-10-15 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 ctype.c   | 2 +-
 git-compat-util.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/ctype.c b/ctype.c
index 9353271..faeaf34 100644
--- a/ctype.c
+++ b/ctype.c
@@ -14,7 +14,7 @@ enum {
P = GIT_PATHSPEC_MAGIC  /* other non-alnum, except for ] and } */
 };
 
-unsigned char sane_ctype[256] = {
+const unsigned char sane_ctype[256] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0, /*   0.. 15 */
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  16.. 31 */
S, P, P, P, R, P, P, P, R, R, G, R, P, P, R, P, /*  32.. 47 */
diff --git a/git-compat-util.h b/git-compat-util.h
index 5bd9ad7..80767ff 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -470,7 +470,7 @@ extern const char tolower_trans_tbl[256];
 #undef isupper
 #undef tolower
 #undef toupper
-extern unsigned char sane_ctype[256];
+extern const unsigned char sane_ctype[256];
 #define GIT_SPACE 0x01
 #define GIT_DIGIT 0x02
 #define GIT_ALPHA 0x04
-- 
1.8.0.rc0.29.g1fdd78f

--
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 02/13] ctype: support iscntrl, ispunct, isxdigit and isprint

2012-10-15 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 ctype.c   | 13 -
 git-compat-util.h | 13 +
 2 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/ctype.c b/ctype.c
index faeaf34..0bfebb4 100644
--- a/ctype.c
+++ b/ctype.c
@@ -11,18 +11,21 @@ enum {
D = GIT_DIGIT,
G = GIT_GLOB_SPECIAL,   /* *, ?, [, \\ */
R = GIT_REGEX_SPECIAL,  /* $, (, ), +, ., ^, {, | */
-   P = GIT_PATHSPEC_MAGIC  /* other non-alnum, except for ] and } */
+   P = GIT_PATHSPEC_MAGIC, /* other non-alnum, except for ] and } */
+   X = GIT_CNTRL,
+   U = GIT_PUNCT,
+   Z = GIT_CNTRL | GIT_SPACE
 };
 
 const unsigned char sane_ctype[256] = {
-   0, 0, 0, 0, 0, 0, 0, 0, 0, S, S, 0, 0, S, 0, 0, /*   0.. 15 */
-   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  16.. 31 */
+   X, X, X, X, X, X, X, X, X, Z, Z, X, X, Z, X, X, /*   0.. 15 */
+   X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, X, /*  16.. 31 */
S, P, P, P, R, P, P, P, R, R, G, R, P, P, R, P, /*  32.. 47 */
D, D, D, D, D, D, D, D, D, D, P, P, P, P, P, G, /*  48.. 63 */
P, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /*  64.. 79 */
-   A, A, A, A, A, A, A, A, A, A, A, G, G, 0, R, P, /*  80.. 95 */
+   A, A, A, A, A, A, A, A, A, A, A, G, G, U, R, P, /*  80.. 95 */
P, A, A, A, A, A, A, A, A, A, A, A, A, A, A, A, /*  96..111 */
-   A, A, A, A, A, A, A, A, A, A, A, R, R, 0, P, 0, /* 112..127 */
+   A, A, A, A, A, A, A, A, A, A, A, R, R, U, P, X, /* 112..127 */
/* Nothing in the 128.. range */
 };
 
diff --git a/git-compat-util.h b/git-compat-util.h
index 80767ff..02f48f6 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -470,6 +470,10 @@ extern const char tolower_trans_tbl[256];
 #undef isupper
 #undef tolower
 #undef toupper
+#undef iscntrl
+#undef ispunct
+#undef isxdigit
+#undef isprint
 extern const unsigned char sane_ctype[256];
 #define GIT_SPACE 0x01
 #define GIT_DIGIT 0x02
@@ -477,6 +481,8 @@ extern const unsigned char sane_ctype[256];
 #define GIT_GLOB_SPECIAL 0x08
 #define GIT_REGEX_SPECIAL 0x10
 #define GIT_PATHSPEC_MAGIC 0x20
+#define GIT_CNTRL 0x40
+#define GIT_PUNCT 0x80
 #define sane_istest(x,mask) ((sane_ctype[(unsigned char)(x)]  (mask)) != 0)
 #define isascii(x) (((x)  ~0x7f) == 0)
 #define isspace(x) sane_istest(x,GIT_SPACE)
@@ -487,6 +493,13 @@ extern const unsigned char sane_ctype[256];
 #define isupper(x) sane_iscase(x, 0)
 #define is_glob_special(x) sane_istest(x,GIT_GLOB_SPECIAL)
 #define is_regex_special(x) sane_istest(x,GIT_GLOB_SPECIAL | GIT_REGEX_SPECIAL)
+#define iscntrl(x) (sane_istest(x,GIT_CNTRL))
+#define ispunct(x) sane_istest(x, GIT_PUNCT | GIT_REGEX_SPECIAL | \
+   GIT_GLOB_SPECIAL | GIT_PATHSPEC_MAGIC)
+#define isxdigit(x) (hexval_table[x] != -1)
+#define isprint(x) (sane_istest(x, GIT_ALPHA | GIT_DIGIT | GIT_SPACE | \
+   GIT_PUNCT | GIT_REGEX_SPECIAL | GIT_GLOB_SPECIAL | \
+   GIT_PATHSPEC_MAGIC))
 #define tolower(x) sane_case((unsigned char)(x), 0x20)
 #define toupper(x) sane_case((unsigned char)(x), 0)
 #define is_pathspec_magic(x) sane_istest(x,GIT_PATHSPEC_MAGIC)
-- 
1.8.0.rc0.29.g1fdd78f

--
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 03/13] Import wildmatch from rsync

2012-10-15 Thread Nguyễn Thái Ngọc Duy
These files are from rsync.git commit
f92f5b166e3019db42bc7fe1aa2f1a9178cd215d, which was the last commit
before rsync turned GPL-3. All files are imported as-is and
no-op. Adaptation is done in a separate patch.

rsync.git   -  git.git
lib/wildmatch.[ch]  wildmatch.[ch]
wildtest.txtt/t3070/wildtest.txt

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 t/t3070/wildtest.txt | 165 +++
 wildmatch.c  | 368 +++
 wildmatch.h  |   6 +
 3 files changed, 539 insertions(+)
 create mode 100644 t/t3070/wildtest.txt
 create mode 100644 wildmatch.c
 create mode 100644 wildmatch.h

diff --git a/t/t3070/wildtest.txt b/t/t3070/wildtest.txt
new file mode 100644
index 000..42c1678
--- /dev/null
+++ b/t/t3070/wildtest.txt
@@ -0,0 +1,165 @@
+# Input is in the following format (all items white-space separated):
+#
+# The first two items are 1 or 0 indicating if the wildmat call is expected to
+# succeed and if fnmatch works the same way as wildmat, respectively.  After
+# that is a text string for the match, and a pattern string.  Strings can be
+# quoted (if desired) in either double or single quotes, as well as backticks.
+#
+# MATCH FNMATCH_SAME text to match 'pattern to use'
+
+# Basic wildmat features
+1 1 foofoo
+0 1 foobar
+1 1 '' 
+1 1 foo???
+0 1 foo??
+1 1 foo*
+1 1 foof*
+0 1 foo*f
+1 1 foo*foo*
+1 1 foobar *ob*a*r*
+1 1 aaabababab *ab
+1 1 foo*   foo\*
+0 1 foobar foo\*bar
+1 1 f\oo   f\\oo
+1 1 ball   *[al]?
+0 1 ten[ten]
+1 1 ten**[!te]
+0 1 ten**[!ten]
+1 1 tent[a-g]n
+0 1 tent[!a-g]n
+1 1 tont[!a-g]n
+1 1 tont[^a-g]n
+1 1 a]ba[]]b
+1 1 a-ba[]-]b
+1 1 a]ba[]-]b
+0 1 aaba[]-]b
+1 1 aaba[]a-]b
+1 1 ]  ]
+
+# Extended slash-matching features
+0 1 foo/baz/barfoo*bar
+1 1 foo/baz/barfoo**bar
+0 1 foo/barfoo?bar
+0 1 foo/barfoo[/]bar
+0 1 foo/barf[^eiu][^eiu][^eiu][^eiu][^eiu]r
+1 1 foo-barf[^eiu][^eiu][^eiu][^eiu][^eiu]r
+0 1 foo**/foo
+1 1 /foo   **/foo
+1 1 bar/baz/foo**/foo
+0 1 bar/baz/foo*/foo
+0 0 foo/bar/baz**/bar*
+1 1 deep/foo/bar/baz   **/bar/*
+0 1 deep/foo/bar/baz/  **/bar/*
+1 1 deep/foo/bar/baz/  **/bar/**
+0 1 deep/foo/bar   **/bar/*
+1 1 deep/foo/bar/  **/bar/**
+1 1 foo/bar/baz**/bar**
+1 1 foo/bar/baz/x  */bar/**
+0 0 deep/foo/bar/baz/x */bar/**
+1 1 deep/foo/bar/baz/x **/bar/*/*
+
+# Various additional tests
+0 1 acrt   a[c-c]st
+1 1 acrt   a[c-c]rt
+0 1 ]  [!]-]
+1 1 a  [!]-]
+0 1 '' \
+0 1 \  \
+0 1 /\ */\
+1 1 /\ */\\
+1 1 foofoo
+1 1 @foo   @foo
+0 1 foo@foo
+1 1 [ab]   \[ab]
+1 1 [ab]   [[]ab]
+1 1 [ab]   [[:]ab]
+0 1 [ab]   [[::]ab]
+1 1 [ab]   [[:digit]ab]
+1 1 [ab]   [\[:]ab]
+1 1 ?a?b   \??\?b
+1 1 abc\a\b\c
+0 1 foo''
+1 1 foo/bar/baz/to **/t[o]
+
+# Character class tests
+1 1 a1B[[:alpha:]][[:digit:]][[:upper:]]
+0 1 a  [[:digit:][:upper:][:space:]]
+1 1 A  [[:digit:][:upper:][:space:]]
+1 1 1  [[:digit:][:upper:][:space:]]
+0 1 1  [[:digit:][:upper:][:spaci:]]
+1 1 ' '[[:digit:][:upper:][:space:]]
+0 1 .  [[:digit:][:upper:][:space:]]
+1 1 .  [[:digit:][:punct:][:space:]]
+1 1 5  [[:xdigit:]]
+1 1 f  [[:xdigit:]]
+1 1 D  [[:xdigit:]]
+1 1 _  
[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]
+#1 1 � 
[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]
+1 1   
[^[:alnum:][:alpha:][:blank:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]
+1 1 .  
[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]
+1 1 5  [a-c[:digit:]x-z]
+1 1 b  [a-c[:digit:]x-z]
+1 1 y  [a-c[:digit:]x-z]
+0 1 q  [a-c[:digit:]x-z]
+
+# Additional tests, including some malformed wildmats

[PATCH 04/13] wildmatch: remove unnecessary functions

2012-10-15 Thread Nguyễn Thái Ngọc Duy

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

diff --git a/wildmatch.c b/wildmatch.c
index f3a1731..fae7397 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -53,33 +53,18 @@
 #define ISUPPER(c) (ISASCII(c)  isupper(c))
 #define ISXDIGIT(c) (ISASCII(c)  isxdigit(c))
 
-#ifdef WILD_TEST_ITERATIONS
-int wildmatch_iteration_count;
-#endif
-
 static int force_lower_case = 0;
 
-/* Match pattern p against the a virtually-joined string consisting
- * of text and any strings in array a. */
-static int dowild(const uchar *p, const uchar *text, const uchar*const *a)
+/* Match pattern p against text */
+static int dowild(const uchar *p, const uchar *text)
 {
 uchar p_ch;
 
-#ifdef WILD_TEST_ITERATIONS
-wildmatch_iteration_count++;
-#endif
-
 for ( ; (p_ch = *p) != '\0'; text++, p++) {
int matched, special;
uchar t_ch, prev_ch;
-   while ((t_ch = *text) == '\0') {
-   if (*a == NULL) {
-   if (p_ch != '*')
-   return ABORT_ALL;
-   break;
-   }
-   text = *a++;
-   }
+   if ((t_ch = *text) == '\0'  p_ch != '*')
+   return ABORT_ALL;
if (force_lower_case  ISUPPER(t_ch))
t_ch = tolower(t_ch);
switch (p_ch) {
@@ -107,21 +92,15 @@ static int dowild(const uchar *p, const uchar *text, const 
uchar*const *a)
/* Trailing ** matches everything.  Trailing * matches
 * only if there are no more slash characters. */
if (!special) {
-   do {
if (strchr((char*)text, '/') != NULL)
return FALSE;
-   } while ((text = *a++) != NULL);
}
return TRUE;
}
while (1) {
-   if (t_ch == '\0') {
-   if ((text = *a++) == NULL)
-   break;
-   t_ch = *text;
-   continue;
-   }
-   if ((matched = dowild(p, text, a)) != FALSE) {
+   if (t_ch == '\0')
+   break;
+   if ((matched = dowild(p, text)) != FALSE) {
if (!special || matched != ABORT_TO_STARSTAR)
return matched;
} else if (!special  t_ch == '/')
@@ -225,144 +204,21 @@ static int dowild(const uchar *p, const uchar *text, 
const uchar*const *a)
}
 }
 
-do {
-   if (*text)
-   return FALSE;
-} while ((text = *a++) != NULL);
-
-return TRUE;
-}
-
-/* Match literal string s against the a virtually-joined string consisting
- * of text and any strings in array a. */
-static int doliteral(const uchar *s, const uchar *text, const uchar*const *a)
-{
-for ( ; *s != '\0'; text++, s++) {
-   while (*text == '\0') {
-   if ((text = *a++) == NULL)
-   return FALSE;
-   }
-   if (*text != *s)
-   return FALSE;
-}
-
-do {
-   if (*text)
-   return FALSE;
-} while ((text = *a++) != NULL);
-
-return TRUE;
-}
-
-/* Return the last count path elements from the concatenated string.
- * We return a string pointer to the start of the string, and update the
- * array pointer-pointer to point to any remaining string elements. */
-static const uchar *trailing_N_elements(const uchar*const **a_ptr, int count)
-{
-const uchar*const *a = *a_ptr;
-const uchar*const *first_a = a;
-
-while (*a)
-   a++;
-
-while (a != first_a) {
-   const uchar *s = *--a;
-   s += strlen((char*)s);
-   while (--s = *a) {
-   if (*s == '/'  !--count) {
-   *a_ptr = a+1;
-   return s+1;
-   }
-   }
-}
-
-if (count == 1) {
-   *a_ptr = a+1;
-   return *a;
-}
-
-return NULL;
+return *text ? FALSE : TRUE;
 }
 
 /* Match the pattern against the text string. */
 int wildmatch(const char *pattern, const char *text)
 {
-static const uchar *nomore[1]; /* A NULL pointer. */
-#ifdef WILD_TEST_ITERATIONS
-wildmatch_iteration_count = 0;
-#endif
-return dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
+return dowild((const uchar*)pattern, (const uchar*)text) == TRUE;
 }
 
 /* Match the pattern against the forced-to-lower-case text string. */
 int iwildmatch(const char *pattern, const char *text)
 {
-static const uchar *nomore[1]; /* A NULL pointer. */
 int ret;
-#ifdef WILD_TEST_ITERATIONS
-wildmatch_iteration_count = 0;
-#endif
 force_lower_case = 1;
-ret = dowild((const uchar*)pattern, (const uchar*)text, nomore) == TRUE;
+ret = dowild((const uchar*)pattern, (const uchar*)text) == TRUE;
 force_lower_case = 0;
 return ret;
 }
-
-/* Match pattern p against the a virtually-joined string 

[PATCH 05/13] wildmatch: follow Git's coding convention

2012-10-15 Thread Nguyễn Thái Ngọc Duy
wildmatch's coding style is pretty close to Git's except the use of 4
space indentation instead of 8. This patch should produce empty diff
with git diff -b

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

diff --git a/wildmatch.c b/wildmatch.c
index fae7397..4653dd6 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -58,167 +58,167 @@ static int force_lower_case = 0;
 /* Match pattern p against text */
 static int dowild(const uchar *p, const uchar *text)
 {
-uchar p_ch;
+   uchar p_ch;
 
-for ( ; (p_ch = *p) != '\0'; text++, p++) {
-   int matched, special;
-   uchar t_ch, prev_ch;
-   if ((t_ch = *text) == '\0'  p_ch != '*')
-   return ABORT_ALL;
-   if (force_lower_case  ISUPPER(t_ch))
-   t_ch = tolower(t_ch);
-   switch (p_ch) {
- case '\\':
-   /* Literal match with following character.  Note that the test
-* in default handles the p[1] == '\0' failure case. */
-   p_ch = *++p;
-   /* FALLTHROUGH */
- default:
-   if (t_ch != p_ch)
-   return FALSE;
-   continue;
- case '?':
-   /* Match anything but '/'. */
-   if (t_ch == '/')
-   return FALSE;
-   continue;
- case '*':
-   if (*++p == '*') {
-   while (*++p == '*') {}
-   special = TRUE;
-   } else
-   special = FALSE;
-   if (*p == '\0') {
-   /* Trailing ** matches everything.  Trailing * matches
-* only if there are no more slash characters. */
-   if (!special) {
-   if (strchr((char*)text, '/') != NULL)
-   return FALSE;
-   }
-   return TRUE;
-   }
-   while (1) {
-   if (t_ch == '\0')
-   break;
-   if ((matched = dowild(p, text)) != FALSE) {
-   if (!special || matched != ABORT_TO_STARSTAR)
-   return matched;
-   } else if (!special  t_ch == '/')
-   return ABORT_TO_STARSTAR;
-   t_ch = *++text;
-   }
-   return ABORT_ALL;
- case '[':
-   p_ch = *++p;
-#ifdef NEGATE_CLASS2
-   if (p_ch == NEGATE_CLASS2)
-   p_ch = NEGATE_CLASS;
-#endif
-   /* Assign literal TRUE/FALSE because of matched comparison. */
-   special = p_ch == NEGATE_CLASS? TRUE : FALSE;
-   if (special) {
-   /* Inverted character class. */
-   p_ch = *++p;
-   }
-   prev_ch = 0;
-   matched = FALSE;
-   do {
-   if (!p_ch)
-   return ABORT_ALL;
-   if (p_ch == '\\') {
-   p_ch = *++p;
-   if (!p_ch)
+   for ( ; (p_ch = *p) != '\0'; text++, p++) {
+   int matched, special;
+   uchar t_ch, prev_ch;
+   if ((t_ch = *text) == '\0'  p_ch != '*')
return ABORT_ALL;
-   if (t_ch == p_ch)
-   matched = TRUE;
-   } else if (p_ch == '-'  prev_ch  p[1]  p[1] != ']') {
-   p_ch = *++p;
-   if (p_ch == '\\') {
+   if (force_lower_case  ISUPPER(t_ch))
+   t_ch = tolower(t_ch);
+   switch (p_ch) {
+   case '\\':
+   /* Literal match with following character.  Note that 
the test
+* in default handles the p[1] == '\0' failure case. 
*/
p_ch = *++p;
-   if (!p_ch)
-   return ABORT_ALL;
-   }
-   if (t_ch = p_ch  t_ch = prev_ch)
-   matched = TRUE;
-   p_ch = 0; /* This makes prev_ch get set to 0. */
-   } else if (p_ch == '['  p[1] == ':') {
-   const uchar *s;
-   int i;
-   for (s = p += 2; (p_ch = *p)  p_ch != ']'; p++) {} 
/*SHARED ITERATOR*/
-   if (!p_ch)
-   return ABORT_ALL;
-   i = p - s - 1;
-   if (i  0 || p[-1] != ':') {
-   /* Didn't find :], so treat like a normal set. */
-   p = s - 2;
-   p_ch = '[';
-   if (t_ch == p_ch)
-   matched = TRUE;
+   /* FALLTHROUGH */
+   default:
+   if (t_ch != p_ch)
+   return FALSE;
+   continue;
+   case '?':
+   /* Match anything but '/'. */
+   if (t_ch == '/')
+  

[PATCH 06/13] Integrate wildmatch to git

2012-10-15 Thread Nguyễn Thái Ngọc Duy
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 .gitignore   |   1 +
 Makefile |   3 +
 t/t3070-wildmatch.sh | 188 +++
 t/t3070/wildtest.txt | 165 
 test-wildmatch.c |  14 
 wildmatch.c  |   5 +-
 6 files changed, 210 insertions(+), 166 deletions(-)
 create mode 100755 t/t3070-wildmatch.sh
 delete mode 100644 t/t3070/wildtest.txt
 create mode 100644 test-wildmatch.c

diff --git a/.gitignore b/.gitignore
index f1acd3e..1153a4b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -193,6 +193,7 @@
 /test-sigchain
 /test-subprocess
 /test-svn-fe
+/test-wildmatch
 /common-cmds.h
 *.tar.gz
 *.dsc
diff --git a/Makefile b/Makefile
index 13293d3..bc868d1 100644
--- a/Makefile
+++ b/Makefile
@@ -503,6 +503,7 @@ TEST_PROGRAMS_NEED_X += test-sha1
 TEST_PROGRAMS_NEED_X += test-sigchain
 TEST_PROGRAMS_NEED_X += test-subprocess
 TEST_PROGRAMS_NEED_X += test-svn-fe
+TEST_PROGRAMS_NEED_X += test-wildmatch
 
 TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X))
 
@@ -674,6 +675,7 @@ LIB_H += unpack-trees.h
 LIB_H += userdiff.h
 LIB_H += utf8.h
 LIB_H += varint.h
+LIB_H += wildmatch.h
 LIB_H += xdiff-interface.h
 LIB_H += xdiff/xdiff.h
 
@@ -803,6 +805,7 @@ LIB_OBJS += userdiff.o
 LIB_OBJS += utf8.o
 LIB_OBJS += varint.o
 LIB_OBJS += walker.o
+LIB_OBJS += wildmatch.o
 LIB_OBJS += wrapper.o
 LIB_OBJS += write_or_die.o
 LIB_OBJS += ws.o
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
new file mode 100755
index 000..dbd3c8b
--- /dev/null
+++ b/t/t3070-wildmatch.sh
@@ -0,0 +1,188 @@
+#!/bin/sh
+
+test_description='wildmatch tests'
+
+. ./test-lib.sh
+
+match() {
+if [ $1 = 1 ]; then
+   test_expect_success wildmatch:match '$3' '$4' 
+   test-wildmatch wildmatch '$3' '$4'
+   
+else
+   test_expect_success wildmatch: no match '$3' '$4' 
+   ! test-wildmatch wildmatch '$3' '$4'
+   
+fi
+if [ $2 = 1 ]; then
+   test_expect_success fnmatch:  match '$3' '$4' 
+   test-wildmatch fnmatch '$3' '$4'
+   
+elif [ $2 = 0 ]; then
+   test_expect_success fnmatch:   no match '$3' '$4' 
+   ! test-wildmatch fnmatch '$3' '$4'
+   
+#else
+#  test_expect_success BROKEN_FNMATCH fnmatch:   '$3' '$4' 
+#  ! test-wildmatch fnmatch '$3' '$4'
+#  
+fi
+}
+
+# Basic wildmat features
+match 1 1 foo foo
+match 0 0 foo bar
+match 1 1 '' 
+match 1 1 foo '???'
+match 0 0 foo '??'
+match 1 1 foo '*'
+match 1 1 foo 'f*'
+match 0 0 foo '*f'
+match 1 1 foo '*foo*'
+match 1 1 foobar '*ob*a*r*'
+match 1 1 aaabababab '*ab'
+match 1 1 'foo*' 'foo\*'
+match 0 0 foobar 'foo\*bar'
+match 1 1 'f\oo' 'f\\oo'
+match 1 1 ball '*[al]?'
+match 0 0 ten '[ten]'
+match 1 1 ten '**[!te]'
+match 0 0 ten '**[!ten]'
+match 1 1 ten 't[a-g]n'
+match 0 0 ten 't[!a-g]n'
+match 1 1 ton 't[!a-g]n'
+match 1 1 ton 't[^a-g]n'
+match 1 1 'a]b' 'a[]]b'
+match 1 1 a-b 'a[]-]b'
+match 1 1 'a]b' 'a[]-]b'
+match 0 0 aab 'a[]-]b'
+match 1 1 aab 'a[]a-]b'
+match 1 1 ']' ']'
+
+# Extended slash-matching features
+match 0 0 'foo/baz/bar' 'foo*bar'
+match 1 0 'foo/baz/bar' 'foo**bar'
+match 0 0 'foo/bar' 'foo?bar'
+match 0 0 'foo/bar' 'foo[/]bar'
+match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
+match 0 0 'foo' '**/foo'
+match 1 1 '/foo' '**/foo'
+match 1 0 'bar/baz/foo' '**/foo'
+match 0 0 'bar/baz/foo' '*/foo'
+match 0 0 'foo/bar/baz' '**/bar*'
+match 1 0 'deep/foo/bar/baz' '**/bar/*'
+match 0 0 'deep/foo/bar/baz/' '**/bar/*'
+match 1 0 'deep/foo/bar/baz/' '**/bar/**'
+match 0 0 'deep/foo/bar' '**/bar/*'
+match 1 0 'deep/foo/bar/' '**/bar/**'
+match 1 0 'foo/bar/baz' '**/bar**'
+match 1 0 'foo/bar/baz/x' '*/bar/**'
+match 0 0 'deep/foo/bar/baz/x' '*/bar/**'
+match 1 0 'deep/foo/bar/baz/x' '**/bar/*/*'
+
+# Various additional tests
+match 0 0 'acrt' 'a[c-c]st'
+match 1 1 'acrt' 'a[c-c]rt'
+match 0 0 ']' '[!]-]'
+match 1 1 'a' '[!]-]'
+match 0 0 '' '\'
+match 0 0 '\' '\'
+match 0 0 '/\' '*/\'
+match 1 1 '/\' '*/\\'
+match 1 1 'foo' 'foo'
+match 1 1 '@foo' '@foo'
+match 0 0 'foo' '@foo'
+match 1 1 '[ab]' '\[ab]'
+match 1 1 '[ab]' '[[]ab]'
+match 1 1 '[ab]' '[[:]ab]'
+match 0 0 '[ab]' '[[::]ab]'
+match 1 1 '[ab]' '[[:digit]ab]'
+match 1 1 '[ab]' '[\[:]ab]'
+match 1 1 '?a?b' '\??\?b'
+match 1 1 'abc' '\a\b\c'
+match 0 0 'foo' ''
+match 1 0 'foo/bar/baz/to' '**/t[o]'
+
+# Character class tests
+match 1 1 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'
+match 0 0 'a' '[[:digit:][:upper:][:space:]]'
+match 1 1 'A' '[[:digit:][:upper:][:space:]]'
+match 1 0 '1' '[[:digit:][:upper:][:space:]]'
+match 0 0 '1' '[[:digit:][:upper:][:spaci:]]'
+match 1 1 ' ' '[[:digit:][:upper:][:space:]]'
+match 0 0 '.' '[[:digit:][:upper:][:space:]]'
+match 1 1 '.' '[[:digit:][:punct:][:space:]]'
+match 1 1 '5' '[[:xdigit:]]'
+match 1 1 'f' '[[:xdigit:]]'
+match 1 1 'D' '[[:xdigit:]]'
+match 1 0 '_' 

[PATCH 07/13] t3070: disable unreliable fnmatch tests

2012-10-15 Thread Nguyễn Thái Ngọc Duy
These tests show different results on different fnmatch() versions. We
don't want to test fnmatch here. We want to make sure wildmatch
behavior matches fnmatch and that only makes sense in cases when
fnmatch() behaves consistently.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 t/t3070-wildmatch.sh | 86 ++--
 1 file changed, 43 insertions(+), 43 deletions(-)

diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index dbd3c8b..dd95b00 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -52,11 +52,11 @@ match 1 1 ten 't[a-g]n'
 match 0 0 ten 't[!a-g]n'
 match 1 1 ton 't[!a-g]n'
 match 1 1 ton 't[^a-g]n'
-match 1 1 'a]b' 'a[]]b'
-match 1 1 a-b 'a[]-]b'
-match 1 1 'a]b' 'a[]-]b'
-match 0 0 aab 'a[]-]b'
-match 1 1 aab 'a[]a-]b'
+match 1 x 'a]b' 'a[]]b'
+match 1 x a-b 'a[]-]b'
+match 1 x 'a]b' 'a[]-]b'
+match 0 x aab 'a[]-]b'
+match 1 x aab 'a[]a-]b'
 match 1 1 ']' ']'
 
 # Extended slash-matching features
@@ -67,7 +67,7 @@ match 0 0 'foo/bar' 'foo[/]bar'
 match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
 match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
 match 0 0 'foo' '**/foo'
-match 1 1 '/foo' '**/foo'
+match 1 x '/foo' '**/foo'
 match 1 0 'bar/baz/foo' '**/foo'
 match 0 0 'bar/baz/foo' '*/foo'
 match 0 0 'foo/bar/baz' '**/bar*'
@@ -85,77 +85,77 @@ match 1 0 'deep/foo/bar/baz/x' '**/bar/*/*'
 match 0 0 'acrt' 'a[c-c]st'
 match 1 1 'acrt' 'a[c-c]rt'
 match 0 0 ']' '[!]-]'
-match 1 1 'a' '[!]-]'
+match 1 x 'a' '[!]-]'
 match 0 0 '' '\'
-match 0 0 '\' '\'
-match 0 0 '/\' '*/\'
-match 1 1 '/\' '*/\\'
+match 0 x '\' '\'
+match 0 x '/\' '*/\'
+match 1 x '/\' '*/\\'
 match 1 1 'foo' 'foo'
 match 1 1 '@foo' '@foo'
 match 0 0 'foo' '@foo'
 match 1 1 '[ab]' '\[ab]'
 match 1 1 '[ab]' '[[]ab]'
-match 1 1 '[ab]' '[[:]ab]'
-match 0 0 '[ab]' '[[::]ab]'
-match 1 1 '[ab]' '[[:digit]ab]'
-match 1 1 '[ab]' '[\[:]ab]'
+match 1 x '[ab]' '[[:]ab]'
+match 0 x '[ab]' '[[::]ab]'
+match 1 x '[ab]' '[[:digit]ab]'
+match 1 x '[ab]' '[\[:]ab]'
 match 1 1 '?a?b' '\??\?b'
 match 1 1 'abc' '\a\b\c'
 match 0 0 'foo' ''
 match 1 0 'foo/bar/baz/to' '**/t[o]'
 
 # Character class tests
-match 1 1 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'
-match 0 0 'a' '[[:digit:][:upper:][:space:]]'
-match 1 1 'A' '[[:digit:][:upper:][:space:]]'
-match 1 0 '1' '[[:digit:][:upper:][:space:]]'
-match 0 0 '1' '[[:digit:][:upper:][:spaci:]]'
-match 1 1 ' ' '[[:digit:][:upper:][:space:]]'
-match 0 0 '.' '[[:digit:][:upper:][:space:]]'
-match 1 1 '.' '[[:digit:][:punct:][:space:]]'
+match 1 x 'a1B' '[[:alpha:]][[:digit:]][[:upper:]]'
+match 0 x 'a' '[[:digit:][:upper:][:space:]]'
+match 1 x 'A' '[[:digit:][:upper:][:space:]]'
+match 1 x '1' '[[:digit:][:upper:][:space:]]'
+match 0 x '1' '[[:digit:][:upper:][:spaci:]]'
+match 1 x ' ' '[[:digit:][:upper:][:space:]]'
+match 0 x '.' '[[:digit:][:upper:][:space:]]'
+match 1 x '.' '[[:digit:][:punct:][:space:]]'
 match 1 1 '5' '[[:xdigit:]]'
 match 1 1 'f' '[[:xdigit:]]'
 match 1 1 'D' '[[:xdigit:]]'
-match 1 0 '_' 
'[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
-match 1 0 '_' 
'[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
-match 1 1 '.' 
'[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'
-match 1 1 '5' '[a-c[:digit:]x-z]'
-match 1 1 'b' '[a-c[:digit:]x-z]'
-match 1 1 'y' '[a-c[:digit:]x-z]'
-match 0 0 'q' '[a-c[:digit:]x-z]'
+match 1 x '_' 
'[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '_' 
'[[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:graph:][:lower:][:print:][:punct:][:space:][:upper:][:xdigit:]]'
+match 1 x '.' 
'[^[:alnum:][:alpha:][:blank:][:cntrl:][:digit:][:lower:][:space:][:upper:][:xdigit:]]'
+match 1 x '5' '[a-c[:digit:]x-z]'
+match 1 x 'b' '[a-c[:digit:]x-z]'
+match 1 x 'y' '[a-c[:digit:]x-z]'
+match 0 x 'q' '[a-c[:digit:]x-z]'
 
 # Additional tests, including some malformed wildmats
-match 1 1 ']' '[\\-^]'
+match 1 x ']' '[\\-^]'
 match 0 0 '[' '[\\-^]'
-match 1 1 '-' '[\-_]'
-match 1 1 ']' '[\]]'
+match 1 x '-' '[\-_]'
+match 1 x ']' '[\]]'
 match 0 0 '\]' '[\]]'
 match 0 0 '\' '[\]]'
 match 0 0 'ab' 'a[]b'
-match 0 1 'a[]b' 'a[]b'
-match 0 1 'ab[' 'ab['
+match 0 x 'a[]b' 'a[]b'
+match 0 x 'ab[' 'ab['
 match 0 0 'ab' '[!'
 match 0 0 'ab' '[-'
 match 1 1 '-' '[-]'
 match 0 0 '-' '[a-'
 match 0 0 '-' '[!a-'
-match 1 1 '-' '[--A]'
-match 1 1 '5' '[--A]'
+match 1 x '-' '[--A]'
+match 1 x '5' '[--A]'
 match 1 1 ' ' '[ --]'
 match 1 1 '$' '[ --]'
 match 1 1 '-' '[ --]'
 match 0 0 '0' '[ --]'
-match 1 1 '-' '[---]'
-match 1 1 '-' '[--]'
+match 1 x '-' '[---]'
+match 1 x '-' '[--]'
 match 0 0 'j' '[a-e-n]'
-match 1 1 '-' '[a-e-n]'
-match 1 1 'a' '[!--]'
+match 1 x '-' '[a-e-n]'
+match 1 x 'a' '[!--]'
 match 0 0 '[' '[]-a]'
-match 1 1 '^' '[]-a]'
+match 1 x '^' 

[PATCH 08/13] wildmatch: make wildmatch's return value compatible with fnmatch

2012-10-15 Thread Nguyễn Thái Ngọc Duy
wildmatch returns non-zero if matched, zero otherwise. This patch
makes it return zero if matches, non-zero otherwise, like fnmatch().

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

diff --git a/test-wildmatch.c b/test-wildmatch.c
index ac56420..77014e9 100644
--- a/test-wildmatch.c
+++ b/test-wildmatch.c
@@ -4,9 +4,9 @@
 int main(int argc, char **argv)
 {
if (!strcmp(argv[1], wildmatch))
-   return wildmatch(argv[3], argv[2]) ? 0 : 1;
+   return !!wildmatch(argv[3], argv[2]);
else if (!strcmp(argv[1], iwildmatch))
-   return iwildmatch(argv[3], argv[2]) ? 0 : 1;
+   return !!iwildmatch(argv[3], argv[2]);
else if (!strcmp(argv[1], fnmatch))
return !!fnmatch(argv[3], argv[2], FNM_PATHNAME);
else
diff --git a/wildmatch.c b/wildmatch.c
index ac29471..6d992d3 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -20,6 +20,9 @@ typedef unsigned char uchar;
 
 #define FALSE 0
 #define TRUE 1
+
+#define NOMATCH 1
+#define MATCH 0
 #define ABORT_ALL -1
 #define ABORT_TO_STARSTAR -2
 
@@ -78,12 +81,12 @@ static int dowild(const uchar *p, const uchar *text)
/* FALLTHROUGH */
default:
if (t_ch != p_ch)
-   return FALSE;
+   return NOMATCH;
continue;
case '?':
/* Match anything but '/'. */
if (t_ch == '/')
-   return FALSE;
+   return NOMATCH;
continue;
case '*':
if (*++p == '*') {
@@ -96,14 +99,14 @@ static int dowild(const uchar *p, const uchar *text)
 * only if there are no more slash characters. 
*/
if (!special) {
if (strchr((char*)text, '/') != NULL)
-   return FALSE;
+   return NOMATCH;
}
-   return TRUE;
+   return MATCH;
}
while (1) {
if (t_ch == '\0')
break;
-   if ((matched = dowild(p, text)) != FALSE) {
+   if ((matched = dowild(p, text)) != NOMATCH) {
if (!special || matched != 
ABORT_TO_STARSTAR)
return matched;
} else if (!special  t_ch == '/')
@@ -202,18 +205,18 @@ static int dowild(const uchar *p, const uchar *text)
matched = TRUE;
} while (prev_ch = p_ch, (p_ch = *++p) != ']');
if (matched == special || t_ch == '/')
-   return FALSE;
+   return NOMATCH;
continue;
}
}
 
-   return *text ? FALSE : TRUE;
+   return *text ? NOMATCH : MATCH;
 }
 
 /* Match the pattern against the text string. */
 int wildmatch(const char *pattern, const char *text)
 {
-   return dowild((const uchar*)pattern, (const uchar*)text) == TRUE;
+   return dowild((const uchar*)pattern, (const uchar*)text);
 }
 
 /* Match the pattern against the forced-to-lower-case text string. */
@@ -221,7 +224,7 @@ int iwildmatch(const char *pattern, const char *text)
 {
int ret;
force_lower_case = 1;
-   ret = dowild((const uchar*)pattern, (const uchar*)text) == TRUE;
+   ret = dowild((const uchar*)pattern, (const uchar*)text);
force_lower_case = 0;
return ret;
 }
-- 
1.8.0.rc0.29.g1fdd78f

--
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 09/13] wildmatch: remove static variable force_lower_case

2012-10-15 Thread Nguyễn Thái Ngọc Duy
One place less to worry about thread safety. Also combine wildmatch
and iwildmatch into one.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 test-wildmatch.c |  4 ++--
 wildmatch.c  | 21 +
 wildmatch.h  |  3 +--
 3 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/test-wildmatch.c b/test-wildmatch.c
index 77014e9..74c0864 100644
--- a/test-wildmatch.c
+++ b/test-wildmatch.c
@@ -4,9 +4,9 @@
 int main(int argc, char **argv)
 {
if (!strcmp(argv[1], wildmatch))
-   return !!wildmatch(argv[3], argv[2]);
+   return !!wildmatch(argv[3], argv[2], 0);
else if (!strcmp(argv[1], iwildmatch))
-   return !!iwildmatch(argv[3], argv[2]);
+   return !!wildmatch(argv[3], argv[2], FNM_CASEFOLD);
else if (!strcmp(argv[1], fnmatch))
return !!fnmatch(argv[3], argv[2], FNM_PATHNAME);
else
diff --git a/wildmatch.c b/wildmatch.c
index 6d992d3..eef7b13 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -59,10 +59,8 @@ typedef unsigned char uchar;
 #define ISUPPER(c) (ISASCII(c)  isupper(c))
 #define ISXDIGIT(c) (ISASCII(c)  isxdigit(c))
 
-static int force_lower_case = 0;
-
 /* Match pattern p against text */
-static int dowild(const uchar *p, const uchar *text)
+static int dowild(const uchar *p, const uchar *text, int force_lower_case)
 {
uchar p_ch;
 
@@ -106,7 +104,7 @@ static int dowild(const uchar *p, const uchar *text)
while (1) {
if (t_ch == '\0')
break;
-   if ((matched = dowild(p, text)) != NOMATCH) {
+   if ((matched = dowild(p, text,  
force_lower_case)) != NOMATCH) {
if (!special || matched != 
ABORT_TO_STARSTAR)
return matched;
} else if (!special  t_ch == '/')
@@ -214,17 +212,8 @@ static int dowild(const uchar *p, const uchar *text)
 }
 
 /* Match the pattern against the text string. */
-int wildmatch(const char *pattern, const char *text)
-{
-   return dowild((const uchar*)pattern, (const uchar*)text);
-}
-
-/* Match the pattern against the forced-to-lower-case text string. */
-int iwildmatch(const char *pattern, const char *text)
+int wildmatch(const char *pattern, const char *text, int flags)
 {
-   int ret;
-   force_lower_case = 1;
-   ret = dowild((const uchar*)pattern, (const uchar*)text);
-   force_lower_case = 0;
-   return ret;
+   return dowild((const uchar*)pattern, (const uchar*)text,
+ flags  FNM_CASEFOLD ? 1 :0);
 }
diff --git a/wildmatch.h b/wildmatch.h
index 562faa3..e974f9a 100644
--- a/wildmatch.h
+++ b/wildmatch.h
@@ -1,4 +1,3 @@
 /* wildmatch.h */
 
-int wildmatch(const char *pattern, const char *text);
-int iwildmatch(const char *pattern, const char *text);
+int wildmatch(const char *pattern, const char *text, int flags);
-- 
1.8.0.rc0.29.g1fdd78f

--
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 10/13] wildmatch: fix case-insensitive matching

2012-10-15 Thread Nguyễn Thái Ngọc Duy
dowild() does case insensitive matching by lower-casing the text. That
means lower case letters in patterns imply case-insensitive matching,
but upper case means exact matching.

We do not want that subtlety. Lower case pattern too so iwildmatch()
always does what we expect it to do.

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

diff --git a/wildmatch.c b/wildmatch.c
index eef7b13..5469866 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -71,6 +71,8 @@ static int dowild(const uchar *p, const uchar *text, int 
force_lower_case)
return ABORT_ALL;
if (force_lower_case  ISUPPER(t_ch))
t_ch = tolower(t_ch);
+   if (force_lower_case  ISUPPER(p_ch))
+   p_ch = tolower(p_ch);
switch (p_ch) {
case '\\':
/* Literal match with following character.  Note that 
the test
-- 
1.8.0.rc0.29.g1fdd78f

--
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 11/13] wildmatch: adjust ** behavior

2012-10-15 Thread Nguyễn Thái Ngọc Duy
Standard wildmatch() sees consecutive asterisks as * that can also
match slashes. But that may be hard to explain to users as
abc/**/def can match abcdef, abcxyzdef, abc/def, abc/x/def,
abc/x/y/def...

This patch changes wildmatch so that users can do

- **/def - all paths ending with file/directory 'def'
- abc/** - equivalent to /abc/
- abc/**/def - abc/x/def, abc/x/y/def...
- otherwise consider the pattern malformed if ** is found

Basically the magic of ** only remains if it's wrapped around by
slashes.

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

diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index dd95b00..15848d5 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -46,7 +46,7 @@ match 0 0 foobar 'foo\*bar'
 match 1 1 'f\oo' 'f\\oo'
 match 1 1 ball '*[al]?'
 match 0 0 ten '[ten]'
-match 1 1 ten '**[!te]'
+match 0 1 ten '**[!te]'
 match 0 0 ten '**[!ten]'
 match 1 1 ten 't[a-g]n'
 match 0 0 ten 't[!a-g]n'
@@ -61,7 +61,8 @@ match 1 1 ']' ']'
 
 # Extended slash-matching features
 match 0 0 'foo/baz/bar' 'foo*bar'
-match 1 0 'foo/baz/bar' 'foo**bar'
+match 0 0 'foo/baz/bar' 'foo**bar'
+match 0 1 'foobazbar' 'foo**bar'
 match 0 0 'foo/bar' 'foo?bar'
 match 0 0 'foo/bar' 'foo[/]bar'
 match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
diff --git a/wildmatch.c b/wildmatch.c
index 5469866..85bc0df 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -21,11 +21,6 @@ typedef unsigned char uchar;
 #define FALSE 0
 #define TRUE 1
 
-#define NOMATCH 1
-#define MATCH 0
-#define ABORT_ALL -1
-#define ABORT_TO_STARSTAR -2
-
 #define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 \
 *(class) == *(litmatch) \
 strncmp((char*)class, litmatch, len) == 
0)
@@ -90,8 +85,14 @@ static int dowild(const uchar *p, const uchar *text, int 
force_lower_case)
continue;
case '*':
if (*++p == '*') {
+   const uchar *prev_p = p - 2;
while (*++p == '*') {}
-   special = TRUE;
+   if ((prev_p == text || *prev_p == '/') ||
+   (*p == '\0' || *p == '/' ||
+(p[0] == '\\'  p[1] == '/'))) {
+   special = TRUE;
+   } else
+   return ABORT_MALFORMED;
} else
special = FALSE;
if (*p == '\0') {
diff --git a/wildmatch.h b/wildmatch.h
index e974f9a..984a38c 100644
--- a/wildmatch.h
+++ b/wildmatch.h
@@ -1,3 +1,9 @@
 /* wildmatch.h */
 
+#define ABORT_MALFORMED 2
+#define NOMATCH 1
+#define MATCH 0
+#define ABORT_ALL -1
+#define ABORT_TO_STARSTAR -2
+
 int wildmatch(const char *pattern, const char *text, int flags);
-- 
1.8.0.rc0.29.g1fdd78f

--
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 12/13] wildmatch: make /**/ match zero or more directories

2012-10-15 Thread Nguyễn Thái Ngọc Duy
foo/**/bar matches foo/x/bar, foo/x/y/bar... but not
foo/bar. We make a special case, when foo/**/ is detected (and
foo/ part is already matched), try matching bar with the rest of
the string.

Match one or more directories semantics can be easily achieved using
foo/*/**/bar.

This also makes **/foo match foo in addition to x/foo,
x/y/foo..

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 t/t3070-wildmatch.sh |  8 +++-
 wildmatch.c  | 12 
 2 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index 15848d5..e6ad6f4 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -63,11 +63,17 @@ match 1 1 ']' ']'
 match 0 0 'foo/baz/bar' 'foo*bar'
 match 0 0 'foo/baz/bar' 'foo**bar'
 match 0 1 'foobazbar' 'foo**bar'
+match 1 1 'foo/baz/bar' 'foo/**/bar'
+match 1 0 'foo/baz/bar' 'foo/**/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/**/bar'
+match 1 0 'foo/bar' 'foo/**/bar'
+match 1 0 'foo/bar' 'foo/**/**/bar'
 match 0 0 'foo/bar' 'foo?bar'
 match 0 0 'foo/bar' 'foo[/]bar'
 match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
 match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
-match 0 0 'foo' '**/foo'
+match 1 0 'foo' '**/foo'
 match 1 x '/foo' '**/foo'
 match 1 0 'bar/baz/foo' '**/foo'
 match 0 0 'bar/baz/foo' '*/foo'
diff --git a/wildmatch.c b/wildmatch.c
index 85bc0df..3972e26 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -90,6 +90,18 @@ static int dowild(const uchar *p, const uchar *text, int 
force_lower_case)
if ((prev_p == text || *prev_p == '/') ||
(*p == '\0' || *p == '/' ||
 (p[0] == '\\'  p[1] == '/'))) {
+   /*
+* Assuming we already match 'foo/' and 
are at
+* star star slash, just assume it 
matches
+* nothing and go ahead match the rest 
of the
+* pattern with the remaining string. 
This
+* helps make foo/**/bar ( because
+* otherwise it breaks C comment 
syntax) match
+* both foo/bar and foo/a/bar.
+*/
+   if (p[0] == '/' 
+   dowild(p + 1, text, 
force_lower_case) == MATCH)
+   return MATCH;
special = TRUE;
} else
return ABORT_MALFORMED;
-- 
1.8.0.rc0.29.g1fdd78f

--
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 13/13] Support ** wildcard in .gitignore and .gitattributes

2012-10-15 Thread Nguyễn Thái Ngọc Duy

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/gitignore.txt| 19 +++
 dir.c  |  4 +++-
 t/t0003-attributes.sh  | 37 +
 t/t3001-ls-files-others-exclude.sh | 18 ++
 4 files changed, 77 insertions(+), 1 deletion(-)

diff --git a/Documentation/gitignore.txt b/Documentation/gitignore.txt
index 2e7328b..d4747ce 100644
--- a/Documentation/gitignore.txt
+++ b/Documentation/gitignore.txt
@@ -96,6 +96,25 @@ PATTERN FORMAT
For example, /{asterisk}.c matches cat-file.c but not
mozilla-sha1/sha1.c.
 
+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.
+
 NOTES
 -
 
diff --git a/dir.c b/dir.c
index ee8e711..cb7328b 100644
--- a/dir.c
+++ b/dir.c
@@ -8,6 +8,7 @@
 #include cache.h
 #include dir.h
 #include refs.h
+#include wildmatch.h
 
 struct path_simplify {
int len;
@@ -593,7 +594,8 @@ int match_pathname(const char *pathname, int pathlen,
namelen -= prefix;
}
 
-   return fnmatch_icase(pattern, name, FNM_PATHNAME) == 0;
+   return wildmatch(pattern, name,
+ignore_case ? FNM_CASEFOLD : 0) == 0;
 }
 
 /* Scan the list and let the last match determine the fate.
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index f6c21ea..c962403 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -216,6 +216,43 @@ test_expect_success 'patterns starting with exclamation' '
attr_check !f foo
 '
 
+test_expect_success '** test' '
+   echo **/f foo=bar .gitattributes 
+   cat \EOF expect 
+f: foo: bar
+a/f: foo: bar
+a/b/f: foo: bar
+a/b/c/f: foo: bar
+EOF
+   git check-attr foo -- f actual 2err 
+   git check-attr foo -- a/f actual 2err 
+   git check-attr foo -- a/b/f actual 2err 
+   git check-attr foo -- a/b/c/f actual 2err 
+   test_cmp expect actual 
+   test_line_count = 0 err
+'
+
+test_expect_success '** with no slashes test' '
+   echo a**f foo=bar .gitattributes 
+   git check-attr foo -- f actual 
+   cat \EOF expect 
+f: foo: unspecified
+af: foo: bar
+axf: foo: bar
+a/f: foo: unspecified
+a/b/f: foo: unspecified
+a/b/c/f: foo: unspecified
+EOF
+   git check-attr foo -- f actual 2err 
+   git check-attr foo -- af actual 2err 
+   git check-attr foo -- axf actual 2err 
+   git check-attr foo -- a/f actual 2err 
+   git check-attr foo -- a/b/f actual 2err 
+   git check-attr foo -- a/b/c/f actual 2err 
+   test_cmp expect actual 
+   test_line_count = 0 err
+'
+
 test_expect_success 'setup bare' '
git clone --bare . bare.git 
cd bare.git
diff --git a/t/t3001-ls-files-others-exclude.sh 
b/t/t3001-ls-files-others-exclude.sh
index dc2f045..efb7ebc 100755
--- a/t/t3001-ls-files-others-exclude.sh
+++ b/t/t3001-ls-files-others-exclude.sh
@@ -220,4 +220,22 @@ test_expect_success 'pattern matches prefix completely' '
test_cmp expect actual
 '
 
+test_expect_success 'ls-files with ** patterns' '
+   cat \EOF expect 
+a.1
+one/a.1
+one/two/a.1
+three/a.1
+EOF
+   git ls-files -o -i --exclude **/a.1 actual
+   test_cmp expect actual
+'
+
+
+test_expect_success 'ls-files with ** patterns and no slashes' '
+   : expect 
+   git ls-files -o -i --exclude one**a.1 actual 
+   test_cmp expect actual
+'
+
 test_done
-- 
1.8.0.rc0.29.g1fdd78f

--
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 01/12] dir.c: rename cryptic 'which' variable to more consistent name

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

'el' is only *slightly* less cryptic, but is already used as the
variable name for a struct exclude_list pointer in numerous other
places, so this reduces the number of cryptic variable names in use by
one :-)

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 10 +-
 dir.h |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/dir.c b/dir.c
index ee8e711..f7219b5 100644
--- a/dir.c
+++ b/dir.c
@@ -347,7 +347,7 @@ void parse_exclude_pattern(const char **pattern,
 }
 
 void add_exclude(const char *string, const char *base,
-int baselen, struct exclude_list *which)
+int baselen, struct exclude_list *el)
 {
struct exclude *x;
int patternlen;
@@ -371,8 +371,8 @@ void add_exclude(const char *string, const char *base,
x-base = base;
x-baselen = baselen;
x-flags = flags;
-   ALLOC_GROW(which-excludes, which-nr + 1, which-alloc);
-   which-excludes[which-nr++] = x;
+   ALLOC_GROW(el-excludes, el-nr + 1, el-alloc);
+   el-excludes[el-nr++] = x;
 }
 
 static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
@@ -414,7 +414,7 @@ int add_excludes_from_file_to_list(const char *fname,
   const char *base,
   int baselen,
   char **buf_p,
-  struct exclude_list *which,
+  struct exclude_list *el,
   int check_index)
 {
struct stat st;
@@ -461,7 +461,7 @@ int add_excludes_from_file_to_list(const char *fname,
if (buf[i] == '\n') {
if (entry != buf + i  entry[0] != '#') {
buf[i - (i  buf[i-1] == '\r')] = 0;
-   add_exclude(entry, base, baselen, which);
+   add_exclude(entry, base, baselen, el);
}
entry = buf + i + 1;
}
diff --git a/dir.h b/dir.h
index f5c89e3..69cc7d2 100644
--- a/dir.h
+++ b/dir.h
@@ -105,11 +105,11 @@ extern int path_excluded(struct path_exclude_check *, 
const char *, int namelen,
 
 
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, 
int baselen,
- char **buf_p, struct exclude_list 
*which, int check_index);
+ char **buf_p, struct exclude_list 
*el, int check_index);
 extern void add_excludes_from_file(struct dir_struct *, const char *fname);
 extern void parse_exclude_pattern(const char **string, int *patternlen, int 
*flags, int *nowildcardlen);
 extern void add_exclude(const char *string, const char *base,
-   int baselen, struct exclude_list *which);
+   int baselen, struct exclude_list *el);
 extern void free_excludes(struct exclude_list *el);
 extern int file_exists(const char *);
 
-- 
1.8.0.rc0.29.g1fdd78f

--
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 02/12] dir.c: rename path_excluded() to is_path_excluded()

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

Start adopting clearer names for exclude functions.  This 'is_*'
naming pattern for functions returning booleans was agreed here:

http://thread.gmane.org/gmane.comp.version-control.git/204661/focus=204924

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c  | 2 +-
 builtin/ls-files.c | 2 +-
 dir.c  | 4 ++--
 dir.h  | 2 +-
 unpack-trees.c | 2 +-
 5 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index 89dce56..c689f37 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -453,7 +453,7 @@ int cmd_add(int argc, const char **argv, const char *prefix)
 !file_exists(pathspec[i])) {
if (ignore_missing) {
int dtype = DT_UNKNOWN;
-   if (path_excluded(check, pathspec[i], 
-1, dtype))
+   if (is_path_excluded(check, 
pathspec[i], -1, dtype))
dir_add_ignored(dir, 
pathspec[i], strlen(pathspec[i]));
} else
die(_(pathspec '%s' did not match any 
files),
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index 31b3f2d..ef7f99a 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -203,7 +203,7 @@ static void show_ru_info(void)
 static int ce_excluded(struct path_exclude_check *check, struct cache_entry 
*ce)
 {
int dtype = ce_to_dtype(ce);
-   return path_excluded(check, ce-name, ce_namelen(ce), dtype);
+   return is_path_excluded(check, ce-name, ce_namelen(ce), dtype);
 }
 
 static void show_files(struct dir_struct *dir)
diff --git a/dir.c b/dir.c
index f7219b5..6dfb815 100644
--- a/dir.c
+++ b/dir.c
@@ -679,8 +679,8 @@ void path_exclude_check_clear(struct path_exclude_check 
*check)
  * A path to a directory known to be excluded is left in check-path to
  * optimize for repeated checks for files in the same excluded directory.
  */
-int path_excluded(struct path_exclude_check *check,
- const char *name, int namelen, int *dtype)
+int is_path_excluded(struct path_exclude_check *check,
+const char *name, int namelen, int *dtype)
 {
int i;
struct strbuf *path = check-path;
diff --git a/dir.h b/dir.h
index 69cc7d2..d40aeea 100644
--- a/dir.h
+++ b/dir.h
@@ -101,7 +101,7 @@ struct path_exclude_check {
 };
 extern void path_exclude_check_init(struct path_exclude_check *, struct 
dir_struct *);
 extern void path_exclude_check_clear(struct path_exclude_check *);
-extern int path_excluded(struct path_exclude_check *, const char *, int 
namelen, int *dtype);
+extern int is_path_excluded(struct path_exclude_check *, const char *, int 
namelen, int *dtype);
 
 
 extern int add_excludes_from_file_to_list(const char *fname, const char *base, 
int baselen,
diff --git a/unpack-trees.c b/unpack-trees.c
index 33a5819..3ac6370 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -1372,7 +1372,7 @@ static int check_ok_to_remove(const char *name, int len, 
int dtype,
return 0;
 
if (o-dir 
-   path_excluded(o-path_exclude_check, name, -1, dtype))
+   is_path_excluded(o-path_exclude_check, name, -1, dtype))
/*
 * ce-name is explicitly excluded, so it is Ok to
 * overwrite it.
-- 
1.8.0.rc0.29.g1fdd78f

--
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 04/12] dir.c: rename excluded() to is_excluded()

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

Continue adopting clearer names for exclude functions.  This is_*
naming pattern for functions returning booleans was discussed here:

http://thread.gmane.org/gmane.comp.version-control.git/204661/focus=204924

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 attr.c |  2 +-
 dir.c  | 10 +-
 dir.h  |  4 ++--
 3 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/attr.c b/attr.c
index 2fc6353..5362563 100644
--- a/attr.c
+++ b/attr.c
@@ -284,7 +284,7 @@ static struct match_attr *parse_attr_line(const char *line, 
const char *src,
  * (reading the file from top to bottom), .gitattribute of the root
  * directory (again, reading the file from top to bottom) down to the
  * current directory, and then scan the list backwards to find the first match.
- * This is exactly the same as what excluded() does in dir.c to deal with
+ * This is exactly the same as what is_excluded() does in dir.c to deal with
  * .gitignore
  */
 
diff --git a/dir.c b/dir.c
index 7e1a23b..50381f8 100644
--- a/dir.c
+++ b/dir.c
@@ -639,7 +639,7 @@ int is_excluded_from_list(const char *pathname,
return -1; /* undecided */
 }
 
-static int excluded(struct dir_struct *dir, const char *pathname, int *dtype_p)
+static int is_excluded(struct dir_struct *dir, const char *pathname, int 
*dtype_p)
 {
int pathlen = strlen(pathname);
int st;
@@ -689,7 +689,7 @@ int is_path_excluded(struct path_exclude_check *check,
/*
 * we allow the caller to pass namelen as an optimization; it
 * must match the length of the name, as we eventually call
-* excluded() on the whole name string.
+* is_excluded() on the whole name string.
 */
if (namelen  0)
namelen = strlen(name);
@@ -706,7 +706,7 @@ int is_path_excluded(struct path_exclude_check *check,
 
if (ch == '/') {
int dt = DT_DIR;
-   if (excluded(check-dir, path-buf, dt))
+   if (is_excluded(check-dir, path-buf, dt))
return 1;
}
strbuf_addch(path, ch);
@@ -715,7 +715,7 @@ int is_path_excluded(struct path_exclude_check *check,
/* An entry in the index; cannot be a directory with subentries */
strbuf_setlen(path, 0);
 
-   return excluded(check-dir, name, dtype);
+   return is_excluded(check-dir, name, dtype);
 }
 
 static struct dir_entry *dir_entry_new(const char *pathname, int len)
@@ -1015,7 +1015,7 @@ static enum path_treatment treat_one_path(struct 
dir_struct *dir,
  const struct path_simplify *simplify,
  int dtype, struct dirent *de)
 {
-   int exclude = excluded(dir, path-buf, dtype);
+   int exclude = is_excluded(dir, path-buf, dtype);
if (exclude  (dir-flags  DIR_COLLECT_IGNORED)
 exclude_matches_pathspec(path-buf, path-len, simplify))
dir_add_ignored(dir, path-buf, path-len);
diff --git a/dir.h b/dir.h
index 2fce4bf..4b887cc 100644
--- a/dir.h
+++ b/dir.h
@@ -91,8 +91,8 @@ extern int match_pathname(const char *, int,
  const char *, int, int, int);
 
 /*
- * The excluded() API is meant for callers that check each level of leading
- * directory hierarchies with excluded() to avoid recursing into excluded
+ * The is_excluded() API is meant for callers that check each level of leading
+ * directory hierarchies with is_excluded() to avoid recursing into excluded
  * directories.  Callers that do not do so should use this API instead.
  */
 struct path_exclude_check {
-- 
1.8.0.rc0.29.g1fdd78f

--
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 06/12] dir.c: refactor is_excluded()

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

In a similar way to the previous commit, this extracts a new helper
function last_exclude_matching() which returns the last exclude_list
element which matched, or NULL if no match was found.  is_excluded()
becomes a wrapper around this, and just returns 0 or 1 depending on
whether any matching exclude_list element was found.

This allows callers to find out _why_ a given path was excluded,
rather than just whether it was or not, paving the way for a new git
sub-command which allows users to test their exclude lists from the
command line.

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 38 +-
 1 file changed, 29 insertions(+), 9 deletions(-)

diff --git a/dir.c b/dir.c
index 859e0f9..c91a2f6 100644
--- a/dir.c
+++ b/dir.c
@@ -658,24 +658,44 @@ int is_excluded_from_list(const char *pathname,
return -1; /* undecided */
 }
 
-static int is_excluded(struct dir_struct *dir, const char *pathname, int 
*dtype_p)
+/*
+ * Loads the exclude lists for the directory containing pathname, then
+ * scans all exclude lists to determine whether pathname is excluded.
+ * Returns the exclude_list element which matched, or NULL for
+ * undecided.
+ */
+static struct exclude *last_exclude_matching(struct dir_struct *dir,
+const char *pathname,
+int *dtype_p)
 {
int pathlen = strlen(pathname);
int st;
+   struct exclude *exclude;
const char *basename = strrchr(pathname, '/');
basename = (basename) ? basename+1 : pathname;
 
prep_exclude(dir, pathname, basename-pathname);
for (st = EXC_CMDL; st = EXC_FILE; st++) {
-   switch (is_excluded_from_list(pathname, pathlen,
- basename, dtype_p,
- dir-exclude_list[st])) {
-   case 0:
-   return 0;
-   case 1:
-   return 1;
-   }
+   exclude = last_exclude_matching_from_list(
+   pathname, pathlen, basename, dtype_p,
+   dir-exclude_list[st]);
+   if (exclude)
+   return exclude;
}
+   return NULL;
+}
+
+/*
+ * Loads the exclude lists for the directory containing pathname, then
+ * scans all exclude lists to determine whether pathname is excluded.
+ * Returns 1 if true, otherwise 0.
+ */
+static int is_excluded(struct dir_struct *dir, const char *pathname, int 
*dtype_p)
+{
+   struct exclude *exclude =
+   last_exclude_matching(dir, pathname, dtype_p);
+   if (exclude)
+   return exclude-flags  EXC_FLAG_NEGATIVE ? 0 : 1;
return 0;
 }
 
-- 
1.8.0.rc0.29.g1fdd78f

--
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 07/12] dir.c: refactor is_path_excluded()

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

In a similar way to the previous commit, this extracts a new helper
function last_exclude_matching_path() which return the last
exclude_list element which matched, or NULL if no match was found.
is_path_excluded() becomes a wrapper around this, and just returns 0
or 1 depending on whether any matching exclude_list element was found.

This allows callers to find out _why_ a given path was excluded,
rather than just whether it was or not, paving the way for a new git
sub-command which allows users to test their exclude lists from the
command line.

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 dir.c | 47 ++-
 dir.h |  3 +++
 2 files changed, 41 insertions(+), 9 deletions(-)

diff --git a/dir.c b/dir.c
index c91a2f6..84ab826 100644
--- a/dir.c
+++ b/dir.c
@@ -703,6 +703,7 @@ void path_exclude_check_init(struct path_exclude_check 
*check,
 struct dir_struct *dir)
 {
check-dir = dir;
+   check-exclude = NULL;
strbuf_init(check-path, 256);
 }
 
@@ -712,18 +713,21 @@ void path_exclude_check_clear(struct path_exclude_check 
*check)
 }
 
 /*
- * Is this name excluded?  This is for a caller like show_files() that
- * do not honor directory hierarchy and iterate through paths that are
- * possibly in an ignored directory.
+ * For each subdirectory in name, starting with the top-most, checks
+ * to see if that subdirectory is excluded, and if so, returns the
+ * corresponding exclude structure.  Otherwise, checks whether name
+ * itself (which is presumably a file) is excluded.
  *
  * A path to a directory known to be excluded is left in check-path to
  * optimize for repeated checks for files in the same excluded directory.
  */
-int is_path_excluded(struct path_exclude_check *check,
-const char *name, int namelen, int *dtype)
+struct exclude *last_exclude_matching_path(struct path_exclude_check *check,
+  const char *name, int namelen,
+  int *dtype)
 {
int i;
struct strbuf *path = check-path;
+   struct exclude *exclude;
 
/*
 * we allow the caller to pass namelen as an optimization; it
@@ -733,11 +737,17 @@ int is_path_excluded(struct path_exclude_check *check,
if (namelen  0)
namelen = strlen(name);
 
+   /*
+* If path is non-empty, and name is equal to path or a
+* subdirectory of path, name should be excluded, because
+* it's inside a directory which is already known to be
+* excluded and was previously left in check-path.
+*/
if (path-len 
path-len = namelen 
!memcmp(name, path-buf, path-len) 
(!name[path-len] || name[path-len] == '/'))
-   return 1;
+   return check-exclude;
 
strbuf_setlen(path, 0);
for (i = 0; name[i]; i++) {
@@ -745,8 +755,12 @@ int is_path_excluded(struct path_exclude_check *check,
 
if (ch == '/') {
int dt = DT_DIR;
-   if (is_excluded(check-dir, path-buf, dt))
-   return 1;
+   exclude = last_exclude_matching(check-dir,
+   path-buf, dt);
+   if (exclude) {
+   check-exclude = exclude;
+   return exclude;
+   }
}
strbuf_addch(path, ch);
}
@@ -754,7 +768,22 @@ int is_path_excluded(struct path_exclude_check *check,
/* An entry in the index; cannot be a directory with subentries */
strbuf_setlen(path, 0);
 
-   return is_excluded(check-dir, name, dtype);
+   return last_exclude_matching(check-dir, name, dtype);
+}
+
+/*
+ * Is this name excluded?  This is for a caller like show_files() that
+ * do not honor directory hierarchy and iterate through paths that are
+ * possibly in an ignored directory.
+ */
+int is_path_excluded(struct path_exclude_check *check,
+ const char *name, int namelen, int *dtype)
+{
+   struct exclude *exclude =
+   last_exclude_matching_path(check, name, namelen, dtype);
+   if (exclude)
+   return exclude-flags  EXC_FLAG_NEGATIVE ? 0 : 1;
+   return 0;
 }
 
 static struct dir_entry *dir_entry_new(const char *pathname, int len)
diff --git a/dir.h b/dir.h
index 4b887cc..02ac0bf 100644
--- a/dir.h
+++ b/dir.h
@@ -97,10 +97,13 @@ extern int match_pathname(const char *, int,
  */
 struct path_exclude_check {
struct dir_struct *dir;
+   struct exclude *exclude;
struct strbuf path;
 };
 extern void path_exclude_check_init(struct path_exclude_check *, struct 
dir_struct 

[PATCH 08/12] dir.c: keep track of where patterns came from

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

For exclude patterns read in from files, the filename is stored together
with the corresponding line number (counting starting at 1).

For exclude patterns provided on the command line, the sequence number
is negative, with counting starting at -1, so for example the 2nd
pattern provided via --exclude would be numbered -2.  This allows any
future consumers of that data to easily distinguish between exclude
patterns from files vs. from the CLI.

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/clean.c|  2 +-
 builtin/ls-files.c |  3 ++-
 dir.c  | 26 --
 dir.h  |  5 -
 4 files changed, 27 insertions(+), 9 deletions(-)

diff --git a/builtin/clean.c b/builtin/clean.c
index 0c7b3d0..f618231 100644
--- a/builtin/clean.c
+++ b/builtin/clean.c
@@ -99,7 +99,7 @@ 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,
-   dir.exclude_list[EXC_CMDL]);
+   dir.exclude_list[EXC_CMDL], --exclude option, 
-(i+1));
 
pathspec = get_pathspec(prefix, argv);
 
diff --git a/builtin/ls-files.c b/builtin/ls-files.c
index ef7f99a..db3c081 100644
--- a/builtin/ls-files.c
+++ b/builtin/ls-files.c
@@ -35,6 +35,7 @@ static int error_unmatch;
 static char *ps_matched;
 static const char *with_tree;
 static int exc_given;
+static int exclude_args;
 
 static const char *tag_cached = ;
 static const char *tag_unmerged = ;
@@ -423,7 +424,7 @@ static int option_parse_exclude(const struct option *opt,
struct exclude_list *list = opt-value;
 
exc_given = 1;
-   add_exclude(arg, , 0, list);
+   add_exclude(arg, , 0, list, --exclude option, --exclude_args);
 
return 0;
 }
diff --git a/dir.c b/dir.c
index 84ab826..81a5dd5 100644
--- a/dir.c
+++ b/dir.c
@@ -347,7 +347,8 @@ void parse_exclude_pattern(const char **pattern,
 }
 
 void add_exclude(const char *string, const char *base,
-int baselen, struct exclude_list *el)
+int baselen, struct exclude_list *el,
+const char *src, int srcpos)
 {
struct exclude *x;
int patternlen;
@@ -371,6 +372,8 @@ void add_exclude(const char *string, const char *base,
x-base = base;
x-baselen = baselen;
x-flags = flags;
+   x-src = src;
+   x-srcpos = srcpos;
ALLOC_GROW(el-excludes, el-nr + 1, el-alloc);
el-excludes[el-nr++] = x;
 }
@@ -418,7 +421,7 @@ int add_excludes_from_file_to_list(const char *fname,
   int check_index)
 {
struct stat st;
-   int fd, i;
+   int fd, i, lineno = 1;
size_t size = 0;
char *buf, *entry;
 
@@ -461,8 +464,10 @@ int add_excludes_from_file_to_list(const char *fname,
if (buf[i] == '\n') {
if (entry != buf + i  entry[0] != '#') {
buf[i - (i  buf[i-1] == '\r')] = 0;
-   add_exclude(entry, base, baselen, el);
+   add_exclude(entry, base, baselen, el,
+   fname, lineno);
}
+   lineno++;
entry = buf + i + 1;
}
}
@@ -493,8 +498,10 @@ static void prep_exclude(struct dir_struct *dir, const 
char *base, int baselen)
!strncmp(dir-basebuf, base, stk-baselen))
break;
dir-exclude_stack = stk-prev;
-   while (stk-exclude_ix  el-nr)
-   free(el-excludes[--el-nr]);
+   while (stk-exclude_ix  el-nr) {
+   struct exclude *exclude = el-excludes[--el-nr];
+   free(exclude);
+   }
free(stk-filebuf);
free(stk);
}
@@ -521,7 +528,14 @@ static void prep_exclude(struct dir_struct *dir, const 
char *base, int baselen)
memcpy(dir-basebuf + current, base + current,
   stk-baselen - current);
strcpy(dir-basebuf + stk-baselen, dir-exclude_per_dir);
-   add_excludes_from_file_to_list(dir-basebuf,
+
+   /*
+* dir-basebuf gets reused by the traversal, but we
+* need fname to remain unchanged to ensure the src
+* member of each struct exclude correctly back-references
+* its source file.
+*/
+   add_excludes_from_file_to_list(strdup(dir-basebuf),
   dir-basebuf, stk-baselen,
   stk-filebuf, el, 1);
dir-exclude_stack = stk;
diff 

[PATCH 09/12] dir.c: refactor treat_gitlinks()

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

Extract the body of the for loop in treat_gitlinks() into a separate
treat_gitlink() function so that it can be reused elsewhere.  This
paves the way for a new check-ignore sub-command.

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 builtin/add.c | 49 +++--
 1 file changed, 31 insertions(+), 18 deletions(-)

diff --git a/builtin/add.c b/builtin/add.c
index c689f37..6d2fb0c 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -153,31 +153,44 @@ static char *prune_directory(struct dir_struct *dir, 
const char **pathspec, int
return seen;
 }
 
-static void treat_gitlinks(const char **pathspec)
+/*
+ * Check whether path refers to a submodule, or something inside a
+ * submodule.  If the former, returns the path with any trailing slash
+ * stripped.  If the latter, dies with an error message.
+ */
+const char *treat_gitlink(const char *path)
 {
-   int i;
-
-   if (!pathspec || !*pathspec)
-   return;
-
+   int i, path_len = strlen(path);
for (i = 0; i  active_nr; i++) {
struct cache_entry *ce = active_cache[i];
if (S_ISGITLINK(ce-ce_mode)) {
-   int len = ce_namelen(ce), j;
-   for (j = 0; pathspec[j]; j++) {
-   int len2 = strlen(pathspec[j]);
-   if (len2 = len || pathspec[j][len] != '/' ||
-   memcmp(ce-name, pathspec[j], len))
-   continue;
-   if (len2 == len + 1)
-   /* strip trailing slash */
-   pathspec[j] = xstrndup(ce-name, len);
-   else
-   die (_(Path '%s' is in submodule 
'%.*s'),
-   pathspec[j], len, ce-name);
+   int ce_len = ce_namelen(ce);
+   if (path_len = ce_len || path[ce_len] != '/' ||
+   memcmp(ce-name, path, ce_len))
+   /* path does not refer to this
+* submodule or anything inside it */
+   continue;
+   if (path_len == ce_len + 1) {
+   /* path refers to submodule;
+* strip trailing slash */
+   return xstrndup(ce-name, ce_len);
+   } else {
+   die (_(Path '%s' is in submodule '%.*s'),
+path, ce_len, ce-name);
}
}
}
+   return path;
+}
+
+void treat_gitlinks(const char **pathspec)
+{
+   if (!pathspec || !*pathspec)
+   return;
+
+   int i;
+   for (i = 0; pathspec[i]; i++)
+   pathspec[i] = treat_gitlink(pathspec[i]);
 }
 
 static void refresh(int verbose, const char **pathspec)
-- 
1.8.0.rc0.29.g1fdd78f

--
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 10/12] pathspec.c: move reusable code from builtin/add.c

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

This is in preparation for reuse by a new git check-ignore command.

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Makefile  |  2 ++
 builtin/add.c | 95 ++---
 pathspec.c| 98 +++
 pathspec.h|  6 
 4 files changed, 109 insertions(+), 92 deletions(-)
 create mode 100644 pathspec.c
 create mode 100644 pathspec.h

diff --git a/Makefile b/Makefile
index 13293d3..48facad 100644
--- a/Makefile
+++ b/Makefile
@@ -645,6 +645,7 @@ LIB_H += pack-refs.h
 LIB_H += pack-revindex.h
 LIB_H += parse-options.h
 LIB_H += patch-ids.h
+LIB_H += pathspec.h
 LIB_H += pkt-line.h
 LIB_H += progress.h
 LIB_H += prompt.h
@@ -758,6 +759,7 @@ LIB_OBJS += parse-options-cb.o
 LIB_OBJS += patch-delta.o
 LIB_OBJS += patch-ids.o
 LIB_OBJS += path.o
+LIB_OBJS += pathspec.o
 LIB_OBJS += pkt-line.o
 LIB_OBJS += preload-index.o
 LIB_OBJS += pretty.o
diff --git a/builtin/add.c b/builtin/add.c
index 6d2fb0c..927b0f2 100644
--- a/builtin/add.c
+++ b/builtin/add.c
@@ -6,6 +6,7 @@
 #include cache.h
 #include builtin.h
 #include dir.h
+#include pathspec.h
 #include exec_cmd.h
 #include cache-tree.h
 #include run-command.h
@@ -97,39 +98,6 @@ int add_files_to_cache(const char *prefix, const char 
**pathspec, int flags)
return !!data.add_errors;
 }
 
-static void fill_pathspec_matches(const char **pathspec, char *seen, int specs)
-{
-   int num_unmatched = 0, i;
-
-   /*
-* Since we are walking the index as if we were walking the directory,
-* we have to mark the matched pathspec as seen; otherwise we will
-* mistakenly think that the user gave a pathspec that did not match
-* anything.
-*/
-   for (i = 0; i  specs; i++)
-   if (!seen[i])
-   num_unmatched++;
-   if (!num_unmatched)
-   return;
-   for (i = 0; i  active_nr; i++) {
-   struct cache_entry *ce = active_cache[i];
-   match_pathspec(pathspec, ce-name, ce_namelen(ce), 0, seen);
-   }
-}
-
-static char *find_used_pathspec(const char **pathspec)
-{
-   char *seen;
-   int i;
-
-   for (i = 0; pathspec[i];  i++)
-   ; /* just counting */
-   seen = xcalloc(i, 1);
-   fill_pathspec_matches(pathspec, seen, i);
-   return seen;
-}
-
 static char *prune_directory(struct dir_struct *dir, const char **pathspec, 
int prefix)
 {
char *seen;
@@ -153,46 +121,6 @@ static char *prune_directory(struct dir_struct *dir, const 
char **pathspec, int
return seen;
 }
 
-/*
- * Check whether path refers to a submodule, or something inside a
- * submodule.  If the former, returns the path with any trailing slash
- * stripped.  If the latter, dies with an error message.
- */
-const char *treat_gitlink(const char *path)
-{
-   int i, path_len = strlen(path);
-   for (i = 0; i  active_nr; i++) {
-   struct cache_entry *ce = active_cache[i];
-   if (S_ISGITLINK(ce-ce_mode)) {
-   int ce_len = ce_namelen(ce);
-   if (path_len = ce_len || path[ce_len] != '/' ||
-   memcmp(ce-name, path, ce_len))
-   /* path does not refer to this
-* submodule or anything inside it */
-   continue;
-   if (path_len == ce_len + 1) {
-   /* path refers to submodule;
-* strip trailing slash */
-   return xstrndup(ce-name, ce_len);
-   } else {
-   die (_(Path '%s' is in submodule '%.*s'),
-path, ce_len, ce-name);
-   }
-   }
-   }
-   return path;
-}
-
-void treat_gitlinks(const char **pathspec)
-{
-   if (!pathspec || !*pathspec)
-   return;
-
-   int i;
-   for (i = 0; pathspec[i]; i++)
-   pathspec[i] = treat_gitlink(pathspec[i]);
-}
-
 static void refresh(int verbose, const char **pathspec)
 {
char *seen;
@@ -210,23 +138,6 @@ static void refresh(int verbose, const char **pathspec)
 free(seen);
 }
 
-static const char **validate_pathspec(int argc, const char **argv, const char 
*prefix)
-{
-   const char **pathspec = get_pathspec(prefix, argv);
-
-   if (pathspec) {
-   const char **p;
-   for (p = pathspec; *p; p++) {
-   if (has_symlink_leading_path(*p, strlen(*p))) {
-   int len = prefix ? strlen(prefix) : 0;
-   die(_('%s' is beyond a symbolic link), *p + 
len);
-   }
-   }
-   }

[PATCH 11/12] dir.c: provide free_directory() for reclaiming dir_struct memory

2012-10-15 Thread Nguyễn Thái Ngọc Duy
From: Adam Spiers g...@adamspiers.org

Signed-off-by: Adam Spiers g...@adamspiers.org
Signed-off-by: Junio C Hamano gits...@pobox.com
Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 Documentation/technical/api-directory-listing.txt |  2 ++
 dir.c | 28 +--
 dir.h |  1 +
 3 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/Documentation/technical/api-directory-listing.txt 
b/Documentation/technical/api-directory-listing.txt
index add6f43..ca571a8 100644
--- a/Documentation/technical/api-directory-listing.txt
+++ b/Documentation/technical/api-directory-listing.txt
@@ -76,4 +76,6 @@ marked. If you to exclude files, make sure you have loaded 
index first.
 
 * Use `dir.entries[]`.
 
+* Call `free_directory()` when none of the contained elements are no longer in 
use.
+
 (JC)
diff --git a/dir.c b/dir.c
index 81a5dd5..d50634d 100644
--- a/dir.c
+++ b/dir.c
@@ -481,6 +481,16 @@ void add_excludes_from_file(struct dir_struct *dir, const 
char *fname)
die(cannot use %s as an exclude file, fname);
 }
 
+static void free_exclude_stack(struct exclude_stack *stk)
+{
+   free(stk-filebuf);
+   free(stk);
+}
+
+/*
+ * Loads the per-directory exclude list for the substring of base
+ * which has a char length of baselen.
+ */
 static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
 {
struct exclude_list *el;
@@ -502,8 +512,7 @@ static void prep_exclude(struct dir_struct *dir, const char 
*base, int baselen)
struct exclude *exclude = el-excludes[--el-nr];
free(exclude);
}
-   free(stk-filebuf);
-   free(stk);
+   free_exclude_stack(stk);
}
 
/* Read from the parent directories and push them down. */
@@ -1521,3 +1530,18 @@ void free_pathspec(struct pathspec *pathspec)
free(pathspec-items);
pathspec-items = NULL;
 }
+
+void free_directory(struct dir_struct *dir)
+{
+   struct exclude_stack *stk;
+   int st;
+   for (st = EXC_CMDL; st = EXC_FILE; st++)
+   free_excludes(dir-exclude_list[st]);
+
+   stk = dir-exclude_stack;
+   while (stk) {
+   struct exclude_stack *prev = stk-prev;
+   free_exclude_stack(stk);
+   stk = prev;
+   }
+}
diff --git a/dir.h b/dir.h
index 3921aa9..fb57c66 100644
--- a/dir.h
+++ b/dir.h
@@ -117,6 +117,7 @@ extern void parse_exclude_pattern(const char **string, int 
*patternlen, int *fla
 extern void add_exclude(const char *string, const char *base,
int baselen, struct exclude_list *el, const char *src, 
int srcpos);
 extern void free_excludes(struct exclude_list *el);
+extern void free_directory(struct dir_struct *dir);
 extern int file_exists(const char *);
 
 extern int is_inside_dir(const char *dir);
-- 
1.8.0.rc0.29.g1fdd78f

--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Michael J Gruber
Sorry for being late ($DAYJOB and such), but I just noticed this is on
next already:

Simon Oosthoek venit, vidit, dixit 05.10.2012 23:10:
 By setting GIT_PS1_SHOW_COLORHINTS when using __git_ps1
 as PROMPT_COMMAND, you will get color hints in addition to
 a different character (*+% etc.)
 
 Signed-off-by: Simon Oosthoek soosth...@nieuwland.nl
 ---
  contrib/completion/git-prompt.sh |   42 
 +++---
  1 file changed, 39 insertions(+), 3 deletions(-)
 
 diff --git a/contrib/completion/git-prompt.sh 
 b/contrib/completion/git-prompt.sh
 index c50c94a..51285d7 100644
 --- a/contrib/completion/git-prompt.sh
 +++ b/contrib/completion/git-prompt.sh
 @@ -53,6 +53,12 @@
  # find one, or @{upstream} otherwise.  Once you have set
  # GIT_PS1_SHOWUPSTREAM, you can override it on a per-repository basis by
  # setting the bash.showUpstream config variable.
 +#
 +# If you would like a colored hint about the current dirty state, set
 +# GIT_PS1_SHOWCOLORHINTS to a nonempty value. When tracked files are
 +# modified, the branch name turns red, when all modifications are staged
 +# the branch name turns yellow and when all changes are checked in, the
 +# color changes to green. The colors are currently hardcoded in the function.
  
  # __gitdir accepts 0 or 1 arguments (i.e., location)
  # returns location of .git repo
 @@ -201,11 +207,12 @@ __git_ps1_show_upstream ()
  # __git_ps1 accepts 0 or 1 arguments (i.e., format string)
  # when called from PS1 using command substitution
  # in this mode it returns text to add to bash PS1 prompt (includes branch 
 name) or
 -# __git_ps1 accepts 0 or 2 arguments when called from PROMPT_COMMAND
 +# __git_ps1 accepts 0 or 2 arguments when called from PROMPT_COMMAND (pc)
  # in that case it _sets_ PS1. The arguments are parts of a PS1 string.
  # when both arguments are given, the first is prepended and the second 
 appended
  # to the state string when assigned to PS1, otherwise default start/end 
 strings
  # are used.
 +# In pcmode you can request colored hints using GIT_PS1_SHOWCOLORHINTS=true
  __git_ps1 ()
  {
   local pcmode=yes
 @@ -320,8 +327,37 @@ __git_ps1 ()
  
   local f=$w$i$s$u
   if [ $pcmode = yes ]; then
 - PS1=$ps1pc_start($c${b##refs/heads/}${f:+ 
 $f}$r$p)$ps1pc_end
 - elif [ $pcmode = no ]; then
 + PS1=$ps1pc_start(
 + if [ -n ${GIT_PS1_SHOWCOLORHINT-} ]; then

You're missing the S here (HINTS).

 + local c_red='\e[31m'
 + local c_green='\e[32m'
 + local c_yellow='\e[33m'
 + local c_lblue='\e[1;34m'
 + local c_purple='\e[35m'
 + local c_cyan='\e[36m'
 + local c_clear='\e[0m'
 + local branchstring=$c${b##refs/heads/}
 + local branch_color=$c_green
 + local flags_color=$c_cyan
 +
 + if [ $w = * ]; then
 + branch_color=$c_red
 + elif [ -n $i ]; then
 + branch_color=$c_yellow
 + fi
 +
 + # Setting PS1 directly with \[ and \] around 
 colors
 + # is necessary to prevent wrapping issues!
 + 
 PS1=$PS1\[$branch_color\]$branchstring\[$c_clear\]
 + if [ -n $f ]; then
 + PS1=$PS1 
 \[$flags_color\]$f\[$c_clear\]
 + fi
 + else
 + PS1=$PS1$c${b##refs/heads/}${f:+ $f}$r$p
 + fi
 + PS1=$PS1)$ps1pc_end
 + else
 + # NO color option unless in PROMPT_COMMAND mode
   printf -- ${1:- (%s)} $c${b##refs/heads/}${f:+ 
 $f}$r$p
   fi
   fi
 

I'm afraid I don't like this coloring style at all because it is
inconsistent with the color usage of git status -sb. First of all, the
colors are different, and second, the fact *what* is colored is
different. I had suggested following git status -sb for a good reason.
It colors a branch green and a detached head red. It colors change
(A/D/M/R) as red/green depending on non-cached/cached, so that's how */+
should be. Your call for $/% (I'd leave them uncolored).[*][**]

I think it's very confusing to have completely different schemes (not
just themes) for two versions of the same information: concise status
information.

So, please try and follow git status -sb.

Michael

[*] Really, there's nothin red about a branch when there are cached or
non-cached changes. They are changes wrt. to what's in HEAD resp. the
index, no matter what HEAD is.

[**] Also, coloring the 

BUG when trying to delete symbolic refs

2012-10-15 Thread Johan Herland
Hi,

At $dayjob we renamed a branch, and for a grace period, we kept the
old name as a symref/alias to the new name, to give our users a window
for switching. This has worked well, until we tried to remove the
symref/alias. The following script demonstrates what we discovered:

 $ git --version
 git version 1.8.0.rc2.249.g6cc8227
 $ git init symref_delete_test/
 Initialized empty Git repository in .../symref_delete_test/.git/
 $ cd symref_delete_test/
 $ echo foo  foo  git add foo  git commit -m foo
 [master (root-commit) c7ae77e] foo
  1 file changed, 1 insertion(+)
  create mode 100644 foo
 $ git gc
 Counting objects: 3, done.
 Writing objects: 100% (3/3), done.
 Total 3 (delta 0), reused 0 (delta 0)
 $ cat .git/packed-refs
 # pack-refs with: peeled
 c7ae77e537138bee3f722e57e1af87a7011466cb refs/heads/master
 $ echo bar  foo  git commit -am bar
 [master 7451bf0] bar
  1 file changed, 1 insertion(+), 1 deletion(-)
 $ git symbolic-ref refs/heads/alias refs/heads/master
 $ git rev-parse master
 7451bf08b7aacedc9e88a9fa37a6c1f701071bbe
 $ git rev-parse alias
 7451bf08b7aacedc9e88a9fa37a6c1f701071bbe
 $ git branch -d alias
 Deleted branch alias (was 7451bf0).
 $ git rev-parse master
 c7ae77e537138bee3f722e57e1af87a7011466cb
 $ git rev-parse alias
 c7ae77e537138bee3f722e57e1af87a7011466cb
 $ cat .git/packed-refs
 # pack-refs with: peeled
 c7ae77e537138bee3f722e57e1af87a7011466cb refs/heads/master
 $ ls .git/refs/heads/
 alias

Basically, there is a master branch, and an alias symref to
master. When we naively try to delete the symref with git branch -d
alias, it ends up:

 - NOT deleting the alias symref
 - DELETING the master loose ref
 - NOT deleting the master packed ref

So, from the user perspective, git branch -d alias ends up resetting
master (and alias) back to the last time we happened to run git
gc. Needless to say, this is not quite what we had in mind...

AFAICS, there may be three possible acceptable outcomes when we run
git branch -d alias in the above scenario:

 A. The symbolic ref is deleted. This is obviously what we expected...

 B. The command fails because alias is a symref. This would be
understandable if we don't want to teach branch -d about symrefs.
But then, the error message should ideally explain which command we
should use to remove the symref.

 C. The master ref (BOTH loose and packed versions of it) is
deleted. This would be less helpful for us, but Git would at least be
internally consistent (in that the symref would be resolved, and the
command would become git branch -d master).

Obviously, I would advocate for option A. What say you?


Have fun! :)

...Johan

-- 
Johan Herland, jo...@herland.net
www.herland.net
--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Simon Oosthoek

On 10/15/2012 10:23 AM, Michael J Gruber wrote:

Sorry for being late ($DAYJOB and such), but I just noticed this is on
next already:


+   if [ -n ${GIT_PS1_SHOWCOLORHINT-} ]; then


You're missing the S here (HINTS).


indeed, well spotted!
My test setup was apparently configured without the S and the commented 
uses all had HINTS...






+   local c_red='\e[31m'
+   local c_green='\e[32m'
+   local c_yellow='\e[33m'
+   local c_lblue='\e[1;34m'
+   local c_purple='\e[35m'
+   local c_cyan='\e[36m'
+   local c_clear='\e[0m'
+   local branchstring=$c${b##refs/heads/}
+   local branch_color=$c_green
+   local flags_color=$c_cyan
+
+   if [ $w = * ]; then
+   branch_color=$c_red
+   elif [ -n $i ]; then
+   branch_color=$c_yellow
+   fi
+
+   # Setting PS1 directly with \[ and \] around 
colors
+   # is necessary to prevent wrapping issues!
+   
PS1=$PS1\[$branch_color\]$branchstring\[$c_clear\]
+   if [ -n $f ]; then
+   PS1=$PS1 
\[$flags_color\]$f\[$c_clear\]
+   fi
+   else
+   PS1=$PS1$c${b##refs/heads/}${f:+ $f}$r$p
+   fi
+   PS1=$PS1)$ps1pc_end
+   else
+   # NO color option unless in PROMPT_COMMAND mode
printf -- ${1:- (%s)} $c${b##refs/heads/}${f:+ 
$f}$r$p
fi
fi



I'm afraid I don't like this coloring style at all because it is
inconsistent with the color usage of git status -sb. First of all, the
colors are different, and second, the fact *what* is colored is
different. I had suggested following git status -sb for a good reason.
It colors a branch green and a detached head red. It colors change
(A/D/M/R) as red/green depending on non-cached/cached, so that's how */+
should be. Your call for $/% (I'd leave them uncolored).[*][**]


This way works for me. The coloring scheme itself is probably quite 
personal and can, and probably should, be modified by end-users.
(Whether the current code is suitable for user-modification is another 
matter)


I'm quite unfamiliar with the color coding of git (I hadn't enabled that 
option), I suppose consistency would be better, but then you'd have to 
add some code to figure out which color is used for what in git's output 
and convert that to the code setting the colors here.


As for the characters used, I think there's a good reason not to use the 
ones git uses in the prompt. The characters in git status output are put 
in front of the files they apply to, in the prompt you only get a 
summarized output. And perhaps that argument could be extended to the 
use of the colors as well, I prefer to know whether I have uncommitted 
changes and in that category I want to know whether I already staged 
them or not.


If I want to know which files are unstaged/uncommitted I do git status 
to see that.




I think it's very confusing to have completely different schemes (not
just themes) for two versions of the same information: concise status
information.

So, please try and follow git status -sb.


I think there are different levels of conciseness. And I see git status 
-sb uses green for staged modified files, which would be confusing to me.




Michael

[*] Really, there's nothin red about a branch when there are cached or
non-cached changes. They are changes wrt. to what's in HEAD resp. the
index, no matter what HEAD is.


Do you mean that red (unstaged) and yellow (staged) are both red to you?



[**] Also, coloring the status characters opens the way to even using
the same characters as status -sb (ADM).



Perhaps, but that would be confusing to me ;-)

Cheers

Simon
--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Michael J Gruber
Simon Oosthoek venit, vidit, dixit 15.10.2012 11:01:
 On 10/15/2012 10:23 AM, Michael J Gruber wrote:
 Sorry for being late ($DAYJOB and such), but I just noticed this is on
 next already:

 +   if [ -n ${GIT_PS1_SHOWCOLORHINT-} ]; then

 You're missing the S here (HINTS).
 
 indeed, well spotted!
 My test setup was apparently configured without the S and the commented 
 uses all had HINTS...
 
 

 +   local c_red='\e[31m'
 +   local c_green='\e[32m'
 +   local c_yellow='\e[33m'
 +   local c_lblue='\e[1;34m'
 +   local c_purple='\e[35m'
 +   local c_cyan='\e[36m'
 +   local c_clear='\e[0m'
 +   local branchstring=$c${b##refs/heads/}
 +   local branch_color=$c_green
 +   local flags_color=$c_cyan
 +
 +   if [ $w = * ]; then
 +   branch_color=$c_red
 +   elif [ -n $i ]; then
 +   branch_color=$c_yellow
 +   fi
 +
 +   # Setting PS1 directly with \[ and \] around 
 colors
 +   # is necessary to prevent wrapping issues!
 +   
 PS1=$PS1\[$branch_color\]$branchstring\[$c_clear\]
 +   if [ -n $f ]; then
 +   PS1=$PS1 
 \[$flags_color\]$f\[$c_clear\]
 +   fi
 +   else
 +   PS1=$PS1$c${b##refs/heads/}${f:+ $f}$r$p
 +   fi
 +   PS1=$PS1)$ps1pc_end
 +   else
 +   # NO color option unless in PROMPT_COMMAND mode
 printf -- ${1:- (%s)} $c${b##refs/heads/}${f:+ 
 $f}$r$p
 fi
 fi


 I'm afraid I don't like this coloring style at all because it is
 inconsistent with the color usage of git status -sb. First of all, the
 colors are different, and second, the fact *what* is colored is
 different. I had suggested following git status -sb for a good reason.
 It colors a branch green and a detached head red. It colors change
 (A/D/M/R) as red/green depending on non-cached/cached, so that's how */+
 should be. Your call for $/% (I'd leave them uncolored).[*][**]
 
 This way works for me. The coloring scheme itself is probably quite 
 personal and can, and probably should, be modified by end-users.
 (Whether the current code is suitable for user-modification is another 
 matter)

It really doesn't matter much what works for you, and it doesn't matter
what works for me either. The point is: What works for most users?

 I'm quite unfamiliar with the color coding of git (I hadn't enabled that 
 option), I suppose consistency would be better, but then you'd have to 
 add some code to figure out which color is used for what in git's output 
 and convert that to the code setting the colors here.

As a starter, you could use the default colors which git uses. Querying
git for the colors could be the next, optional step.

 As for the characters used, I think there's a good reason not to use the 
 ones git uses in the prompt. The characters in git status output are put 
 in front of the files they apply to, in the prompt you only get a 
 summarized output. And perhaps that argument could be extended to the 
 use of the colors as well, I prefer to know whether I have uncommitted 
 changes and in that category I want to know whether I already staged 
 them or not.

Well, sure. The prompt could show any of AMCRD if you have any of those
changes. * + are shortcuts saying you have any of those.

 If I want to know which files are unstaged/uncommitted I do git status 
 to see that.

Sure. I don't propose putting file names in the prompt ;)


 I think it's very confusing to have completely different schemes (not
 just themes) for two versions of the same information: concise status
 information.

 So, please try and follow git status -sb.
 
 I think there are different levels of conciseness. And I see git status 
 -sb uses green for staged modified files, which would be confusing to me.

...only because you don't know the color coding scheme. It's green
because those changes are saved somewhere (in the index) and would even
survice a branch switch.

 Michael

 [*] Really, there's nothin red about a branch when there are cached or
 non-cached changes. They are changes wrt. to what's in HEAD resp. the
 index, no matter what HEAD is.
 
 Do you mean that red (unstaged) and yellow (staged) are both red to you?

No, I said red for unstaged, green for staged for the characters, i.e. a
* would always be red if present, a + always green if present.

For the branch name, it would be red for detached head and green for
checked out branch.

 [**] Also, coloring the status characters opens the 

make test

2012-10-15 Thread Joachim Schmitz

Hi folks

I'm trying to understand why certain tests in 'make test' fail. Here's the 
first one


$ ../git --version
git version 1.8.0.rc2.5.g6b89306
$ GIT_TEST_CMP_USE_COPIED_CONTEXT=true ./t-basic.sh # our diff doesn't 
understand -u

ok 1 - .git/objects should be empty after git init in an empty repo
...
ok 3 - success is reported like this
not ok 4 - pretend we have a known breakage # TODO known breakage

   This is expected, right?

ok 5 - pretend we have fixed a known breakage (run in sub test-lib)
...
ok 11 - tests clean up after themselves

   the next is not though? Why might it be failing, where to check?

not ok - 12 tests clean up even on failures
#
#   mkdir failing-cleanup 
#   (
#   cd failing-cleanup 
#
#   cat failing-cleanup.sh -EOF 
#   #!/bin/sh
#
#   test_description='Failing tests with cleanup commands'
#
#   # Point to the t/test-lib.sh, which isn't in ../ as usual
#   TEST_DIRECTORY=/home/jojo/git/git/t
#   . $TEST_DIRECTORY/test-lib.sh
#
#   test_expect_success 'tests clean up even after a failure' '
#   touch clean-after-failure 
#   test_when_finished rm clean-after-failure 
#   (exit 1)
#   '
#   test_expect_success 'failure to clean up causes the test to 
fail' '

#   test_when_finished (exit 2)
#   '
#   test_done
#
#   EOF
#
#   chmod +x failing-cleanup.sh 
#   test_must_fail ./failing-cleanup.sh out 2err 
#   ! test -s err 
#   ! test -f trash 
directory.failing-cleanup/clean-after-failure 

#   sed -e 's/Z$//' -e 's/^ //' expect -\EOF 
#not ok - 1 tests clean up even after a failure
## Z
## touch clean-after-failure 
## test_when_finished rm clean-after-failure 
## (exit 1)
## Z
#not ok - 2 failure to clean up causes the test to fail
## Z
## test_when_finished (exit 2)
## Z
## failed 2 among 2 test(s)
#1..2
#   EOF
#   test_cmp expect out
#   )
#
ok 13 - git update-index without --add should fail adding
...
ok 47 - very long name in the index handled sanely
# still have 1 known breakage(s)
# failed 1 among remaining 46 test(s)
1..47

Bye, Jojo 



--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Simon Oosthoek

On 10/15/2012 11:13 AM, Michael J Gruber wrote:


It really doesn't matter much what works for you, and it doesn't matter
what works for me either. The point is: What works for most users?


Obviously, that was my point as well ;-)


I'm quite unfamiliar with the color coding of git (I hadn't enabled that
option), I suppose consistency would be better, but then you'd have to
add some code to figure out which color is used for what in git's output
and convert that to the code setting the colors here.


As a starter, you could use the default colors which git uses. Querying
git for the colors could be the next, optional step.


I suppose it would be a start.

so how should it be?

all committed: green branch, no characters
only staged changes: green branch, colored characters (yellow/red?)
only unstaged changes: red/yellow branch, colored characters (red)
staged and unstaged changes: red/yellow branch, multiple characters in 
red/yellow?)

detached head: red commit-sha1 (abbrev.), characters as above?

What is the most useful thing to show in case of a detached head?
-the commit hash of current head?
-detached head





As for the characters used, I think there's a good reason not to use the
ones git uses in the prompt. The characters in git status output are put
in front of the files they apply to, in the prompt you only get a
summarized output. And perhaps that argument could be extended to the
use of the colors as well, I prefer to know whether I have uncommitted
changes and in that category I want to know whether I already staged
them or not.


Well, sure. The prompt could show any of AMCRD if you have any of those
changes. * + are shortcuts saying you have any of those.


How do you suppose that should work?
Add another configuration parameter like GIT_PS1_SHOWSTATUSSBCHARS 
(please give a better suggestion ;-) or the other way around 
GIT_PS1_SHOWSTARPLUS (either of which could be the default)



I think it's very confusing to have completely different schemes (not
just themes) for two versions of the same information: concise status
information.

So, please try and follow git status -sb.


I think there are different levels of conciseness. And I see git status
-sb uses green for staged modified files, which would be confusing to me.


...only because you don't know the color coding scheme. It's green
because those changes are saved somewhere (in the index) and would even
survice a branch switch.


I suppose you could see that as green (I usually view a yellow traffic 
light as green as well ;-)


Isn't it best practice to commit the staged changes ASAP? (But let's not 
diverge in this thread to discuss best-practices, so consider that a 
rhetorical question for now ;-)



No, I said red for unstaged, green for staged for the characters, i.e. a
* would always be red if present, a + always green if present.

For the branch name, it would be red for detached head and green for
checked out branch.


using green for staged changes could be acceptable for me, but I'm 
slightly worried that a colored character would be too slight a hint.


OTOH, a detached head would show up with or without color...




Perhaps, but that would be confusing to me ;-)


If that is case, you can try and propose changing that scheme...

But there's really a good reason for it. Cached (staged) changes are
safe because they are saved in the index, and also they are good to
go into the next commit, i.e. the commit traffic lights are green!


I suppose I knew that in the back of my mind, but not as clearly as you 
spell it out here... Tnx!


/Simon

--
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: make test

2012-10-15 Thread Johannes Sixt
Am 10/15/2012 12:36, schrieb Joachim Schmitz:
 not ok 4 - pretend we have a known breakage # TODO known breakage
 
This is expected, right?

Right.

the next is not though? Why might it be failing, where to check?
 
 not ok - 12 tests clean up even on failures
 #
 #   mkdir failing-cleanup 
 #...
 #   test_cmp expect out
 #   )
 #

First thing:

  ./t-basic.sh -v -i

and if that does not give sufficient clues,

  $SHELL_PATH -x ./t-basic.sh -v -i

(Beware, though: in some cases, the latter gives additional failures, in
particular, when the stderr of a command is checked for with test_cmp
instead of grep because the 'actual' results contain the shell command
logs, which are not in the 'expected' results.)

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


t3302-notes-index-expensive.sh and t3419-rebase-patch-id.sh need time in /usr/bin

2012-10-15 Thread Joachim Schmitz

Hi folks

t3302-notes-index-expensive.sh and t3419-rebase-patch-id.sh need time  to 
be in /usr/bin, however on my system it is in /bin.


Can't this be checked for?

Bye, Jojo 



--
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: make test

2012-10-15 Thread Joachim Schmitz
 From: Johannes Sixt [mailto:j.s...@viscovery.net]
 Sent: Monday, October 15, 2012 12:53 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org
 Subject: Re: make test
 
 Am 10/15/2012 12:36, schrieb Joachim Schmitz:
  not ok 4 - pretend we have a known breakage # TODO known breakage
 
 This is expected, right?
 
 Right.
 
 the next is not though? Why might it be failing, where to check?
 
  not ok - 12 tests clean up even on failures
  #
  #   mkdir failing-cleanup 
  #...
  #   test_cmp expect out
  #   )
  #
 
 First thing:
 
   ./t-basic.sh -v -i

OK, I should have mentioned that I did look with -v :
not ok - 12 tests clean up even on failures
#
#   mkdir failing-cleanup 
#   (
#   cd failing-cleanup 
#
#   cat failing-cleanup.sh -EOF 
#   #!/bin/sh
#
#   test_description='Failing tests with cleanup commands'
#
#   # Point to the t/test-lib.sh, which isn't in ../ as usual
#   TEST_DIRECTORY=/home/jojo/git/git/t
#   . $TEST_DIRECTORY/test-lib.sh
#
#   test_expect_success 'tests clean up even after a failure' '
#   touch clean-after-failure 
#   test_when_finished rm clean-after-failure 
#   (exit 1)
#   '
#   test_expect_success 'failure to clean up causes the test to 
fail' '
#   test_when_finished (exit 2)
#   '
#   test_done
#
#   EOF
#
#   chmod +x failing-cleanup.sh 
#   test_must_fail ./failing-cleanup.sh out 2err 
#   ! test -s err 
#   ! test -f trash directory.failing-cleanup/clean-after-failure 

#   sed -e 's/Z$//' -e 's/^ //' expect -\EOF 
#not ok - 1 tests clean up even after a failure
## Z
## touch clean-after-failure 
## test_when_finished rm clean-after-failure 
## (exit 1)
## Z
#not ok - 2 failure to clean up causes the test to fail
## Z
## test_when_finished (exit 2)
## Z
## failed 2 among 2 test(s)
#1..2
#   EOF
#   test_cmp expect out
#   )
#

 and if that does not give sufficient clues,
 
   $SHELL_PATH -x ./t-basic.sh -v -i

not ok - 12 tests clean up even on failures
#
#   mkdir failing-cleanup 
#   (
#   cd failing-cleanup 
#
#   cat failing-cleanup.sh -EOF 
#   #!/bin/sh
#
#   test_description='Failing tests with cleanup commands'
#
#   # Point to the t/test-lib.sh, which isn't in ../ as usual
#   TEST_DIRECTORY=/home/jojo/git/git/t
#   . $TEST_DIRECTORY/test-lib.sh
#
#   test_expect_success 'tests clean up even after a failure' '
#   touch clean-after-failure 
#   test_when_finished rm clean-after-failure 
#   (exit 1)
#   '
#   test_expect_success 'failure to clean up causes the test to 
fail' '
#   test_when_finished (exit 2)
#   '
#   test_done
#
#   EOF
#
#   chmod +x failing-cleanup.sh 
#   test_must_fail ./failing-cleanup.sh out 2err 
#   ! test -s err 
#   ! test -f trash directory.failing-cleanup/clean-after-failure 

#   sed -e 's/Z$//' -e 's/^ //' expect -\EOF 
#not ok - 1 tests clean up even after a failure
## Z
## touch clean-after-failure 
## test_when_finished rm clean-after-failure 
## (exit 1)
## Z
#not ok - 2 failure to clean up causes the test to fail
## Z
## test_when_finished (exit 2)
## Z
## failed 2 among 2 test(s)
#1..2
#   EOF
#   test_cmp expect out
#   )
#
+ die

Looks identical, except for the die at the end. And still leaves me without a 
clue...

 (Beware, though: in some cases, the latter gives additional failures, in
 particular, when the stderr of a command is checked for with test_cmp
 instead of grep because the 'actual' results contain the shell command
 logs, which are not in the 'expected' results.)
 
 -- Hannes,

Bye, Jojo

--
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: push race

2012-10-15 Thread Matthieu Moy
Angelo Borsotti angelo.borso...@gmail.com writes:

 the push command checks first if the tips of the branches match those
 of the remote references, and if it does uploads the snapshot.

The update does two things: upload objects to the database, and then
update the reference. Adding objects to the database does not change the
repository until the objects are reachable from a ref. Updating the ref
is usually done giving the expected old sha1, and locks the ref, so it
can't change in the meantime.

I don't know this part of the code very well, but check refs.c for the C
part, and git update-ref for the plumbing interface.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
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: make test

2012-10-15 Thread Johannes Sixt
Am 10/15/2012 13:00, schrieb Joachim Schmitz:
 From: Johannes Sixt [mailto:j.s...@viscovery.net]
 and if that does not give sufficient clues,

   $SHELL_PATH -x ./t-basic.sh -v -i
 
 not ok - 12 tests clean up even on failures
 #...
 + die
 
 Looks identical, except for the die at the end. And still leaves me without 
 a clue...

When I do that it begins like this (I'm on Windows):

D:\Src\mingw-git\tbash -x t-basic.sh -v -i
+ test_description='Test the very basics part #1.
...
'
+ . ./test-lib.sh
++ ORIGINAL_TERM=cygwin
++ test -z ''
+++ pwd
++ TEST_DIRECTORY=/d/Src/mingw-git/t
++ test -z ''
++ TEST_OUTPUT_DIRECTORY=/d/Src/mingw-git/t
++ GIT_BUILD_DIR=/d/Src/mingw-git/t/..
++ /d/Src/mingw-git/t/../git
++ test 1 '!=' 1
++ . /d/Src/mingw-git/t/../GIT-BUILD-OPTIONS
+++ SHELL_PATH=/bin/sh
+++ PERL_PATH=/usr/bin/perl
+++ DIFF=diff
+++ PYTHON_PATH=/usr/bin/python
+++ TAR=tar
...

It seems you need a shell that is verbose under -x.

-- 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: make test

2012-10-15 Thread Joachim Schmitz
 From: Johannes Sixt [mailto:j.s...@viscovery.net]
 Sent: Monday, October 15, 2012 1:18 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org
 Subject: Re: make test
 
 Am 10/15/2012 13:00, schrieb Joachim Schmitz:
  From: Johannes Sixt [mailto:j.s...@viscovery.net]
  and if that does not give sufficient clues,
 
$SHELL_PATH -x ./t-basic.sh -v -i
 
  not ok - 12 tests clean up even on failures
  #...
  + die
 
  Looks identical, except for the die at the end. And still leaves me 
  without a clue...
 
 When I do that it begins like this (I'm on Windows):
 
 D:\Src\mingw-git\tbash -x t-basic.sh -v -i
 + test_description='Test the very basics part #1.
 ...
 '
 + . ./test-lib.sh
 ++ ORIGINAL_TERM=cygwin
 ++ test -z ''
 +++ pwd
 ++ TEST_DIRECTORY=/d/Src/mingw-git/t
 ++ test -z ''
 ++ TEST_OUTPUT_DIRECTORY=/d/Src/mingw-git/t
 ++ GIT_BUILD_DIR=/d/Src/mingw-git/t/..
 ++ /d/Src/mingw-git/t/../git
 ++ test 1 '!=' 1
 ++ . /d/Src/mingw-git/t/../GIT-BUILD-OPTIONS
 +++ SHELL_PATH=/bin/sh
 +++ PERL_PATH=/usr/bin/perl
 +++ DIFF=diff
 +++ PYTHON_PATH=/usr/bin/python
 +++ TAR=tar
 ...
 
 It seems you need a shell that is verbose under -x.


Erm, no, I left that part out...

+ . ./test-lib.sh
++ ORIGINAL_TERM=dumb
++ test -z ''
+++ pwd
++ TEST_DIRECTORY=/home/jojo/git/git/t
++ test -z ''
++ TEST_OUTPUT_DIRECTORY=/home/jojo/git/git/t
++ GIT_BUILD_DIR=/home/jojo/git/git/t/..
++ /home/jojo/git/git/t/../git
++ test 1 '!=' 1
++ . /home/jojo/git/git/t/../GIT-BUILD-OPTIONS
+++ SHELL_PATH=/bin/sh
+++ PERL_PATH=/usr/local/bin/perl
+++ DIFF=diff
+++ PYTHON_PATH=/usr/local/bin/python
+++ TAR=tar
+++ NO_CURL=
+++ USE_LIBPCRE=
+++ NO_PERL=
+++ NO_PYTHON=
+++ NO_UNIX_SOCKETS=
+++ GIT_TEST_CMP_USE_COPIED_CONTEXT=YesPlease
+++ NO_GETTEXT=
+++ GETTEXT_POISON=
++ export PERL_PATH SHELL_PATH
++ case $GIT_TEST_TEE_STARTED, $*  in
++ LANG=C
++ LC_ALL=C
++ PAGER=cat
++ TZ=UTC
++ TERM=dumb
++ export LANG LC_ALL PAGER TERM TZ
++ EDITOR=:
+++ /usr/local/bin/perl -e '
my @env = keys %ENV;
my $ok = join(|, qw(
TRACE
DEBUG
USE_LOOKUP
TEST
.*_TEST
PROVE
VALGRIND
PERF_AGGREGATING_LATER
));
my @vars = grep(/^GIT_/  !/^GIT_($ok)/o, @env);
print join(\n, @vars);
'
++ unset VISUAL EMAIL LANGUAGE COLUMNS GIT_AUTHOR_NAME GIT_MERGE_AUTOEDIT 
GIT_EXEC_PATH GIT_ATTR_NOSYSTEM GIT_MERGE_VERBOSITY
GIT_TEMPLATE_DIR GIT_CONFIG_NOSYSTEM GIT_AUTHOR_EMAIL GIT_COMMITTER_NAME 
GIT_COMMITTER_EMAIL
++ unset XDG_CONFIG_HOME
++ GIT_AUTHOR_EMAIL=aut...@example.com
++ GIT_AUTHOR_NAME='A U Thor'
++ GIT_COMMITTER_EMAIL=commit...@example.com
++ GIT_COMMITTER_NAME='C O Mitter'
++ GIT_MERGE_VERBOSITY=5
++ GIT_MERGE_AUTOEDIT=no
++ export GIT_MERGE_VERBOSITY GIT_MERGE_AUTOEDIT
++ export GIT_AUTHOR_EMAIL GIT_AUTHOR_NAME
++ export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME
++ export EDITOR
++ expr '  ' : '.* --valgrind '
++ test -n ''
++ unset CDPATH
++ unset GREP_OPTIONS
++ case $(echo $GIT_TRACE |tr [A-Z] [a-z]) in
+++ echo
+++ tr '[A-Z]' '[a-z]'
++ _x05='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
++
_x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-
f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0
-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'
++ _z40=
++ LF='
'
++ export _x05 _x40 _z40 LF
++ '[' xdumb '!=' xdumb ']'
++ test 2 -ne 0
++ case $1 in
++ verbose=t
++ shift
++ test 1 -ne 0
++ case $1 in
++ immediate=t
++ shift
++ test 0 -ne 0
++ test -n ''
++ test 'Test the very basics part #1.
The rest of the test suite does not check the basic operation of git
plumbing commands to work very carefully.  Their job is to concentrate
on tricky features that caused bugs in the past to detect regression.

This test runs very basic features, like registering things in cache,
writing tree, etc.

Note that this test *deliberately* hard-codes many expected object
IDs.  When object ID computation changes, like in the previous case of
swapping compression and hashing order, the person who is making the
modification *should* take notice and update the test vectors here.
' '!=' ''
++ test '' = t
++ exec
++ exec
++ test t = t
++ exec
++ test_failure=0
++ test_count=0
++ test_fixed=0
++ test_broken=0
++ test_success=0
++ test_external_has_tap=0
++ GIT_EXIT_OK=
++ trap die EXIT
++ . /home/jojo/git/git/t/test-lib-functions.sh
+++ satisfied_prereq=' '
+++ lazily_testable_prereq=
+++ lazily_tested_prereq=
++ test -n ''
++ test -n ''
++ git_bin_dir=/home/jojo/git/git/t/../bin-wrappers
++ test -x /home/jojo/git/git/t/../bin-wrappers/git
++
PATH=/home/jojo/git/git/t/../bin-wrappers:/home/jojo/git/git/t/../bin-wrappers:/bin:/bin/unsupported:/usr/bin:/usr/ucb:/usr/local/bi
n:/usr/tandem/java/bin:/home/jojo/bin
++ 

Re: make test

2012-10-15 Thread Johannes Sixt
Am 10/15/2012 13:37, schrieb Joachim Schmitz:
 ...
 + eval '
 find .git/objects -type f -print should-be-empty 
 test_line_count = 0 should-be-empty
 '
 ++ find .git/objects -type f -print
 ++ test_line_count = 0 should-be-empty
 ++ test 3 '!=' 3
 +++ wc -l
 ++ test 0 = 0
 + eval_ret=0

This is the key line. If it is 'eval_ret=1' (or other non-zero value),
then the test failed, and the lines above it usually indicate where in the
test snippet the failure occurred.

-- 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: push race

2012-10-15 Thread Nguyen Thai Ngoc Duy
On Mon, Oct 15, 2012 at 6:05 PM, Matthieu Moy
matthieu@grenoble-inp.fr wrote:
 Angelo Borsotti angelo.borso...@gmail.com writes:

 the push command checks first if the tips of the branches match those
 of the remote references, and if it does uploads the snapshot.

 The update does two things: upload objects to the database, and then
 update the reference. Adding objects to the database does not change the
 repository until the objects are reachable from a ref. Updating the ref
 is usually done giving the expected old sha1, and locks the ref, so it
 can't change in the meantime.

 I don't know this part of the code very well, but check refs.c for the C
 part, and git update-ref for the plumbing interface.

I think it's lock_any_ref_for_update(), which is called inside
refs.c:update_ref().
-- 
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: make test

2012-10-15 Thread Joachim Schmitz


 -Original Message-
 From: Johannes Sixt [mailto:j.s...@viscovery.net]
 Sent: Monday, October 15, 2012 1:53 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org
 Subject: Re: make test
 
 Am 10/15/2012 13:37, schrieb Joachim Schmitz:
  ...
  + eval '
  find .git/objects -type f -print should-be-empty 
  test_line_count = 0 should-be-empty
  '
  ++ find .git/objects -type f -print
  ++ test_line_count = 0 should-be-empty
  ++ test 3 '!=' 3
  +++ wc -l
  ++ test 0 = 0
  + eval_ret=0
 
 This is the key line. If it is 'eval_ret=1' (or other non-zero value),
 then the test failed, and the lines above it usually indicate where in the
 test snippet the failure occurred.


...
++ mkdir failing-cleanup
++ cd failing-cleanup
++ cat
++ chmod +x failing-cleanup.sh
++ test_must_fail ./failing-cleanup.sh
+ eval_ret=1
+ test -z t
+ test 1 = 0
+ test -n ''
+ test t = t
+ test -n ''
+ return 1
+ test_failure_ 'tests clean up even on failures' '
...

This part?

--
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: make test

2012-10-15 Thread Johannes Sixt
Am 10/15/2012 13:58, schrieb Joachim Schmitz:
 ++ mkdir failing-cleanup
 ++ cd failing-cleanup
 ++ cat
 ++ chmod +x failing-cleanup.sh
 ++ test_must_fail ./failing-cleanup.sh
 + eval_ret=1

I wonder why the log does not show the commands of function
test_must_fail. Is there a 'set +x' hidden somewhere? Run
./failing-cleanup.sh manually. Check its exit code (it should be non-zero,
but not something strange like 127 and above; see test_must_fail()) and
dig further from there. I'll stop here.

-- 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: make test

2012-10-15 Thread Andreas Schwab
Johannes Sixt j.s...@viscovery.net writes:

 Am 10/15/2012 13:58, schrieb Joachim Schmitz:
 ++ mkdir failing-cleanup
 ++ cd failing-cleanup
 ++ cat
 ++ chmod +x failing-cleanup.sh
 ++ test_must_fail ./failing-cleanup.sh
 + eval_ret=1

 I wonder why the log does not show the commands of function
 test_must_fail.

That's because stderr is redirected.

Andreas.

-- 
Andreas Schwab, sch...@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
And now for something completely different.
--
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: make test

2012-10-15 Thread Joachim Schmitz
 From: Johannes Sixt [mailto:j.s...@viscovery.net]
 Sent: Monday, October 15, 2012 2:10 PM
 To: Joachim Schmitz
 Cc: git@vger.kernel.org
 Subject: Re: make test
 
 Am 10/15/2012 13:58, schrieb Joachim Schmitz:
  ++ mkdir failing-cleanup
  ++ cd failing-cleanup
  ++ cat
  ++ chmod +x failing-cleanup.sh
  ++ test_must_fail ./failing-cleanup.sh
  + eval_ret=1
 
 I wonder why the log does not show the commands of function
 test_must_fail. Is there a 'set +x' hidden somewhere? Run
 ./failing-cleanup.sh manually. Check its exit code (it should be non-zero,
 but not something strange like 127 and above; see test_must_fail()) and
 dig further from there. I'll stop here.


It returns 0.

--
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: make test

2012-10-15 Thread Joachim Schmitz
 From: Andreas Schwab [mailto:sch...@linux-m68k.org]
 Sent: Monday, October 15, 2012 2:35 PM
 To: Johannes Sixt
 Cc: Joachim Schmitz; git@vger.kernel.org
 Subject: Re: make test
 
 Johannes Sixt j.s...@viscovery.net writes:
 
  Am 10/15/2012 13:58, schrieb Joachim Schmitz:
  ++ mkdir failing-cleanup
  ++ cd failing-cleanup
  ++ cat
  ++ chmod +x failing-cleanup.sh
  ++ test_must_fail ./failing-cleanup.sh
  + eval_ret=1
 
  I wonder why the log does not show the commands of function
  test_must_fail.
 
 That's because stderr is redirected.
 

cat err
++ ./failing-cleanup.sh
++ exit_code=0
++ test 0 = 0
++ echo 'test_must_fail: command succeeded: ./failing-cleanup.sh'
test_must_fail: command succeeded: ./failing-cleanup.sh
++ return 1

--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Simon Oosthoek

Hi Michael, sorry for the duplicate, forgot to reply-all...

On 10/15/2012 11:13 AM, Michael J Gruber wrote:


...only because you don't know the color coding scheme. It's green
because those changes are saved somewhere (in the index) and would even
survice a branch switch.



But git doesn't exactly let you do this:
I modified some things in git-prompt.sh trying to implement some of what 
we discussed. Then staged the file and tried git checkout HEAD^^ (or any 
branch)


error: Your local changes to the following files would be overwritten by 
checkout:

contrib/completion/git-prompt.sh
Please, commit your changes or stash them before you can switch branches.
Aborting

So I don't think it's all that strange to mark the branch as not quite 
safe to change. The idea (or at least my idea) behind these hints is 
that it reminds me to do stuff that prevents these Aborts. I think 
that that is a useful feature for any user of git.


In this light, would you accept yellow in the branch color to indicate 
uncommitted staged changes?


Cheers

Simon
--
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: push race

2012-10-15 Thread Ævar Arnfjörð Bjarmason
On Mon, Oct 15, 2012 at 11:14 AM, Angelo Borsotti
angelo.borso...@gmail.com wrote:
 Hello,

FWIW we have a lot of lemmings pushing to the same ref all the time at
$work, and while I've seen cases where:

 1. Two clients try to push
 2. They both get the initial lock
 3. One of them fails to get the secondary lock (I think updating the ref)

I've never seen cases where they clobber each other in #3 (and I would
have known from dude, where's my commit that I just pushed reports).

So while we could fix git to make sure there's no race condition such
that two clients never get the #2 lock I haven't seen it cause actual
data issues because of two clients getting the #3 lock.

It might still happen in some cases, I recommend testing it with e.g.
lots of pushes in parallel with GNU Parallel.
--
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: push race

2012-10-15 Thread demerphq
On 15 October 2012 16:09, Ævar Arnfjörð Bjarmason ava...@gmail.com wrote:
 On Mon, Oct 15, 2012 at 11:14 AM, Angelo Borsotti
 angelo.borso...@gmail.com wrote:
 Hello,

 FWIW we have a lot of lemmings pushing to the same ref all the time at
 $work, and while I've seen cases where:

  1. Two clients try to push
  2. They both get the initial lock
  3. One of them fails to get the secondary lock (I think updating the ref)

 I've never seen cases where they clobber each other in #3 (and I would
 have known from dude, where's my commit that I just pushed reports).

Except that the error message is really cryptic. It definitely doesnt
shout out maybe you collided with someone elses push.

Yves

-- 
perl -Mre=debug -e /just|another|perl|hacker/
--
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 UI experiment] diffstat: annotate/highlight new or removed files

2012-10-15 Thread Nguyễn Thái Ngọc Duy
diffstat does not show whether a file is added or deleted. I know
--summary does. But the problem with --summary is it makes me look for
information of a file in two places: diffstat and summary. And with a
commit that adds/removes a lot, showing both --stat --summary can be
long.

This patch adds (new), (gone) or (new mode) to diffstat, with
highlight, to easily catch file additions/removals. The extra text is
chosen to be short enough so that it won't take up too much space for
path names:

 .gitignore  |   1 +
 Makefile|   3 +
 t/t3070-wildmatch.sh (new)  | 188 
 t/t3070/wildtest.txt (gone) | 165 -
 test-wildmatch.c (new)  |  14 ++
 wildmatch.c |   5 +-
 6 files changed, 210 insertions(+), 166 deletions(-)

I don't put creation modes in there too because most of the time it
does not matter much to me and I could look down to --summary for mode
verification. But we could put (new+x) for 0755 and just (new) for
0644. (new mode) then could become (+x), (-x) or something like
that.

Coloring is to me an improvement over --summary. Probably the main
point. Without it, perhaps it's not worth putting extra text to
diffstat.

Single patch for easy testing. Test suite probably breaks.

Signed-off-by: Nguyễn Thái Ngọc Duy pclo...@gmail.com
---
 diff.c | 81 +-
 diff.h |  3 ++-
 utf8.c | 33 +++
 utf8.h |  2 ++
 4 files changed, 97 insertions(+), 22 deletions(-)

diff --git a/diff.c b/diff.c
index 35d3f07..f9217e6 100644
--- a/diff.c
+++ b/diff.c
@@ -45,6 +45,7 @@ static char diff_colors[][COLOR_MAXLEN] = {
GIT_COLOR_YELLOW,   /* COMMIT */
GIT_COLOR_BG_RED,   /* WHITESPACE */
GIT_COLOR_NORMAL,   /* FUNCINFO */
+   GIT_COLOR_YELLOW,   /* STATUSINFO */
 };
 
 static int parse_diff_color_slot(const char *var, int ofs)
@@ -65,6 +66,8 @@ static int parse_diff_color_slot(const char *var, int ofs)
return DIFF_WHITESPACE;
if (!strcasecmp(var+ofs, func))
return DIFF_FUNCINFO;
+   if (!strcasecmp(var+ofs, status))
+   return DIFF_STATUSINFO;
return -1;
 }
 
@@ -1223,7 +1226,8 @@ static void fn_out_consume(void *priv, char *line, 
unsigned long len)
}
 }
 
-static char *pprint_rename(const char *a, const char *b)
+static char *pprint_rename(struct diff_options *options,
+  const char *a, const char *b)
 {
const char *old = a;
const char *new = b;
@@ -1237,7 +1241,9 @@ static char *pprint_rename(const char *a, const char *b)
 
if (qlen_a || qlen_b) {
quote_c_style(a, name, NULL, 0);
-   strbuf_addstr(name,  = );
+   strbuf_addf(name,  %s=%s ,
+   diff_get_color_opt(options, DIFF_STATUSINFO),
+   diff_get_color_opt(options, DIFF_RESET));
quote_c_style(b, name, NULL, 0);
return strbuf_detach(name, NULL);
}
@@ -1278,13 +1284,19 @@ static char *pprint_rename(const char *a, const char *b)
strbuf_grow(name, pfx_length + a_midlen + b_midlen + sfx_length + 7);
if (pfx_length + sfx_length) {
strbuf_add(name, a, pfx_length);
-   strbuf_addch(name, '{');
+   strbuf_addf(name, %s{%s,
+   diff_get_color_opt(options, DIFF_STATUSINFO),
+   diff_get_color_opt(options, DIFF_RESET));
}
strbuf_add(name, a + pfx_length, a_midlen);
-   strbuf_addstr(name,  = );
+   strbuf_addf(name,  %s=%s ,
+   diff_get_color_opt(options, DIFF_STATUSINFO),
+   diff_get_color_opt(options, DIFF_RESET));
strbuf_add(name, b + pfx_length, b_midlen);
if (pfx_length + sfx_length) {
-   strbuf_addch(name, '}');
+   strbuf_addf(name, %s}%s,
+   diff_get_color_opt(options, DIFF_STATUSINFO),
+   diff_get_color_opt(options, DIFF_RESET));
strbuf_add(name, a + len_a - sfx_length, sfx_length);
}
return strbuf_detach(name, NULL);
@@ -1300,6 +1312,7 @@ struct diffstat_t {
unsigned is_unmerged:1;
unsigned is_binary:1;
unsigned is_renamed:1;
+   char status;
uintmax_t added, deleted;
} **files;
 };
@@ -1357,7 +1370,8 @@ static int scale_linear(int it, int width, int max_change)
 static void show_name(FILE *file,
  const char *prefix, const char *name, int len)
 {
-   fprintf(file,  %s%-*s |, prefix, len, name);
+   fprintf(file,  %s%-*s |, prefix,
+   len + strlen_ansi(name), name);
 }
 
 static void show_graph(FILE *file, char ch, int cnt, const char *set, const 
char *reset)
@@ -1370,7 +1384,8 @@ static void 

Re: push race

2012-10-15 Thread Marc Branchaud
On 12-10-15 10:09 AM, Ævar Arnfjörð Bjarmason wrote:
 On Mon, Oct 15, 2012 at 11:14 AM, Angelo Borsotti
 angelo.borso...@gmail.com wrote:
 Hello,
 
 FWIW we have a lot of lemmings pushing to the same ref all the time at
 $work, and while I've seen cases where:
 
  1. Two clients try to push
  2. They both get the initial lock
  3. One of them fails to get the secondary lock (I think updating the ref)
 
 I've never seen cases where they clobber each other in #3 (and I would
 have known from dude, where's my commit that I just pushed reports).
 
 So while we could fix git to make sure there's no race condition such
 that two clients never get the #2 lock I haven't seen it cause actual
 data issues because of two clients getting the #3 lock.
 
 It might still happen in some cases, I recommend testing it with e.g.
 lots of pushes in parallel with GNU Parallel.

Here's a previous discussion of a race in concurrent updates to the same ref,
even when the updates are all identical:

http://news.gmane.org/find-root.php?group=gmane.comp.version-control.gitarticle=164636

In that thread, Peff outlines the lock procedure for refs:

1. get the lock
2. check and remember the sha1
3. release the lock
4. do some long-running work (like the actual push)
5. get the lock
6. check that the sha1 is the same as the remembered one
7. update the sha1
8. release the lock

Angelo, in your case I think one of your concurrent updates would fail in
step 6.  As you say, this is after the changes have been uploaded.  However,
there's none of the file-overwriting that you fear, because the changes are
stored in git's object database under their SHA hashes.  So there'll only be
an object-level collision if two parties upload the exact same object, in
which case it doesn't matter.

M.

--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Simon Oosthoek

On 10/15/2012 11:39 AM, Junio C Hamano wrote:

Thanks for bringing some sanity to the color of the bikeshed ;-)

As I don't use colors very much, I didn't bother checking the color
assignment in the patch in question, but everything you said in your
response makes 100% sense, including the traffic light analogy.



Hi Junio, Michael

The point of the thread and the patch was to enable the possibility of 
colors in the prompt without messing it up.


The actual colors used are more or less how I'm used to it, but as you 
said they may not be suitable to everyone.


@Junio, is this patch something you want to include as it is now (with 
the extra S that Michael pointed out) or do you want to wait for a 
discussion about which colors to use for which state?


I guess it could be quite a messy discussion, as you already hint at 
bikeshed colors, it's quite personal and subjective.


As a start, I think it's worth considering what the color would actually 
mean.


To me:
A neutral color should mean it's safe to switch branches or merge/update
A non-neutral color would mean some action is required before switching 
branches.
There are various states that may or may not get in the way of 
switching, like stashed stuff or divergence from upstream. I think these 
could get a color hint, but I'm not sure what kind.


Cheers

Simon




--
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/5] Create html documents for all files in Documentation/RelNotes

2012-10-15 Thread Michael J Gruber
Junio C Hamano venit, vidit, dixit 07.10.2012 22:53:
 Jeff King p...@peff.net writes:
 
 [1] I would not be surprised if they do not actually format all that
 well. Though they are written in an asciidoc-ish style, they have
 not traditionally been formatted, and I suspect there are many small
 errors (like improper quoting of metacharacters) in them.
 
 They aren't even errors. As far as I (who writes the release
 notes) am concerned, they are straight text without any asciidoc
 or markdown mark-up.

I'm wondering: If it's neither markdown nor markup then what is it:
marklevel, markeven or markstraight?

Seriously, if Thomas converts them into asciidoc it's an added benefit
(and I don't think you'd have to change your writing by much), but
RelNotes should not be in the standard make target.

On a different note: Is pdf really the format of choice for mobile
platforms? I'd expect something that is formatted (markup) but can
reflow text intrinsically, not only by making your pdf reader jump
through hoops. HTML?

Michael


--
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 0/5] Create single PDF for all HTML files

2012-10-15 Thread Michael J Gruber
Jeff King venit, vidit, dixit 08.10.2012 00:52:
 On Sun, Oct 07, 2012 at 10:14:28AM +0200, Thomas Ackermann wrote:
 
 There are patched QT and unpatched QT versions of wkhtmltopdf
 (see http://code.google.com/p/wkhtmltopdf/). I am using V0.9.9 for Windows
 which is patched QT.
 
 That's a definite compatibility question for taking your patches into
 upstream git.
 
 There is one drawback with wkhtmltopdf: At least on my Netbook (Win7 64bit,
 Pentium 1.5GHz) it is very slow. It takes more than 3 hrs to create 
 git-doc.pdf.

 If you want to have a quick look on the resulting pdf just clone 
 https://github.com/tacker66/git-docpdf.git. This repo contains
 a current version of user.manual.pdf and git-doc.pdf 
 
 It does look better than the output generated by the man -Tdvi loop I
 posted. It retains more styling from the HTML and it has a nice table of
 contents. But 3 hours? Yeesh. Mine took 11 seconds.
 
 I wonder if a more sane route is to drop HTML entirely, convert the
 asciidoc to docbook (which we already do for manpages), and then create
 a docbook document that is a collection of all elements, which can then

Hmm, I think the html output often looks better than the man output
(tables and such), and it is a formatted, reflowable, interlinked format
fit for many puposes.

 be converted to pdf, epub, or whatever. I would not be surprised if
 somebody has solved this problem before (but it is not really my itch,
 so I did not look very far).

I'd rather ditch docbook and have one toolchain (asciidoc, unless we
want to switch to something else) only... We've been hunting asciidoc as
well as docbook compatibility (between versions) and interoperability
(between them) issues again and again.

In fact, if I remember correctly, that's what has been keeping us from
using *real* tables in the doc (but hasn't kept us from using tables ;) ).

Michael
--
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: build deps

2012-10-15 Thread Michael J Gruber
Thiago Farina venit, vidit, dixit 12.10.2012 06:08:
 On Thu, Oct 11, 2012 at 10:06 PM, Andrew Wong
 andrew.kw.w.li...@gmail.com wrote:
 On 10/11/12 16:54, Thiago Farina wrote:
 Just setting CC to gcc works for me. But still, I'd like to be able to
 build with clang (may be as you noted is just something with the + in
 my PATH).
 Oh, I just realized you were using sudo. The PATH environment was
 probably not inherited when you use sudo to run make. So the
 subsequent shells statred by make' were not able to find clang.
 
 Interesting, thank you for your observation.
 
 This worked for me now:
 
 $ git clone  https://github.com/gitster/git
 $ cd git
 $ make configure
 $ ./configure
 $ make
 $ ./git version
 git version 1.8.0.rc2
 
 clang reported this:
 combine-diff.c:1006:19: warning: adding 'int' to a string does not
 append to the string [-Wstring-plus-int]
 prefix = COLONS + offset;
  ~~~^~~~
 combine-diff.c:1006:19: note: use array indexing to silence this
 warning
 prefix = COLONS + offset;
 ^
[   ]
 1 warning generated.

Does

COLONS[offset]

silence that?


 grep.c:451:16: warning: comparison of unsigned enum expression  0 is
 always false [-Wtautological-compare]
 if (p-field  0 || GREP_HEADER_FIELD_MAX = p-field)
  ^ ~
 1 warning generated.
 

Right, that enum type starts at 0. Junio, you last touched this area.
Can we just dump the first comparison or did you have something else in
mind?

Michael
--
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: Planning to pass the baton to an interim maintainer

2012-10-15 Thread Michael J Gruber
Jeff King venit, vidit, dixit 15.10.2012 07:56:
 On Sun, Oct 14, 2012 at 11:23:07AM -0700, Junio C Hamano wrote:
 
 I am planning to

  * tag 1.8.0 final on Oct 21st (Sun);
  * go offline on Oct 22nd (Mon); and
  * come back online on Nov 12th (Mon).

 Peff, could you be the interim maintainer as you've done in earlier
 years while I was away?
 
 Sure, I look forward to ruling the list with an iron fist...er, helping
 contributors review their patches.

...the ironing fist, yeah ;)

Michael

--
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: push race

2012-10-15 Thread Angelo Borsotti
Hi Marc,

correct, there will be no file overwriting because no files are
written on the work tree.
I tried to follow the actions of the program, but did not quite catch
the 6. you mention.

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


error: git-fast-import died of signal 11

2012-10-15 Thread Uri Moszkowicz
Hi,
I'm trying to convert a CVS repository to Git using cvs2git. I was able to
generate the dump file without problem but am unable to get Git to
fast-import it. The dump file is 328GB and I ran git fast-import on a
machine with 512GB of RAM.

fatal: Out of memory? mmap failed: Cannot allocate memory
fast-import: dumping crash report to fast_import_crash_18192
error: git-fast-import died of signal 11

How can I import the repository?

Thanks,
Uri
--
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


When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Elia Pinto
Very clear analysis. Well written. Perhaps is it the time to update
http://git-scm.com/book/ch6-1.html (A SHORT NOTE ABOUT SHA-1) ?

Hope useful

http://www.schneier.com/crypto-gram-1210.html

Best Regards
--
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 v5 0/3] completion: refactor and zsh wrapper

2012-10-15 Thread Matthieu Moy
Felipe Contreras felipe.contre...@gmail.com writes:

 Hi,

 Here's a bit of reorganition. I'm introducing a new __gitcompadd helper that 
 is
 useful to wrapp all changes to COMPREPLY. 2nd and 3rd patches show how it's
 useful.

 The zsh wrapper is now very very simple, but I haven't received much feedback
 yet. I hope it will get in at some point in time.

I didn't review the code, but I've installed your patch series, and it
seems to work well.

-- 
Matthieu Moy
http://www-verimag.imag.fr/~moy/
--
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: Planning to pass the baton to an interim maintainer

2012-10-15 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 Jeff King venit, vidit, dixit 15.10.2012 07:56:
 On Sun, Oct 14, 2012 at 11:23:07AM -0700, Junio C Hamano wrote:
 
 I am planning to

  * tag 1.8.0 final on Oct 21st (Sun);
  * go offline on Oct 22nd (Mon); and
  * come back online on Nov 12th (Mon).

 Peff, could you be the interim maintainer as you've done in earlier
 years while I was away?
 
 Sure, I look forward to ruling the list with an iron fist...er, helping
 contributors review their patches.

 ...the ironing fist, yeah ;)

For the record, I do not iron every wrinkles out of everybody's
patches.  Anyhow, that is funny ;-)

--
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: A design for subrepositories

2012-10-15 Thread Jens Lehmann
Am 15.10.2012 00:59, schrieb Lauri Alanko:
 la@bq:~/tmp/super$ git mv sub movedsub
 fatal: source directory is empty, source=sub, destination=movedsub

 This error here indicates that we didn't teach git to properly move
 a submodule yet. It is one of my next goals to make git [submodule]
 mv sub movedsub do the right thing here.
 
 I'll digress here a bit: I'm not really fond of the idea of adding
 special-purpose support into the core git commands. It just makes them
 messier, and there will always be other tools that won't be supported by
 git directly. I'd much rather see an mv-hook that arbitrary extensions
 could use to update metadata associated with a tree entry.

One third of the participants of the GitSurvey2010 stated that they are
using submodules (e.g. more than gitattributes), so adding some support
for them into the core doesn't look that unwarranted to me. And believe
me, without putting support in there the user experience will stay
suboptimal.

 Indeed, one of the reasons a separate tool seemed attractive to me was
 that that way I could be sure that the tool was a high-level utility
 that was completely implemented on top of basic low-level git
 operations. The fact that git's submodule support manifests as bits and
 pieces in various parts of the core seems a bit worrisome to me.

I see it the other way around: Due to the fact that submodules were
only accessible via the submodule script and not integrated into the
core made a lot of people (e.g. the Jenkins Git plugin we are using at
work) code around that. That wouldn't have been necessary if I would
have finished my submodule update work at that time.

And e.g. you can't forget to add changes inside the submodule anymore
since diff and status learned to show those changes. And we still have
mis-merges at my dayjob due to not updated submodules, which will go
away the moment merge learns to update all submodules without merge
conflicts. And so on.

 (Moreover, it's confusing to the user. I read the git-submodule man page
 and thought that that described all the available submodule operations.
 Only now did I find out that clone and fetch also have built-in
 submodule functionality.)

Then the man page might need some overhaul. Care to take a look?

 la@bq:~/tmp/super$ mv sub movedsub

 Currently it is better to remove the submodule here, as recreating it
 with a git submodule update later will get the relative paths right.
 
 This was a bit of a special case, as this was the original directory
 where we did git init sub and git submodule add ./sub. So sub
 actually contains the real repository, not a gitlink to
 .git/modules/sub. Arguably git submodule add should move the local
 submodule's repository there.

That sounds like a good idea.

 la@bq:~/tmp/super$ git rm sub
 rm 'sub'
 la@bq:~/tmp/super$ git add movedsub

 And to git this adds a completely different submodule (as its name
 is not sub), which breaks your expectation.
 
 Submodule? This is just a normal git add, not git submodule add. I
 thought this just adds to the index a gitlink with the head revision in
 movedsub, which is the same as the head revision was in sub, so it's
 detected as a move of a gitlink.

You're free to use simple gitlinks, but then you can't expect existing
and coming goodies - like git being able to move them around in the
work tree - work all by itself, because they are only possible with
submodule support.

 To do what you intended
 use this line instead:

 $ git update-index --add --cacheinfo 16 $HASH movedsub
 
 Doesn't this do exactly the same thing as git add for a directory
 containing a repository?

In my test case git add movesub silently does nothing, as my
directory is empty. So I need the update-index here.

 la@bq:~/tmp/superc$ git submodule update --init
 Submodule 'sub' (/home/la/tmp/super/sub) registered for path 'sub'
 fatal: repository '/home/la/tmp/super/sub' does not exist
 Clone of '/home/la/tmp/super/sub' into submodule path 'sub' failed

 And that fails because to be able to clone a submodule it has to be
 pushed into its own repo first, so it can be cloned from there somewhere
 else. After doing that this will work.
 
 Sorry, but I can't get this to work. To me it seems that when fetching
 submodules from the origin, submodule.sub.url has to point to the actual
 location of the repository, and if this is outdated or missing, the
 fetch won't work.
 
 It would make sense that if the url is missing, the submodule repo
 inside origin's .git/modules would be used, but this doesn't seem to be
 the case currently.

No it isn't. Patches welcome ;-)

 Anyway, I am a bit surprised to hear of such active development for
 git-submodule. It's pretty old now (the shell script says 2007), and I
 thought that if it were to ever support the kind of basic functionality
 I require, it would do so already.

So much to do, so little time.

 How soon do you envision support for bare repositories with submodules?

I'm not sure what you mean by 

Re: [PATCH] git-cvsimport: allow author-specific timezones

2012-10-15 Thread Junio C Hamano
Chris Rorvick crorv...@cogcap.com writes:

 From: Chris Rorvick ch...@rorvick.com

 CVS patchsets are imported with timestamps having an offset of +
 (UTC).  The cvs-authors file is already used to translate the CVS
 username to full name and email in the corresponding commit.  Extend
 this file to support an optional timezone for calculating a user-
 specific timestamp offset.

 Signed-off-by: Chris Rorvick ch...@rorvick.com
 ---

 This supercedes the patches submitted for using the local timezone in
 commits.

  Documentation/git-cvsimport.txt|   5 +-
  git-cvsimport.perl |  22 ++-
  t/t9604-cvsimport-timestamps.sh|  92 +
  t/t9604/cvsroot/.gitattributes |   1 +
  t/t9604/cvsroot/CVSROOT/.gitignore |   2 +
  t/t9604/cvsroot/module/a,v | 265 
 +
  6 files changed, 381 insertions(+), 6 deletions(-)
  create mode 100775 t/t9604-cvsimport-timestamps.sh

OK, a new test script has its executable bit set (correct).

  create mode 100664 t/t9604/cvsroot/.gitattributes
  create mode 100664 t/t9604/cvsroot/CVSROOT/.gitignore
  create mode 100664 t/t9604/cvsroot/module/a,v

 diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
 index 6695ab3..35dc636 100644
 --- a/Documentation/git-cvsimport.txt
 +++ b/Documentation/git-cvsimport.txt
 @@ -141,13 +141,14 @@ This option can be used several times to provide 
 several detection regexes.
  +
  -
   exon=Andreas Ericsson a...@op5.se
 - spawn=Simon Pawn sp...@frog-pond.org
 + spawn=Simon Pawn sp...@frog-pond.org America/Chicago
  
  -
  +
  'git cvsimport' will make it appear as those authors had
  their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly
 -all along.
 +all along.  If a timezone is specified, GIT_AUTHOR_DATE will
 +have the corresponding offset applied.

The description above the context reads:

-A author-conv-file::
CVS by default uses the Unix username when writing its
commit logs. Using this option and an author-conv-file
in this format

which probably need to be updated to describe what this format is
a bit better.

... an author-conv-file that maps the name recorded in CVS
to author name, author e-mail and an optional timezone for
the author

or something.

  For convenience, this data is saved to `$GIT_DIR/cvs-authors`
  each time the '-A' option is provided and read from that same

 @@ -844,7 +854,9 @@ sub commit {
   }
   }
  
 - my $commit_date = strftime(+ %Y-%m-%d %H:%M:%S,gmtime($date));
 + $ENV{'TZ'}=$author_tz;
 + my $commit_date = strftime(%s %z, localtime($date));

With this, because it updates $commit_date, the specified timezone
applies to both AUTHOR and COMMITTER dates (which is correct---I am
just pointing it out).

 diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh
 new file mode 100644

Huh?  What happened to the executable bit we saw earlier?

 index 000..fb7459c
 --- /dev/null
 +++ b/t/t9604-cvsimport-timestamps.sh
 @@ -0,0 +1,92 @@
 +#!/bin/sh
 +
 +test_description='git cvsimport timestamps'
 +. ./lib-cvs.sh
 +
 +setup_cvs_test_repository t9604
 +
 +test_expect_success 'check timestamps are UTC (TZ=America/Chicago)' '
 +
 +TZ=America/Chicago git cvsimport -p-x -C module-1 module 
 +git cvsimport -p-x -C module-1 module 
 +(cd module-1 
 +git log --pretty=format:%s %ai -- ../actual-1 
 +echo  ../actual-1
 +) 
 +echo Rev 16 2011-11-06 07:00:01 +
 +Rev 15 2011-11-06 06:59:59 +
 +Rev 14 2011-03-13 08:00:01 +
 +Rev 13 2011-03-13 07:59:59 +
 +Rev 12 2010-12-01 00:00:00 +
 +Rev 11 2010-11-01 00:00:00 +
 +Rev 10 2010-10-01 00:00:00 +
 +Rev  9 2010-09-01 00:00:00 +
 +Rev  8 2010-08-01 00:00:00 +
 +Rev  7 2010-07-01 00:00:00 +
 +Rev  6 2010-06-01 00:00:00 +
 +Rev  5 2010-05-01 00:00:00 +
 +Rev  4 2010-04-01 00:00:00 +
 +Rev  3 2010-03-01 00:00:00 +
 +Rev  2 2010-02-01 00:00:00 +
 +Rev  1 2010-01-01 00:00:00 + expect-1 
 +test_cmp actual-1 expect-1
 +'

A handful of issues.

- (style) Please use one tab for one level of indent;
- (style) Learn to use -\HERE document to make list easier to
  read; 
- You shouldn't have to choose --pretty=format which places LF
  in between records and add another LF yourself.  Instead, you
  can use --pretty=tformat that uses LF as record terminator, or
  its short-hand form --format=...;
- I am not sure what you are gaining out of the trailing --.

See below for a suggested way to lay this out better.

 +test_expect_success 'check timestamps are UTC (TZ=Australia/Sydney)' '
 +
 +TZ=America/Chicago git cvsimport -p-x -C module-2 module 

This look identical to the first one, but even with a trivial change
to use Australia/Sydney instead of Chicago, I am not sure what the
test buys us.

 

Re: [Patch 0/5] Create single PDF for all HTML files

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 01:55:51PM +0200, Michael J Gruber wrote:

  I wonder if a more sane route is to drop HTML entirely, convert the
  asciidoc to docbook (which we already do for manpages), and then create
  a docbook document that is a collection of all elements, which can then
 
 Hmm, I think the html output often looks better than the man output
 (tables and such), and it is a formatted, reflowable, interlinked format
 fit for many puposes.

It does look better, but that is because the docbook-roff step is where
things get ugly. In theory, docbook is at least as expressive as HTML,
and has lots of nice semantic markup that gives us flexibility in what
the final product looks like.

There are docbook-epub converters (I think xmlto will do this out of
the box), as well as a host of other formats. But convincing docbook to
create a collection of refentry (their term for manpage) articles is
harder than you'd think. I tried a few things when this thread started
and couldn't get anything simple to work (xml has managed to make the
simple act of include this document in this other document insanely
complex). But I only spent a few minutes on it.

  be converted to pdf, epub, or whatever. I would not be surprised if
  somebody has solved this problem before (but it is not really my itch,
  so I did not look very far).
 
 I'd rather ditch docbook and have one toolchain (asciidoc, unless we
 want to switch to something else) only... We've been hunting asciidoc as
 well as docbook compatibility (between versions) and interoperability
 (between them) issues again and again.

Yeah, I really hate our doc toolchain. It just seems like everything
else is even worse. We can ditch docbook, but then how do we make
manpages?

-Peff
--
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: When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Ævar Arnfjörð Bjarmason
On Mon, Oct 15, 2012 at 6:42 PM, Elia Pinto gitter.spi...@gmail.com wrote:
 Very clear analysis. Well written. Perhaps is it the time to update
 http://git-scm.com/book/ch6-1.html (A SHORT NOTE ABOUT SHA-1) ?

 Hope useful

 http://www.schneier.com/crypto-gram-1210.html

This would be concerning if the Git security model would break down if
someone found a SHA1 collision, but it really wouldn't.

It's one thing to find *a* collision, it's quite another to:

 1. Find a collision for the sha1 of harmless.c which I know you use,
and replace it with evil.c.

 2. Somehow make evil.c compile so that it actually does something
useful and nefarious, and doesn't just make the C compiler puke.

If finding one arbitrary collision costs $43K in 2021 dollars
getting past this point is going to take quite a large multiple of
$43K.

 3. Somehow inject the new evil object into your repository, or
convince you to re-clone it / clone it from somewhere you usually
wouldn't.

At some point in the early days of Git Linus went on a rant to this
effect either on this list or on the LKML.

Maybe it would be useful to include some of that instead?

It would be very interesting to see an analysis that deals with some
actual Git-related security scenarios, instead of something that just
assumes that if someone finds *any* SHA1 collision the sky is going to
fall.
--
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: build deps

2012-10-15 Thread Thiago Farina
On Mon, Oct 15, 2012 at 12:44 PM, Michael J Gruber
g...@drmicha.warpmail.net wrote:
 clang reported this:
 combine-diff.c:1006:19: warning: adding 'int' to a string does not
 append to the string [-Wstring-plus-int]
 prefix = COLONS + offset;
  ~~~^~~~
 combine-diff.c:1006:19: note: use array indexing to silence this
 warning
 prefix = COLONS + offset;
 ^
[   ]
 1 warning generated.

 Does

 COLONS[offset]

 silence that?

Yes.
--
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: When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Elia Pinto
2012/10/15 Ævar Arnfjörð Bjarmason ava...@gmail.com:
 On Mon, Oct 15, 2012 at 6:42 PM, Elia Pinto gitter.spi...@gmail.com wrote:
 Very clear analysis. Well written. Perhaps is it the time to update
 http://git-scm.com/book/ch6-1.html (A SHORT NOTE ABOUT SHA-1) ?

 Hope useful

 http://www.schneier.com/crypto-gram-1210.html

 This would be concerning if the Git security model would break down if
 someone found a SHA1 collision, but it really wouldn't.
I know perfectly.

 It's one thing to find *a* collision, it's quite another to:

  1. Find a collision for the sha1 of harmless.c which I know you use,
 and replace it with evil.c.

  2. Somehow make evil.c compile so that it actually does something
 useful and nefarious, and doesn't just make the C compiler puke.

 If finding one arbitrary collision costs $43K in 2021 dollars
 getting past this point is going to take quite a large multiple of
 $43K.

  3. Somehow inject the new evil object into your repository, or
 convince you to re-clone it / clone it from somewhere you usually
 wouldn't.

 At some point in the early days of Git Linus went on a rant to this
 effect either on this list or on the LKML.

 Maybe it would be useful to include some of that instead?

What you wrote is a risk analysis. I appreciate, i am also a  security
professionals..
 It would be very interesting to see an analysis that deals with some
 actual Git-related security scenarios, instead of something that just
 assumes that if someone finds *any* SHA1 collision the sky is going to
 fall.
What you wrote is a risk analysis. I appreciate, as security professionals, too.

I agree, of course. However, it is totally different from saying that
because exists the birthday paradox git will be immune to collision,
sure, if caused by a cryptographic attack. But clearly the risk for a
project that uses a cryptographic hash function as a hash function, as
git, is zero in the absence of a real use case. In computer security
the use of encryption is hardly the point of attack, today, as you
have clearly said. But it is the most invisible to highlight.

It seemed interesting to quote here the Bruce article because the
topic has already been discussed in the past here. That's it. No more,
no less.

Thanks

Best Regards
Best Regard
--
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/2] show color hints based on state of the git tree

2012-10-15 Thread Junio C Hamano
Simon Oosthoek soosth...@nieuwland.nl writes:

 The point of the thread and the patch was to enable the possibility of
 colors in the prompt without messing it up.

 The actual colors used are more or less how I'm used to it, but as you
 said they may not be suitable to everyone.

 @Junio, is this patch something you want to include as it is now (with
 the extra S that Michael pointed out) or do you want to wait for a
 discussion about which colors to use for which state?

The latter.

 I guess it could be quite a messy discussion, as you already hint at
 bikeshed colors, it's quite personal and subjective.

The choice of colours may be subjective, but you can just omit that
part, if there is already an existing choice made by others in
earlier changes like in status output.  As long as the subjective
choices in two systems that show similar information are consistent,
exact choice of colours does not matter that 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: When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 07:47:09PM +0200, Ævar Arnfjörð Bjarmason wrote:

 On Mon, Oct 15, 2012 at 6:42 PM, Elia Pinto gitter.spi...@gmail.com wrote:
  Very clear analysis. Well written. Perhaps is it the time to update
  http://git-scm.com/book/ch6-1.html (A SHORT NOTE ABOUT SHA-1) ?
 
  Hope useful
 
  http://www.schneier.com/crypto-gram-1210.html
 
 This would be concerning if the Git security model would break down if
 someone found a SHA1 collision, but it really wouldn't.
 
 It's one thing to find *a* collision, it's quite another to:
 
  1. Find a collision for the sha1 of harmless.c which I know you use,
 and replace it with evil.c.
 
  2. Somehow make evil.c compile so that it actually does something
 useful and nefarious, and doesn't just make the C compiler puke.
 
 If finding one arbitrary collision costs $43K in 2021 dollars
 getting past this point is going to take quite a large multiple of
 $43K.

There are easier attacks than that if you can hide arbitrary bytes
inside a file. It's hard with C source code. The common one in hash
collision detection circles is to put invisible cruft into binary
document formats like PDF or Postscript. Git blobs themselves do not
have such an invisible place to put it, but you might be storing a
format that does.

But worse, git _commits_ have such an invisible portion. We calculate
the sha1 over the full commit, but we tend to show only the portion up
to the first NUL byte. I used that horrible trick in my choose your own
sha1 prefix patch. However, we could mitigate that by checking for
embedded NULs in git-fsck.

  3. Somehow inject the new evil object into your repository, or
 convince you to re-clone it / clone it from somewhere you usually
 wouldn't.

Yeah, this part is the kicker. With the commit NUL trick, you would make
a useful commit and then ask somebody to pull it, and then later replace
it with a commit pointing to an arbitrary tree. But if we assume we can
detect that easily (which I think we can), we are left with replacing
binary blobs that have hidden bits. And most projects do not take many
such blobs, and the result is that you could only replace the contents
of that particular blob, not an arbitrary part of the tree.

 It would be very interesting to see an analysis that deals with some
 actual Git-related security scenarios, instead of something that just
 assumes that if someone finds *any* SHA1 collision the sky is going to
 fall.

I agree that most of the analysis is overblown. Having read the analysis
Schneier pointed to, it actually is not that bad. We have 5-10 years to
get to a point where it's really expensive and extremely complex to
mount a single attack.

That doesn't seem like an emergency to me. It sounds like something we
should be thinking about (and we are). The simplest thing would be to
wait for a moment when it makes sense to break compatibility (e.g., we
decide that git 2.0 is here, and everybody will have to rewrite to
take advantage of new features, so we can jump to sha-2). We can also
start building sha-2 history that references sha-1 history. That would
mean everybody needs to upgrade their git, but that is not a problem
that requires 5-10 years of foresight and planning.

-Peff
--
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: push race

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 10:29:08AM -0400, Marc Branchaud wrote:

 Here's a previous discussion of a race in concurrent updates to the same ref,
 even when the updates are all identical:
 
 http://news.gmane.org/find-root.php?group=gmane.comp.version-control.gitarticle=164636
 
 In that thread, Peff outlines the lock procedure for refs:
 
 1. get the lock
 2. check and remember the sha1
 3. release the lock
 4. do some long-running work (like the actual push)
 5. get the lock
 6. check that the sha1 is the same as the remembered one
 7. update the sha1
 8. release the lock

A minor nit, but I was wrong on steps 1-3. We don't have to take a lock
on reading, because our write mechanism uses atomic replacement. So it
is really:

  1. read and remember the original sha1
  2. do some long-running work (like the actual push)
  3. get the write lock
  4. read the sha1 and check that it's the same as our original
  5. write the new sha1 to the lockfile
  6. simultaneously release the lock and update the ref by atomically
 renaming the lockfile to the actual ref

Any simultaneous push may see the old sha1 before step 6, and when it
gets to its own step 4, will fail (and two processes cannot be in steps
3-6 simultaneously).

 Angelo, in your case I think one of your concurrent updates would fail in
 step 6.  As you say, this is after the changes have been uploaded.  However,
 there's none of the file-overwriting that you fear, because the changes are
 stored in git's object database under their SHA hashes.  So there'll only be
 an object-level collision if two parties upload the exact same object, in
 which case it doesn't matter.

Right. The only thing that needs locking is the refs, because the object
database is add-only for normal operations, and by definition collisions
mean you have the same content (or are astronomically unlucky, but your
consolation prize is that you can write a paper on how you found a sha1
collision).

-Peff
--
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: push race

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 05:50:47PM +0200, Angelo Borsotti wrote:

 correct, there will be no file overwriting because no files are
 written on the work tree.
 I tried to follow the actions of the program, but did not quite catch
 the 6. you mention.

It is the oldval parameter to refs.c:update_ref. Or if you are using
the git update-ref plumbing, it is the oldvalue parameter.

-Peff
--
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: When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Elia Pinto
Hem , sha-3 i suppose, keccak, no ? But really is not so urgent as you
have already told .

Best

2012/10/15, Jeff King p...@peff.net:
 On Mon, Oct 15, 2012 at 07:47:09PM +0200, Ævar Arnfjörð Bjarmason wrote:

 On Mon, Oct 15, 2012 at 6:42 PM, Elia Pinto gitter.spi...@gmail.com
 wrote:
  Very clear analysis. Well written. Perhaps is it the time to update
  http://git-scm.com/book/ch6-1.html (A SHORT NOTE ABOUT SHA-1) ?
 
  Hope useful
 
  http://www.schneier.com/crypto-gram-1210.html

 This would be concerning if the Git security model would break down if
 someone found a SHA1 collision, but it really wouldn't.

 It's one thing to find *a* collision, it's quite another to:

  1. Find a collision for the sha1 of harmless.c which I know you use,
 and replace it with evil.c.

  2. Somehow make evil.c compile so that it actually does something
 useful and nefarious, and doesn't just make the C compiler puke.

 If finding one arbitrary collision costs $43K in 2021 dollars
 getting past this point is going to take quite a large multiple of
 $43K.

 There are easier attacks than that if you can hide arbitrary bytes
 inside a file. It's hard with C source code. The common one in hash
 collision detection circles is to put invisible cruft into binary
 document formats like PDF or Postscript. Git blobs themselves do not
 have such an invisible place to put it, but you might be storing a
 format that does.

 But worse, git _commits_ have such an invisible portion. We calculate
 the sha1 over the full commit, but we tend to show only the portion up
 to the first NUL byte. I used that horrible trick in my choose your own
 sha1 prefix patch. However, we could mitigate that by checking for
 embedded NULs in git-fsck.

  3. Somehow inject the new evil object into your repository, or
 convince you to re-clone it / clone it from somewhere you usually
 wouldn't.

 Yeah, this part is the kicker. With the commit NUL trick, you would make
 a useful commit and then ask somebody to pull it, and then later replace
 it with a commit pointing to an arbitrary tree. But if we assume we can
 detect that easily (which I think we can), we are left with replacing
 binary blobs that have hidden bits. And most projects do not take many
 such blobs, and the result is that you could only replace the contents
 of that particular blob, not an arbitrary part of the tree.

 It would be very interesting to see an analysis that deals with some
 actual Git-related security scenarios, instead of something that just
 assumes that if someone finds *any* SHA1 collision the sky is going to
 fall.

 I agree that most of the analysis is overblown. Having read the analysis
 Schneier pointed to, it actually is not that bad. We have 5-10 years to
 get to a point where it's really expensive and extremely complex to
 mount a single attack.

 That doesn't seem like an emergency to me. It sounds like something we
 should be thinking about (and we are). The simplest thing would be to
 wait for a moment when it makes sense to break compatibility (e.g., we
 decide that git 2.0 is here, and everybody will have to rewrite to
 take advantage of new features, so we can jump to sha-2). We can also
 start building sha-2 history that references sha-1 history. That would
 mean everybody needs to upgrade their git, but that is not a problem
 that requires 5-10 years of foresight and planning.

 -Peff


-- 
Inviato dal mio dispositivo mobile
--
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: When Will We See Collisions for SHA-1? (An interesting analysis by Bruce Schneier)

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 09:09:44PM +0200, Elia Pinto wrote:

 Hem , sha-3 i suppose, keccak, no ? But really is not so urgent as you
 have already told .

It depends. Read what Schneier wrote right before they announced the
SHA-3 winner:

  https://www.schneier.com/crypto-gram-1210.html#2

There's really no security reason not to use SHA-2, and in fact it's
probably better, as it has been more widely studied at this point. But
that part is easy; it's the compatibility switch-over that's hard (we
could also even parameterize the hash, but that has some annoyances,
too).

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


Cloning tags from master

2012-10-15 Thread dquince
I am trying to implement using tags in our build process, but am running into
an issue with pulling tags from master. My scenario is as follows
We decide on a release and I tag master with testtag which has commit
testtag-1-gf3b117e
When I make another commit to master and check the tag, I see it as
testtag-2-gfb56442
When I try and pull the tag using testtag, it just wants to pull the latest
commit to master. 

I verified this works in branches other than master, so can this be done
from master or does the tag just follow the head?




--
View this message in context: 
http://git.661346.n2.nabble.com/Cloning-tags-from-master-tp7569301.html
Sent from the git mailing list archive at Nabble.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 3/5] Create html documents for all files in Documentation/RelNotes

2012-10-15 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 Junio C Hamano venit, vidit, dixit 07.10.2012 22:53:
 Jeff King p...@peff.net writes:
 
 [1] I would not be surprised if they do not actually format all that
 well. Though they are written in an asciidoc-ish style, they have
 not traditionally been formatted, and I suspect there are many small
 errors (like improper quoting of metacharacters) in them.
 
 They aren't even errors. As far as I (who writes the release
 notes) am concerned, they are straight text without any asciidoc
 or markdown mark-up.

 I'm wondering: If it's neither markdown nor markup then what is it:
 marklevel, markeven or markstraight?

They are called plain text.

 On a different note: Is pdf really the format of choice for mobile
 platforms? I'd expect something that is formatted (markup) but can
 reflow text intrinsically, not only by making your pdf reader jump
 through hoops. HTML?

Yeah, I've been wondering if epub or something might be a better
target myself.
--
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: build deps

2012-10-15 Thread Junio C Hamano
Michael J Gruber g...@drmicha.warpmail.net writes:

 grep.c:451:16: warning: comparison of unsigned enum expression  0 is
 always false [-Wtautological-compare]
 if (p-field  0 || GREP_HEADER_FIELD_MAX = p-field)
  ^ ~
 1 warning generated.

 Right, that enum type starts at 0. Junio, you last touched this area.
 Can we just dump the first comparison or did you have something else in
 mind?

I think it was a leftover from the very first implementation that
defensively said this has to be one of these known ones, and tried
to bound it from both sides of the range, regaredless of the actual
type of the field (these GREP_HEADER_WHAT things may have been
simple integers with #define'd values).  Dropping the negative
comparison is perfectly fine.

--
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 UI experiment] diffstat: annotate/highlight new or removed files

2012-10-15 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

 diffstat does not show whether a file is added or deleted. I know
 --summary does. But the problem with --summary is it makes me look for
 information of a file in two places: diffstat and summary. And with a
 commit that adds/removes a lot, showing both --stat --summary can be
 long.

 This patch adds (new), (gone) or (new mode) to diffstat, with
 highlight, to easily catch file additions/removals. The extra text is
 chosen to be short enough so that it won't take up too much space for
 path names:

  .gitignore  |   1 +
  Makefile|   3 +
  t/t3070-wildmatch.sh (new)  | 188 
  t/t3070/wildtest.txt (gone) | 165 -
  test-wildmatch.c (new)  |  14 ++
  wildmatch.c |   5 +-
  6 files changed, 210 insertions(+), 166 deletions(-)

 I don't put creation modes in there too because most of the time it
 does not matter much to me and I could look down to --summary for mode
 verification. But we could put (new+x) for 0755 and just (new) for
 0644. (new mode) then could become (+x), (-x) or something like
 that.

 Coloring is to me an improvement over --summary. Probably the main
 point. Without it, perhaps it's not worth putting extra text to
 diffstat.

It is kind of surprising that you did not choose to paint new in
green and gone in red, and rather paint everything in yellow.

I personally think the above in monochrome is fairly easy to read;
with coloring, it might become too distracting, though.

Just a nit, new mode is too similar to new.  Everything is new
in the sense that they have new contents; it may be better phrased
without saying new but giving a stress on changed.

Thanks for a fun patch.  I am not strongly against it.
--
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: error: git-fast-import died of signal 11

2012-10-15 Thread Andrew Wong

On 10/15/2012 11:53 AM, Uri Moszkowicz wrote:

I'm trying to convert a CVS repository to Git using cvs2git. I was able to
generate the dump file without problem but am unable to get Git to
fast-import it. The dump file is 328GB and I ran git fast-import on a
machine with 512GB of RAM.
Just taking a wild guess here. Are you using 64bit version of git? If 
not, maybe it'd help to try 64bit?



fatal: Out of memory? mmap failed: Cannot allocate memory
fast-import: dumping crash report to fast_import_crash_18192
error: git-fast-import died of signal 11
fast-import also produced a crash report. It might help to diagnose 
the issue if you can post that report?
The report shouldn't be too big. And you might want to strip any 
sensitive information before posting.

--
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: nd/attr-match-more-optim, nd/wildmatch and as/check-ignore

2012-10-15 Thread Junio C Hamano
Nguyễn Thái Ngọc Duy  pclo...@gmail.com writes:

 These three series all touch the same code in dir.c and cause
 a bunch of conflicts. So I rebase nd/wildmatch and as/check-ignore
 on top of nd/attr-match-more-optim and resolve all conflicts.

Thanks for working on this.  Makes my life much easier.

If not my life, it certainly will make it easier to shift blame to
others when things go wrong (it is called easier to bisect ;-)

--
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] completion: add format-patch options to send-email

2012-10-15 Thread SZEDER Gábor
Hi,

On Sun, Oct 14, 2012 at 06:14:03PM +0200, Felipe Contreras wrote:
 Signed-off-by: Felipe Contreras felipe.contre...@gmail.com
 ---
  contrib/completion/git-completion.bash | 35 
 +-
  t/t9902-completion.sh  | 21 
  2 files changed, 39 insertions(+), 17 deletions(-)
 
 diff --git a/contrib/completion/git-completion.bash 
 b/contrib/completion/git-completion.bash
 index d743e56..2a83504 100644
 --- a/contrib/completion/git-completion.bash
 +++ b/contrib/completion/git-completion.bash

This patch doesn't apply on current master.

 @@ -1559,11 +1559,12 @@ _git_send_email ()
   --signed-off-by-cc --smtp-pass --smtp-server
   --smtp-server-port --smtp-encryption= --smtp-user
   --subject --suppress-cc= --suppress-from --thread --to
 - --validate --no-validate
 + --validate --no-validate
 + $__git_format_patch_options
   return
   ;;
   esac
 - COMPREPLY=()
 + __git_complete_revlist_file

While send-email accepts a rev-list, it doesn't accept
'HEAD:Documentation', does it?  So __git_complete_revlist() would be
better here, because that makes the intent clear.

  }
  
  _git_stage ()
 diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
 index 92d7eb4..c4b6c13 100755
 --- a/t/t9902-completion.sh
 +++ b/t/t9902-completion.sh
 @@ -146,6 +146,22 @@ test_expect_success '__gitcomp - suffix' '
   test_cmp expected out
  '
  
 +setup_repository ()
 +{
 + mkdir $1  (
 + cd $1 
 + git init 
 + test_tick 
 + git commit --allow-empty -m Initial
 + )
 +}
 +
 +test_expect_success 'prepare' '
 + setup_repository one 
 + git clone one test 

Why are these new repositories needed?

 + cd test

This 'cd' makes all subsequent tests to be executed in a different
repository than previously, which breaks 'checkout completes ref
names'.

 +'
 +
  test_expect_success 'basic' '
   run_completion git \\ 
   # built-in
 @@ -228,4 +244,9 @@ test_expect_success 'general options plus command' '
   test_completion git --no-replace-objects check checkout 
  '
  
 +test_expect_success 'send-email' '
 + test_completion git send-email --cov --cover-letter  
 + test_completion git send-email ma master 
 +'
 +
  test_done
 -- 
 1.7.12.1
 
--
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: error: git-fast-import died of signal 11

2012-10-15 Thread Andrew Wong

On 10/15/2012 05:28 PM, Uri Moszkowicz wrote:

Thanks for the reply. Yes I am using a 64-bit build of Git. The report
is too large to attach to email so I've uploaded it here (~6MB tar.xz
file):

http://www.tempfiles.net/download/201210/267447/fast_import_crash18192.html

Hm, there are some blanks in the recent commands section:

  D someFile
  D someFile
  D someFile
  D someFile
  (blank here)
  reset refs/tags/someTag
  from :145763
  reset refs/heads/TAG.FIXUP
* (blank here)

There should have been some commands there. Maybe that has something to 
do with the crash? Would you be able to locate where this is in the cvs 
dump? You might be able to use those tag names around those lines to 
help locate them.

What are those blanks supposed to be? Probably commits?
--
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] completion: add format-patch options to send-email

2012-10-15 Thread Junio C Hamano
SZEDER Gábor sze...@ira.uka.de writes:

 +cd test

 This 'cd' makes all subsequent tests to be executed in a different
 repository than previously, which breaks 'checkout completes ref
 names'.

Yeah, thanks for spotting and yelling at it ;-).

We really need to be careful about tests that cd around.  Even the
ones that only go down and expect the rest of the test to run in
that subdirectory may later have to be modified by somebody to run
back at the original level, and writing cd .., which leads to all
sorts of problems, becomes too tempting.

 +'
 +
  test_expect_success 'basic' '
  run_completion git \\ 
  # built-in
 @@ -228,4 +244,9 @@ test_expect_success 'general options plus command' '
  test_completion git --no-replace-objects check checkout 
  '
  
 +test_expect_success 'send-email' '
 +test_completion git send-email --cov --cover-letter  
 +test_completion git send-email ma master 
 +'
 +
  test_done
 -- 
 1.7.12.1
 
--
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] completion: add format-patch options to send-email

2012-10-15 Thread SZEDER Gábor
On Tue, Oct 16, 2012 at 01:37:35AM +0200, Felipe Contreras wrote:
 On Tue, Oct 16, 2012 at 12:48 AM, SZEDER Gábor sze...@ira.uka.de wrote:
 
  @@ -1559,11 +1559,12 @@ _git_send_email ()
--signed-off-by-cc --smtp-pass --smtp-server
--smtp-server-port --smtp-encryption= --smtp-user
--subject --suppress-cc= --suppress-from --thread 
  --to
  - --validate --no-validate
  + --validate --no-validate
  + $__git_format_patch_options
return
;;
esac
  - COMPREPLY=()
  + __git_complete_revlist_file
 
  While send-email accepts a rev-list, it doesn't accept
  'HEAD:Documentation', does it?  So __git_complete_revlist() would be
  better here, because that makes the intent clear.
 
 Then _git_send_email should be fixed first. I'm simply doing the same
 as _git_send_email.

I can't decipher this recursion here.

  diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
  index 92d7eb4..c4b6c13 100755
  --- a/t/t9902-completion.sh
  +++ b/t/t9902-completion.sh
  @@ -146,6 +146,22 @@ test_expect_success '__gitcomp - suffix' '
test_cmp expected out
   '
 
  +setup_repository ()
  +{
  + mkdir $1  (
  + cd $1 
  + git init 
  + test_tick 
  + git commit --allow-empty -m Initial
  + )
  +}
  +
  +test_expect_success 'prepare' '
  + setup_repository one 
  + git clone one test 
 
  Why are these new repositories needed?
 
 Because otherwise 'git send-email ma' wouldn't succeed.

Even then you don't need two additional repos, because just one
commit in the test repo would suffice.  And the test 'setup for ref
completion' already takes care of that.

  + cd test
 
  This 'cd' makes all subsequent tests to be executed in a different
  repository than previously, which breaks 'checkout completes ref
  names'.
 
 I don't know which test you are talking about, it's not on my repo,
 and all the completion test pass with this patch.

It's in v1.8.0-rc0~1^2 (t9902: add completion tests for odd filenames,
2012-09-26), which is the commit your patch conflicts with.


Best,
Gábor

--
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] completion: add format-patch options to send-email

2012-10-15 Thread Felipe Contreras
On Tue, Oct 16, 2012 at 1:37 AM, Felipe Contreras
felipe.contre...@gmail.com wrote:
 On Tue, Oct 16, 2012 at 12:48 AM, SZEDER Gábor sze...@ira.uka.de wrote:

 + cd test

 This 'cd' makes all subsequent tests to be executed in a different
 repository than previously, which breaks 'checkout completes ref
 names'.

 I don't know which test you are talking about, it's not on my repo,
 and all the completion test pass with this patch.

Maybe this then:

test_expect_success 'prepare' '
git init 
test_tick 
git commit --allow-empty -m Initial
'

I originally created those for some push and fetch tests, but that
required too many reorganizations, and I got fed up with the review,
so I dropped the series[1].

Cheers.

[1] http://article.gmane.org/gmane.comp.version-control.git/197226

-- 
Felipe Contreras
--
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] completion: add format-patch options to send-email

2012-10-15 Thread Felipe Contreras
Signed-off-by: Felipe Contreras felipe.contre...@gmail.com
---

v2: Fix comments by SZEDER Gabor

 contrib/completion/git-completion.bash | 35 +-
 t/t9902-completion.sh  |  5 +
 2 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/contrib/completion/git-completion.bash 
b/contrib/completion/git-completion.bash
index be800e0..bc0657a 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1116,6 +1116,14 @@ _git_fetch ()
__git_complete_remote_or_refspec
 }
 
+__git_format_patch_options=
+   --stdout --attach --no-attach --thread --thread= --output-directory
+   --numbered --start-number --numbered-files --keep-subject --signoff
+   --signature --no-signature --in-reply-to= --cc= --full-index --binary
+   --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix=
+   --inline --suffix= --ignore-if-in-upstream --subject-prefix=
+
+
 _git_format_patch ()
 {
case $cur in
@@ -1126,21 +1134,7 @@ _git_format_patch ()
return
;;
--*)
-   __gitcomp 
-   --stdout --attach --no-attach --thread --thread=
-   --output-directory
-   --numbered --start-number
-   --numbered-files
-   --keep-subject
-   --signoff --signature --no-signature
-   --in-reply-to= --cc=
-   --full-index --binary
-   --not --all
-   --cover-letter
-   --no-prefix --src-prefix= --dst-prefix=
-   --inline --suffix= --ignore-if-in-upstream
-   --subject-prefix=
-   
+   __gitcomp $__git_format_patch_options
return
;;
esac
@@ -1554,6 +1548,12 @@ _git_send_email ()
__gitcomp ssl tls  ${cur##--smtp-encryption=}
return
;;
+   --thread=*)
+   __gitcomp 
+   deep shallow
+ ${cur##--thread=}
+   return
+   ;;
--*)
__gitcomp --annotate --bcc --cc --cc-cmd --chain-reply-to
--compose --confirm= --dry-run --envelope-sender
@@ -1563,11 +1563,12 @@ _git_send_email ()
--signed-off-by-cc --smtp-pass --smtp-server
--smtp-server-port --smtp-encryption= --smtp-user
--subject --suppress-cc= --suppress-from --thread --to
-   --validate --no-validate
+   --validate --no-validate
+   $__git_format_patch_options
return
;;
esac
-   COMPREPLY=()
+   __git_complete_revlist
 }
 
 _git_stage ()
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index cbd0fb6..8fa025f 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -288,4 +288,9 @@ test_expect_failure 'complete tree filename with 
metacharacters' '
EOF
 '
 
+test_expect_success 'send-email' '
+   test_completion git send-email --cov --cover-letter  
+   test_completion git send-email ma master 
+'
+
 test_done
-- 
1.7.12.1

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


Please pull git-l10n updates for git v1.8.0-rc2-4-g42e55

2012-10-15 Thread Jiang Xin
Hi, Junio

The following changes since commit 42e55a5f5709642cb7a56ecad8b706341f0eb38a:

  Merge branch 'maint' (2012-10-13 23:05:54 -0700)

are available in the git repository at:


  git://github.com/git-l10n/git-po master

for you to fetch changes up to 9306b5b9a33185e7867202718162d8a38d5627ab:

  l10n: Update git.pot (3 new, 6 removed messages) (2012-10-16 08:39:10 +0800)


Jiang Xin (2):
  Merge branch 'master' of git://github.com/vnwildman/git
  l10n: Update git.pot (3 new, 6 removed messages)

Tran Ngoc Quan (1):
  l10n: vi.po: update translation upto cc76011

 po/git.pot |  852 +--
 po/vi.po   | 4934 ++--
 2 files changed, 4594 insertions(+), 1192 deletions(-)

-- 
Jiang Xin
--
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: build deps

2012-10-15 Thread David Aguilar
On Mon, Oct 15, 2012 at 1:53 PM, Junio C Hamano gits...@pobox.com wrote:
 Michael J Gruber g...@drmicha.warpmail.net writes:

 grep.c:451:16: warning: comparison of unsigned enum expression  0 is
 always false [-Wtautological-compare]
 if (p-field  0 || GREP_HEADER_FIELD_MAX = p-field)
  ^ ~
 1 warning generated.

 Right, that enum type starts at 0. Junio, you last touched this area.
 Can we just dump the first comparison or did you have something else in
 mind?

 I think it was a leftover from the very first implementation that
 defensively said this has to be one of these known ones, and tried
 to bound it from both sides of the range, regaredless of the actual
 type of the field (these GREP_HEADER_WHAT things may have been
 simple integers with #define'd values).  Dropping the negative
 comparison is perfectly fine.

This snippet of code came up before:

http://thread.gmane.org/gmane.comp.version-control.git/184908/focus=185014

There seemed to be good reasons to keep the check at the time.

Was this same snippet not also touched when Nguyen Thai Ngoc Duy
worked on the even if I'm drunk patch?:

http://thread.gmane.org/gmane.comp.version-control.git/206413/focus=206539

With the drunk patch then we wouldn't need the check at all,
which is really nice.

I hope that helps jog folks' memories.
I'm not sure if the above discussions are relevant anymore,
but I figured it'd be good to provide some more context.

cheers,
-- 
David
--
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: push race

2012-10-15 Thread Shawn Pearce
On Mon, Oct 15, 2012 at 11:56 AM, Jeff King p...@peff.net wrote:
 Right. The only thing that needs locking is the refs, because the object
 database is add-only for normal operations, and by definition collisions
 mean you have the same content (or are astronomically unlucky, but your
 consolation prize is that you can write a paper on how you found a sha1
 collision).

Its worth nothing that a SHA-1 collision can be identified at the
server because the server performs a byte-for-byte compare of both
copies of the object to make sure they match exactly in every way. Its
not fast, but its safe. :-)
--
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-cvsimport: allow author-specific timezones

2012-10-15 Thread Chris Rorvick
On Mon, Oct 15, 2012 at 12:40 PM, Junio C Hamano gits...@pobox.com wrote:
 diff --git a/t/t9604-cvsimport-timestamps.sh 
 b/t/t9604-cvsimport-timestamps.sh
 new file mode 100644

 Huh?  What happened to the executable bit we saw earlier?

Uh, yeah.  Sorry about that.

 +test_expect_success 'check timestamps are UTC (TZ=Australia/Sydney)' '
 +
 +TZ=America/Chicago git cvsimport -p-x -C module-2 module 

 This look identical to the first one, but even with a trivial change
 to use Australia/Sydney instead of Chicago, I am not sure what the
 test buys us.

This is left over from when I was using the script to test the use
local timezone option.  It was useless there, too, but did provide
some symmetry.  :-)  Removed.

It occurred to me that the success of the unit test depends on the
host platform's zoneinfo database.  I think this problem is inherent
with this functionality.  Should the unit test attempt to detect
support for the used timezones and short circuit if this fails?  Not
sure exactly how I'd do this, but wondering if it's worth thinking
about.

I've made all the other recommended changes, I'll resubmit shortly.

Thanks,

Chris
--
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 v3] git-cvsimport: allow author-specific timezones

2012-10-15 Thread Chris Rorvick
CVS patchsets are imported with timestamps having an offset of +
(UTC).  The cvs-authors file is already used to translate the CVS
username to full name and email in the corresponding commit.  Extend
this file to support an optional timezone for calculating a user-
specific timestamp offset.

Signed-off-by: Chris Rorvick ch...@rorvick.com
---

Cleaned up unit tests and added more detail to documentation.

Unit test is inherently platform dependent due to dependency on
zoneinfo database.  Is there a way to improve this situation?

 Documentation/git-cvsimport.txt|   8 +-
 git-cvsimport.perl |  22 ++-
 t/t9604-cvsimport-timestamps.sh|  71 ++
 t/t9604/cvsroot/.gitattributes |   1 +
 t/t9604/cvsroot/CVSROOT/.gitignore |   2 +
 t/t9604/cvsroot/module/a,v | 265 +
 6 files changed, 362 insertions(+), 7 deletions(-)
 create mode 100755 t/t9604-cvsimport-timestamps.sh
 create mode 100644 t/t9604/cvsroot/.gitattributes
 create mode 100644 t/t9604/cvsroot/CVSROOT/.gitignore
 create mode 100644 t/t9604/cvsroot/module/a,v

diff --git a/Documentation/git-cvsimport.txt b/Documentation/git-cvsimport.txt
index 6695ab3..9ea8bb5 100644
--- a/Documentation/git-cvsimport.txt
+++ b/Documentation/git-cvsimport.txt
@@ -137,17 +137,19 @@ This option can be used several times to provide several 
detection regexes.
 -A author-conv-file::
CVS by default uses the Unix username when writing its
commit logs. Using this option and an author-conv-file
-   in this format
+   maps the name recorded in CVS to author name, e-mail and
+   and optional timezone:
 +
 -
exon=Andreas Ericsson a...@op5.se
-   spawn=Simon Pawn sp...@frog-pond.org
+   spawn=Simon Pawn sp...@frog-pond.org America/Chicago
 
 -
 +
 'git cvsimport' will make it appear as those authors had
 their GIT_AUTHOR_NAME and GIT_AUTHOR_EMAIL set properly
-all along.
+all along.  If a timezone is specified, GIT_AUTHOR_DATE will
+have the corresponding offset applied.
 +
 For convenience, this data is saved to `$GIT_DIR/cvs-authors`
 each time the '-A' option is provided and read from that same
diff --git a/git-cvsimport.perl b/git-cvsimport.perl
index 8032f23..ceb119d 100755
--- a/git-cvsimport.perl
+++ b/git-cvsimport.perl
@@ -31,7 +31,7 @@ $SIG{'PIPE'}=IGNORE;
 $ENV{'TZ'}=UTC;
 
 our 
($opt_h,$opt_o,$opt_v,$opt_k,$opt_u,$opt_d,$opt_p,$opt_C,$opt_z,$opt_i,$opt_P, 
$opt_s,$opt_m,@opt_M,$opt_A,$opt_S,$opt_L, $opt_a, $opt_r, $opt_R);
-my (%conv_author_name, %conv_author_email);
+my (%conv_author_name, %conv_author_email, %conv_author_tz);
 
 sub usage(;$) {
my $msg = shift;
@@ -59,6 +59,14 @@ sub read_author_info($) {
$conv_author_name{$user} = $2;
$conv_author_email{$user} = $3;
}
+   # or with an optional timezone:
+   #   spawn=Simon Pawn sp...@frog-pond.org America/Chicago
+   elsif (m/^(\S+?)\s*=\s*(.+?)\s*(.+)\s*(\S+?)\s*$/) {
+   $user = $1;
+   $conv_author_name{$user} = $2;
+   $conv_author_email{$user} = $3;
+   $conv_author_tz{$user} = $4;
+   }
# However, we also read from CVSROOT/users format
# to ease migration.
elsif (/^(\w+):([']?)(.+?)\2\s*$/) {
@@ -84,7 +92,9 @@ sub write_author_info($) {
  die(Failed to open $file for writing: $!);
 
foreach (keys %conv_author_name) {
-   print $f $_=$conv_author_name{$_} $conv_author_email{$_}\n;
+   print $f $_=$conv_author_name{$_} $conv_author_email{$_};
+   print $f  $conv_author_tz{$_} if ($conv_author_tz{$_});
+   print $f \n;
}
close ($f);
 }
@@ -795,7 +805,7 @@ sub write_tree () {
return $tree;
 }
 
-my ($patchset,$date,$author_name,$author_email,$branch,$ancestor,$tag,$logmsg);
+my 
($patchset,$date,$author_name,$author_email,$author_tz,$branch,$ancestor,$tag,$logmsg);
 my (@old,@new,@skipped,%ignorebranch,@commit_revisions);
 
 # commits that cvsps cannot place anywhere...
@@ -844,7 +854,9 @@ sub commit {
}
}
 
-   my $commit_date = strftime(+ %Y-%m-%d %H:%M:%S,gmtime($date));
+   $ENV{'TZ'}=$author_tz;
+   my $commit_date = strftime(%s %z, localtime($date));
+   $ENV{'TZ'}=UTC;
$ENV{GIT_AUTHOR_NAME} = $author_name;
$ENV{GIT_AUTHOR_EMAIL} = $author_email;
$ENV{GIT_AUTHOR_DATE} = $commit_date;
@@ -945,12 +957,14 @@ while (CVS) {
}
$state=3;
} elsif ($state == 3 and s/^Author:\s+//) {
+   $author_tz = UTC;
s/\s+$//;
if (/^(.*?)\s+(.*)/) {
($author_name, $author_email) = ($1, $2);
} elsif ($conv_author_name{$_}) {
$author_name = 

Re: Cloning tags from master

2012-10-15 Thread PJ Weisberg
On Mon, Oct 15, 2012 at 12:44 PM, dquince
devin.qui...@troppussoftware.com wrote:
 I am trying to implement using tags in our build process, but am running into
 an issue with pulling tags from master. My scenario is as follows
 We decide on a release and I tag master with testtag which has commit
 testtag-1-gf3b117e
 When I make another commit to master and check the tag, I see it as
 testtag-2-gfb56442

I don't know what you mean by check the tag, but those look like the
output of git describe when HEAD is one or two commits ahead of
testtag (with no tags that are closer).

 When I try and pull the tag using testtag, it just wants to pull the latest
 commit to master.

You're probably not running git pull origin refs/tags/testtag, but I
think that's the only way to pull the tag, so I don't know what
you're doing here.  The tag doesn't include anything that's not part
of the tag's history, though, so pulling it won't get the latest
version of anything.

 I verified this works in branches other than master, so can this be done
 from master or does the tag just follow the head?

Tags never follow anything.  Once they're created, they stay put.

-PJ

Gehm's Corollary to Clark's Law: Any technology distinguishable from
magic is insufficiently advanced.
--
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-cvsimport: allow author-specific timezones

2012-10-15 Thread Junio C Hamano
Chris Rorvick ch...@rorvick.com writes:

 It occurred to me that the success of the unit test depends on the
 host platform's zoneinfo database.  I think this problem is inherent
 with this functionality.  Should the unit test attempt to detect
 support for the used timezones and short circuit if this fails?  Not
 sure exactly how I'd do this, but wondering if it's worth thinking
 about.

Yeah, that did indeed cross my mind.

You could say TZ=QST6QDT or something silly like that but that in
turn has to assume your tzset() is POSIX.1 compliant anyway.

We should at least protect the tests with prerequiste, perhaps like
this.

 t/t9604-cvsimport-timestamps.sh | 53 ++---
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git i/t/t9604-cvsimport-timestamps.sh w/t/t9604-cvsimport-timestamps.sh
index 6af41b7..f7683da 100755
--- i/t/t9604-cvsimport-timestamps.sh
+++ w/t/t9604-cvsimport-timestamps.sh
@@ -3,9 +3,30 @@
 test_description='git cvsimport timestamps'
 . ./lib-cvs.sh
 
+# Can your Perl grok these TZ settings correctly?
+test_lazy_prereq TZNAME '
+   perl -e '\''
+   use POSIX qw(strftime);
+   while (STDIN) {
+   my ($zone, $time, $expect) = split(q/ /);
+   $ENV{TZ} = $zone;
+   if (strftime(q/%z/, localtime($time)) ne $expect) {
+   exit(1);
+   }
+   }
+   exit(0);
+   '\'' -\EOF
+   America/Chicago 1345174000 -0500
+   America/Chicago 1329622000 -0600
+   Australia/Sydney 1345174000 +1000
+   Australia/Sydney 1329622000 +1100
+   Asia/Shanghai 1329622000 +0800
+   EOF
+'
+
 setup_cvs_test_repository t9604
 
-test_expect_success 'check timestamps are UTC (TZ=America/Chicago)' '
+test_expect_success TZNAME 'check timestamps are UTC (TZ=America/Chicago)' '
TZ=America/Chicago git cvsimport -p-x -C module-1 module 
git cvsimport -p-x -C module-1 module 
(
--
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: push race

2012-10-15 Thread Jeff King
On Mon, Oct 15, 2012 at 07:09:52PM -0700, Shawn O. Pearce wrote:

 On Mon, Oct 15, 2012 at 11:56 AM, Jeff King p...@peff.net wrote:
  Right. The only thing that needs locking is the refs, because the object
  database is add-only for normal operations, and by definition collisions
  mean you have the same content (or are astronomically unlucky, but your
  consolation prize is that you can write a paper on how you found a sha1
  collision).
 
 Its worth nothing that a SHA-1 collision can be identified at the
 server because the server performs a byte-for-byte compare of both
 copies of the object to make sure they match exactly in every way. Its
 not fast, but its safe. :-)

Do we? I thought early versions of git did that, but we did not
double-check collisions any more for performance reasons. You don't
happen to remember where that code is, do you (not that it really
matters, but I am just curious)?

-Peff
--
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/3] Change colors to be based on git status -sb in color mode

2012-10-15 Thread Simon Oosthoek
Hi

this patch is an additional patch to the previous series of two.  It also
corrects the missing S and some minor details. The main point of this
one is changing the used colors to be more close to the color output of git
status -sb Mainly, the branchname stays green until it loses a HEAD, in
detached head state it becomes red.
The flags get their own color, either red or green for unstaged/staged and the
remaining flags get a different color or none at all.

Cheers

Simon

The color in the prompt now follows the colors used by
git itself when showing colors. The branch name is only
colored red if the tree has a detached HEAD.

Signed-off-by: Simon Oosthoek s.oosth...@xs4all.nl
---
 contrib/completion/git-prompt.sh |   52 ++
 1 file changed, 30 insertions(+), 22 deletions(-)

diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh
index 4fb998a..ff69bbc 100644
--- a/contrib/completion/git-prompt.sh
+++ b/contrib/completion/git-prompt.sh
@@ -55,11 +55,9 @@
 # setting the bash.showUpstream config variable.
 #
 # If you would like a colored hint about the current dirty state, set
-# GIT_PS1_SHOWCOLORHINTS to a nonempty value. When tracked files are
-# modified, the branch name turns red, when all modifications are staged
-# the branch name turns yellow and when all changes are checked in, the
-# color changes to green. The colors are currently hardcoded in the function.
-
+# GIT_PS1_SHOWCOLORHINTS to a nonempty value. The colors are based on 
+# the colored output of git status -sb.
+#
 # __gitdir accepts 0 or 1 arguments (i.e., location)
 # returns location of .git repo
 __gitdir ()
@@ -325,35 +323,45 @@ __git_ps1 ()
 
local f=$w$i$s$u
if [ $pcmode = yes ]; then
-   PS1=$ps1pc_start(
-   if [ -n ${GIT_PS1_SHOWCOLORHINT-} ]; then
+   if [ -n ${GIT_PS1_SHOWCOLORHINTS-} ]; then
local c_red='\e[31m'
local c_green='\e[32m'
-   local c_yellow='\e[33m'
local c_lblue='\e[1;34m'
-   local c_purple='\e[35m'
-   local c_cyan='\e[36m'
local c_clear='\e[0m'
local branchstring=$c${b##refs/heads/}
-   local branch_color=$c_green
-   local flags_color=$c_cyan
+   local branch_color=$c_clear
+   local flags_color=$c_lblue
 
-   if [ $w = * ]; then
-   branch_color=$c_red
-   elif [ -n $i ]; then
-   branch_color=$c_yellow
-   fi
+   case $b in 
+   \(*\))  branch_color=$c_red
+   ;;
+   *)  local branch_color=$c_green
+   ;;
+   esac
 
# Setting PS1 directly with \[ and \] around 
colors
# is necessary to prevent wrapping issues!
-   
PS1=$PS1\[$branch_color\]$branchstring\[$c_clear\]
-   if [ -n $f ]; then
-   PS1=$PS1 
\[$flags_color\]$f\[$c_clear\]
+   PS1=$ps1pc_start 
(\[$branch_color\]$branchstring\[$c_clear\]
+
+   if [ -n $w$i$s$u$r$p ]; then
+   PS1=$PS1 
+   fi
+   if [ $w = * ]; then
+   PS1=$PS1\[$c_red\]$w
+   fi
+   if [ -n $i ]; then
+   PS1=$PS1\[$c_green\]$i
+   fi
+   if [ -n $s ]; then
+   PS1=$PS1\[$flags_color\]$s
+   fi
+   if [ -n $u ]; then
+   PS1=$PS1\[$c_red\]$u
fi
+   PS1=$PS1\[$c_clear\]$r$p)$ps1pc_end
else
-   PS1=$PS1$c${b##refs/heads/}${f:+ $f}$r$p
+   PS1=$ps1pc_start ($c${b##refs/heads/}${f:+ 
$f}$r$p)$ps1pc_end
fi
-   PS1=$PS1)$ps1pc_end
else
# NO color option unless in PROMPT_COMMAND mode
printf -- $printf_format $c${b##refs/heads/}${f:+ 
$f}$r$p
-- 
1.7.9.5
--
To unsubscribe from this 

Re: push race

2012-10-15 Thread Jeff King
On Tue, Oct 16, 2012 at 12:15:21PM +0700, Nguyen Thai Ngoc Duy wrote:

 On Tue, Oct 16, 2012 at 11:51 AM, Jeff King p...@peff.net wrote:
  Its worth nothing that a SHA-1 collision can be identified at the
  server because the server performs a byte-for-byte compare of both
  copies of the object to make sure they match exactly in every way. Its
  not fast, but its safe. :-)
 
  Do we? I thought early versions of git did that, but we did not
  double-check collisions any more for performance reasons. You don't
  happen to remember where that code is, do you (not that it really
  matters, but I am just curious)?
 
 We do. I touched that sha-1 collision code last time I updated
 index-pack, to support large blobs. We only do that when we receive an
 object that we already have, which should not happen often unless
 you're under attack, so little performance impact normally. Search
 collision in index-pack.c

Ah, thanks, I remember this now. I think that I was thinking of the very
early code to check every sha1 file write. E.g., the code killed off by
aac1794 (Improve sha1 object file writing., 2005-05-03). But that is
ancient history that is not really relevant.

Interesting that we check only in index-pack. If the pushed content is
small enough, we will call unpack-objects. That follows the usual code
path for writing the object, which will prefer the existing copy.

I suspect a site that is heavy on alternates is invoking the index-pack
code path more frequently than necessary (e.g., history gets pushed to
one forked repo, then when it goes to the next one, we may not share the
ref that tells the client we already have the object and receive it a
second time).

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