Re: [PATCH v2 2/2] grep: stop looking at random places for .gitattributes
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
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
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
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
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
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
.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
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
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
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
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
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
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
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
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
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
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
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
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
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
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()
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()
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()
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()
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
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()
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
-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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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)
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
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 Æ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
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)
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
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
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)
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)
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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