* [PATCH v3 1/5] attr.c: avoid inappropriate access to strbuf "buf" member
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
@ 2011-10-06 18:22 ` Brandon Casey
2011-10-06 18:22 ` [PATCH v3 2/5] cleanup: use internal memory allocation wrapper functions everywhere Brandon Casey
` (3 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Brandon Casey @ 2011-10-06 18:22 UTC (permalink / raw)
To: gitster; +Cc: git, peff, j.sixt, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
This code sequence performs a strcpy into the buf member of a strbuf
struct. The strcpy may move the position of the terminating nul of the
string and effectively change the length of string so that it does not
match the len member of the strbuf struct.
Currently, this sequence works since the strbuf was given a hint when it
was initialized to allocate enough space to accomodate the string that will
be strcpy'ed, but this is an implementation detail of strbufs, not a
guarantee.
So, lets rework this sequence so that the strbuf is only manipulated by
strbuf functions, and direct modification of its "buf" member is not
necessary.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
attr.c | 24 +++++++++++-------------
1 files changed, 11 insertions(+), 13 deletions(-)
diff --git a/attr.c b/attr.c
index 33cb4e4..fe38fcc 100644
--- a/attr.c
+++ b/attr.c
@@ -552,7 +552,6 @@ static void prepare_attr_stack(const char *path)
{
struct attr_stack *elem, *info;
int dirlen, len;
- struct strbuf pathbuf;
const char *cp;
cp = strrchr(path, '/');
@@ -561,8 +560,6 @@ static void prepare_attr_stack(const char *path)
else
dirlen = cp - path;
- strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
-
/*
* At the bottom of the attribute stack is the built-in
* set of attribute definitions, followed by the contents
@@ -607,27 +604,28 @@ static void prepare_attr_stack(const char *path)
* Read from parent directories and push them down
*/
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
- while (1) {
- char *cp;
+ struct strbuf pathbuf = STRBUF_INIT;
+ while (1) {
len = strlen(attr_stack->origin);
if (dirlen <= len)
break;
- strbuf_reset(&pathbuf);
- strbuf_add(&pathbuf, path, dirlen);
+ cp = memchr(path + len + 1, '/', dirlen - len - 1);
+ if (!cp)
+ cp = path + dirlen;
+ strbuf_add(&pathbuf, path, cp - path);
strbuf_addch(&pathbuf, '/');
- cp = strchr(pathbuf.buf + len + 1, '/');
- strcpy(cp + 1, GITATTRIBUTES_FILE);
+ strbuf_addstr(&pathbuf, GITATTRIBUTES_FILE);
elem = read_attr(pathbuf.buf, 0);
- *cp = '\0';
- elem->origin = strdup(pathbuf.buf);
+ strbuf_setlen(&pathbuf, cp - path);
+ elem->origin = strbuf_detach(&pathbuf, NULL);
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);
}
- }
- strbuf_release(&pathbuf);
+ strbuf_release(&pathbuf);
+ }
/*
* Finally push the "info" one at the top of the stack.
--
1.7.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 2/5] cleanup: use internal memory allocation wrapper functions everywhere
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
2011-10-06 18:22 ` [PATCH v3 1/5] attr.c: avoid inappropriate access to strbuf "buf" member Brandon Casey
@ 2011-10-06 18:22 ` Brandon Casey
2011-10-06 18:22 ` [PATCH v3 3/5] builtin/mv.c: plug miniscule memory leak Brandon Casey
` (2 subsequent siblings)
4 siblings, 0 replies; 13+ messages in thread
From: Brandon Casey @ 2011-10-06 18:22 UTC (permalink / raw)
To: gitster; +Cc: git, peff, j.sixt, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
The "x"-prefixed versions of strdup, malloc, etc. will check whether the
allocation was successful and terminate the process otherwise.
A few uses of malloc were left alone since they already implemented a
graceful path of failure or were in a quasi external library like xdiff.
Additionally, the call to malloc in compat/win32/syslog.c was not modified
since the syslog() implemented there is a die handler and a call to the
x-wrappers within a die handler could result in recursion should memory
allocation fail. This will have to be addressed separately.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
attr.c | 2 +-
builtin/mv.c | 2 +-
compat/mingw.c | 2 +-
compat/qsort.c | 2 +-
remote.c | 2 +-
show-index.c | 2 +-
transport-helper.c | 4 ++--
7 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/attr.c b/attr.c
index fe38fcc..0793859 100644
--- a/attr.c
+++ b/attr.c
@@ -533,7 +533,7 @@ static void bootstrap_attr_stack(void)
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
elem = read_attr(GITATTRIBUTES_FILE, 1);
- elem->origin = strdup("");
+ elem->origin = xstrdup("");
elem->prev = attr_stack;
attr_stack = elem;
debug_push(elem);
diff --git a/builtin/mv.c b/builtin/mv.c
index 40f33ca..e9d191f 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -29,7 +29,7 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec,
to_copy--;
if (to_copy != length || base_name) {
char *it = xmemdupz(result[i], to_copy);
- result[i] = base_name ? strdup(basename(it)) : it;
+ result[i] = base_name ? xstrdup(basename(it)) : it;
}
}
return get_pathspec(prefix, result);
diff --git a/compat/mingw.c b/compat/mingw.c
index 6ef0cc4..8947418 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -1183,7 +1183,7 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service,
}
ai->ai_addrlen = sizeof(struct sockaddr_in);
if (hints && (hints->ai_flags & AI_CANONNAME))
- ai->ai_canonname = h ? strdup(h->h_name) : NULL;
+ ai->ai_canonname = h ? xstrdup(h->h_name) : NULL;
else
ai->ai_canonname = NULL;
diff --git a/compat/qsort.c b/compat/qsort.c
index d93dce2..9574d53 100644
--- a/compat/qsort.c
+++ b/compat/qsort.c
@@ -55,7 +55,7 @@ void git_qsort(void *b, size_t n, size_t s,
msort_with_tmp(b, n, s, cmp, buf);
} else {
/* It's somewhat large, so malloc it. */
- char *tmp = malloc(size);
+ char *tmp = xmalloc(size);
msort_with_tmp(b, n, s, cmp, tmp);
free(tmp);
}
diff --git a/remote.c b/remote.c
index b8ecfa5..7840d2f 100644
--- a/remote.c
+++ b/remote.c
@@ -840,7 +840,7 @@ char *apply_refspecs(struct refspec *refspecs, int nr_refspec,
refspec->dst, &ret))
return ret;
} else if (!strcmp(refspec->src, name))
- return strdup(refspec->dst);
+ return xstrdup(refspec->dst);
}
return NULL;
}
diff --git a/show-index.c b/show-index.c
index 4c0ac13..63f9da5 100644
--- a/show-index.c
+++ b/show-index.c
@@ -48,7 +48,7 @@ int main(int argc, char **argv)
unsigned char sha1[20];
uint32_t crc;
uint32_t off;
- } *entries = malloc(nr * sizeof(entries[0]));
+ } *entries = xmalloc(nr * sizeof(entries[0]));
for (i = 0; i < nr; i++)
if (fread(entries[i].sha1, 20, 1, stdin) != 1)
die("unable to read sha1 %u/%u", i, nr);
diff --git a/transport-helper.c b/transport-helper.c
index 4eab844..0713126 100644
--- a/transport-helper.c
+++ b/transport-helper.c
@@ -183,7 +183,7 @@ static struct child_process *get_helper(struct transport *transport)
ALLOC_GROW(refspecs,
refspec_nr + 1,
refspec_alloc);
- refspecs[refspec_nr++] = strdup(capname + strlen("refspec "));
+ refspecs[refspec_nr++] = xstrdup(capname + strlen("refspec "));
} else if (!strcmp(capname, "connect")) {
data->connect = 1;
} else if (!prefixcmp(capname, "export-marks ")) {
@@ -445,7 +445,7 @@ static int fetch_with_import(struct transport *transport,
if (data->refspecs)
private = apply_refspecs(data->refspecs, data->refspec_nr, posn->name);
else
- private = strdup(posn->name);
+ private = xstrdup(posn->name);
read_ref(private, posn->old_sha1);
free(private);
}
--
1.7.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 3/5] builtin/mv.c: plug miniscule memory leak
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
2011-10-06 18:22 ` [PATCH v3 1/5] attr.c: avoid inappropriate access to strbuf "buf" member Brandon Casey
2011-10-06 18:22 ` [PATCH v3 2/5] cleanup: use internal memory allocation wrapper functions everywhere Brandon Casey
@ 2011-10-06 18:22 ` Brandon Casey
2011-10-06 18:22 ` [PATCH v3 4/5] attr: read core.attributesfile from git_default_core_config Brandon Casey
2011-10-06 18:22 ` [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns Brandon Casey
4 siblings, 0 replies; 13+ messages in thread
From: Brandon Casey @ 2011-10-06 18:22 UTC (permalink / raw)
To: gitster; +Cc: git, peff, j.sixt, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
The "it" string would not be free'ed if base_name was non-NULL.
Let's free it.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
builtin/mv.c | 6 +++++-
1 files changed, 5 insertions(+), 1 deletions(-)
diff --git a/builtin/mv.c b/builtin/mv.c
index e9d191f..5efe6c5 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -29,7 +29,11 @@ static const char **copy_pathspec(const char *prefix, const char **pathspec,
to_copy--;
if (to_copy != length || base_name) {
char *it = xmemdupz(result[i], to_copy);
- result[i] = base_name ? xstrdup(basename(it)) : it;
+ if (base_name) {
+ result[i] = xstrdup(basename(it));
+ free(it);
+ } else
+ result[i] = it;
}
}
return get_pathspec(prefix, result);
--
1.7.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 4/5] attr: read core.attributesfile from git_default_core_config
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
` (2 preceding siblings ...)
2011-10-06 18:22 ` [PATCH v3 3/5] builtin/mv.c: plug miniscule memory leak Brandon Casey
@ 2011-10-06 18:22 ` Brandon Casey
2011-10-06 18:22 ` [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns Brandon Casey
4 siblings, 0 replies; 13+ messages in thread
From: Brandon Casey @ 2011-10-06 18:22 UTC (permalink / raw)
To: gitster; +Cc: git, peff, j.sixt, Brandon Casey
From: Junio C Hamano <gitster@pobox.com>
This code calls git_config from a helper function to parse the config entry
it is interested in. Calling git_config in this way may cause a problem if
the helper function can be called after a previous call to git_config by
another function since the second call to git_config may reset some
variable to the value in the config file which was previously overridden.
The above is not a problem in this case since the function passed to
git_config only parses one config entry and the variable it sets is not
assigned outside of the parsing function. But a programmer who desires
all of the standard config options to be parsed may be tempted to modify
git_attr_config() so that it falls back to git_default_config() and then it
_would_ be vulnerable to the above described behavior.
So, move the call to git_config up into the top-level cmd_* function and
move the responsibility for parsing core.attributesfile into the main
config file parser.
Which is only the logical thing to do ;-)
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
attr.c | 15 ++-------------
builtin/check-attr.c | 2 ++
cache.h | 1 +
config.c | 3 +++
environment.c | 1 +
5 files changed, 9 insertions(+), 13 deletions(-)
diff --git a/attr.c b/attr.c
index 0793859..124337d 100644
--- a/attr.c
+++ b/attr.c
@@ -20,8 +20,6 @@ static const char git_attr__unknown[] = "(builtin)unknown";
#define ATTR__UNSET NULL
#define ATTR__UNKNOWN git_attr__unknown
-static const char *attributes_file;
-
/* This is a randomly chosen prime. */
#define HASHSIZE 257
@@ -494,14 +492,6 @@ static int git_attr_system(void)
return !git_env_bool("GIT_ATTR_NOSYSTEM", 0);
}
-static int git_attr_config(const char *var, const char *value, void *dummy)
-{
- if (!strcmp(var, "core.attributesfile"))
- return git_config_pathname(&attributes_file, var, value);
-
- return 0;
-}
-
static void bootstrap_attr_stack(void)
{
if (!attr_stack) {
@@ -521,9 +511,8 @@ static void bootstrap_attr_stack(void)
}
}
- git_config(git_attr_config, NULL);
- if (attributes_file) {
- elem = read_attr_from_file(attributes_file, 1);
+ if (git_attributes_file) {
+ elem = read_attr_from_file(git_attributes_file, 1);
if (elem) {
elem->origin = NULL;
elem->prev = attr_stack;
diff --git a/builtin/check-attr.c b/builtin/check-attr.c
index 708988a..abb1165 100644
--- a/builtin/check-attr.c
+++ b/builtin/check-attr.c
@@ -92,6 +92,8 @@ int cmd_check_attr(int argc, const char **argv, const char *prefix)
struct git_attr_check *check;
int cnt, i, doubledash, filei;
+ git_config(git_default_config, NULL);
+
argc = parse_options(argc, argv, prefix, check_attr_options,
check_attr_usage, PARSE_OPT_KEEP_DASHDASH);
diff --git a/cache.h b/cache.h
index 607c2ea..8d95fb2 100644
--- a/cache.h
+++ b/cache.h
@@ -589,6 +589,7 @@ extern int warn_ambiguous_refs;
extern int shared_repository;
extern const char *apply_default_whitespace;
extern const char *apply_default_ignorewhitespace;
+extern const char *git_attributes_file;
extern int zlib_compression_level;
extern int core_compression_level;
extern int core_compression_seen;
diff --git a/config.c b/config.c
index 4183f80..d3bcaa0 100644
--- a/config.c
+++ b/config.c
@@ -491,6 +491,9 @@ static int git_default_core_config(const char *var, const char *value)
return 0;
}
+ if (!strcmp(var, "core.attributesfile"))
+ return git_config_pathname(&git_attributes_file, var, value);
+
if (!strcmp(var, "core.bare")) {
is_bare_repository_cfg = git_config_bool(var, value);
return 0;
diff --git a/environment.c b/environment.c
index e96edcf..d60b73f 100644
--- a/environment.c
+++ b/environment.c
@@ -29,6 +29,7 @@ const char *git_log_output_encoding;
int shared_repository = PERM_UMASK;
const char *apply_default_whitespace;
const char *apply_default_ignorewhitespace;
+const char *git_attributes_file;
int zlib_compression_level = Z_BEST_SPEED;
int core_compression_level;
int core_compression_seen;
--
1.7.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
` (3 preceding siblings ...)
2011-10-06 18:22 ` [PATCH v3 4/5] attr: read core.attributesfile from git_default_core_config Brandon Casey
@ 2011-10-06 18:22 ` Brandon Casey
2011-10-09 15:16 ` Michael Haggerty
4 siblings, 1 reply; 13+ messages in thread
From: Brandon Casey @ 2011-10-06 18:22 UTC (permalink / raw)
To: gitster; +Cc: git, peff, j.sixt, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
When core.ignorecase is true, the file globs configured in the
.gitattributes file should be matched case-insensitively against the paths
in the working directory. Let's do so.
Plus, add some tests.
The last set of tests is performed only on a case-insensitive filesystem.
Those tests make sure that git handles the case where the .gitignore file
resides in a subdirectory and the user supplies a path that does not match
the case in the filesystem. In that case^H^H^H^Hsituation, part of the
path supplied by the user is effectively interpreted case-insensitively,
and part of it is dependent on the setting of core.ignorecase. git should
only match the portion of the path below the directory holding the
.gitignore file according to the setting of core.ignorecase.
This is also partly future-proofing. Currently, git builds the attr stack
based on the path supplied by the user, so we don't have to do anything
special (like use strcmp_icase) to handle the parts of that path that don't
match the filesystem with respect to case. If git instead built the attr
stack by scanning the repository, then the paths in the origin field would
not necessarily match the paths supplied by the user. If someone makes a
change like that in the future, these tests will notice.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
attr.c | 5 ++-
t/t0003-attributes.sh | 60 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 62 insertions(+), 3 deletions(-)
diff --git a/attr.c b/attr.c
index 124337d..76b079f 100644
--- a/attr.c
+++ b/attr.c
@@ -11,6 +11,7 @@
#include "cache.h"
#include "exec_cmd.h"
#include "attr.h"
+#include "dir.h"
const char git_attr__true[] = "(builtin)true";
const char git_attr__false[] = "\0(builtin)false";
@@ -631,7 +632,7 @@ static int path_matches(const char *pathname, int pathlen,
/* match basename */
const char *basename = strrchr(pathname, '/');
basename = basename ? basename + 1 : pathname;
- return (fnmatch(pattern, basename, 0) == 0);
+ return (fnmatch_icase(pattern, basename, 0) == 0);
}
/*
* match with FNM_PATHNAME; the pattern has base implicitly
@@ -645,7 +646,7 @@ static int path_matches(const char *pathname, int pathlen,
return 0;
if (baselen != 0)
baselen++;
- return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
+ return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;
}
static int macroexpand_one(int attr_nr, int rem);
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index ae2f1da..47a70c4 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -9,7 +9,7 @@ attr_check () {
path="$1"
expect="$2"
- git check-attr test -- "$path" >actual 2>err &&
+ git $3 check-attr test -- "$path" >actual 2>err &&
echo "$path: test: $2" >expect &&
test_cmp expect actual &&
test_line_count = 0 err
@@ -27,6 +27,7 @@ test_expect_success 'setup' '
echo "onoff test -test"
echo "offon -test test"
echo "no notest"
+ echo "A/e/F test=A/e/F"
) >.gitattributes &&
(
echo "g test=a/g" &&
@@ -93,6 +94,63 @@ test_expect_success 'attribute test' '
'
+test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
+
+ test_must_fail attr_check F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
+ test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
+ test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
+ attr_check NO unspecified "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
+
+'
+
+test_expect_success 'attribute matching is case insensitive when core.ignorecase=1' '
+
+ attr_check F f "-c core.ignorecase=1" &&
+ attr_check a/F f "-c core.ignorecase=1" &&
+ attr_check a/c/F f "-c core.ignorecase=1" &&
+ attr_check a/G a/g "-c core.ignorecase=1" &&
+ attr_check a/B/g a/b/g "-c core.ignorecase=1" &&
+ attr_check a/b/G a/b/g "-c core.ignorecase=1" &&
+ attr_check a/b/H a/b/h "-c core.ignorecase=1" &&
+ attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check oNoFf unset "-c core.ignorecase=1" &&
+ attr_check oFfOn set "-c core.ignorecase=1" &&
+ attr_check NO unspecified "-c core.ignorecase=1" &&
+ attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check a/b/d/YES unspecified "-c core.ignorecase=1" &&
+ attr_check a/E/f "A/e/F" "-c core.ignorecase=1"
+
+'
+
+test_expect_success 'check whether FS is case-insensitive' '
+ mkdir junk &&
+ echo good >junk/CamelCase &&
+ echo bad >junk/camelcase &&
+ if test "$(cat junk/CamelCase)" != good
+ then
+ test_set_prereq CASE_INSENSITIVE_FS
+ fi
+'
+
+test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
+ test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
+ test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check A/b/h a/b/h "-c core.ignorecase=0" &&
+ attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
+ attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
+'
+
test_expect_success 'unnormalized paths' '
attr_check ./f f &&
--
1.7.7
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-06 18:22 ` [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns Brandon Casey
@ 2011-10-09 15:16 ` Michael Haggerty
2011-10-10 18:01 ` Brandon Casey
2011-10-11 0:00 ` [PATCH v3 5/5] " Junio C Hamano
0 siblings, 2 replies; 13+ messages in thread
From: Michael Haggerty @ 2011-10-09 15:16 UTC (permalink / raw)
To: Brandon Casey; +Cc: gitster, git, peff, j.sixt, Brandon Casey
On 10/06/2011 08:22 PM, Brandon Casey wrote:
> The last set of tests is performed only on a case-insensitive filesystem.
> Those tests make sure that git handles the case where the .gitignore file
> resides in a subdirectory and the user supplies a path that does not match
> the case in the filesystem. In that case^H^H^H^Hsituation, part of the
> path supplied by the user is effectively interpreted case-insensitively,
> and part of it is dependent on the setting of core.ignorecase. git should
> only match the portion of the path below the directory holding the
> .gitignore file according to the setting of core.ignorecase.
Isn't this a rather perverse scenario? It is hard to imagine that
anybody *wants* part of a single filename to be matched
case-insensitively and another part to be matched case-sensitively.
ISTM that a person who is using a case-insensitive filesystem and has
core-ignorecase=false is (1) a glutton for punishment and (2) probably
very careful to make sure that the case of all pathnames is correct. So
such a person is not likely to benefit from this schizophrenic behavior.
> [...] If git instead built the attr
> stack by scanning the repository, then the paths in the origin field would
> not necessarily match the paths supplied by the user. If someone makes a
> change like that in the future, these tests will notice.
Your decision to treat path names as partly case-insensitive will make
this kind of improvement considerably more complicated.
Therefore, weighing the negligible benefit of declaring this
schizophrenic behavior against the potential big pain of remaining
backwards-compatible with this behavior, I suggest that we either (1)
declare that when core.ignorecase=false then the *whole* filenames
(including the path leading up to the .gitignore file) must match
case-sensitively, or (2) declare the behavior in this situation to be
undefined so that nobody thinks they should depend on it.
But given that I'm a potential implementer but not a potential Windows
user, perhaps my judgment is biased...
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-09 15:16 ` Michael Haggerty
@ 2011-10-10 18:01 ` Brandon Casey
2011-10-11 3:44 ` Michael Haggerty
2011-10-11 0:00 ` [PATCH v3 5/5] " Junio C Hamano
1 sibling, 1 reply; 13+ messages in thread
From: Brandon Casey @ 2011-10-10 18:01 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Brandon Casey, gitster, git, peff, j.sixt
On Sun, Oct 9, 2011 at 10:16 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> On 10/06/2011 08:22 PM, Brandon Casey wrote:
>> The last set of tests is performed only on a case-insensitive filesystem.
>> Those tests make sure that git handles the case where the .gitignore file
>> resides in a subdirectory and the user supplies a path that does not match
>> the case in the filesystem. In that case^H^H^H^Hsituation, part of the
>> path supplied by the user is effectively interpreted case-insensitively,
>> and part of it is dependent on the setting of core.ignorecase. git should
>> only match the portion of the path below the directory holding the
>> .gitignore file according to the setting of core.ignorecase.
>
> Isn't this a rather perverse scenario?
No argument here. :)
> It is hard to imagine that
> anybody *wants* part of a single filename to be matched
> case-insensitively and another part to be matched case-sensitively.
> ISTM that a person who is using a case-insensitive filesystem and has
> core-ignorecase=false is (1) a glutton for punishment and (2) probably
> very careful to make sure that the case of all pathnames is correct. So
> such a person is not likely to benefit from this schizophrenic behavior.
>
>> [...] If git instead built the attr
>> stack by scanning the repository, then the paths in the origin field would
>> not necessarily match the paths supplied by the user. If someone makes a
>> change like that in the future, these tests will notice.
>
> Your decision to treat path names as partly case-insensitive...
You are giving more credit to this patch than it deserves. It really
doesn't do much. It's not a design decision that I made to treat path
names as case-insensitive. That is a consequence of using a
case-insensitive file system. When you give git the path A/b/c and
there exists a/.gitattributes, then on a case insensitive file system
git will try to read A/.gitattributes and the filesystem will return a
handle for a/.gitattributes and git won't be able to tell the
difference. git will then apply the rules in the file to the paths
below a/ even when the path is supplied like A/. So, at the moment,
regardless of the setting of core.ignorecase, the path above a
.gitignore file is treated as case-insensitive on a case-insensitive
filesystem.
The purpose of the tests are primarily to ensure that nothing special
needs to be done concerning paths leading up to a directory containing
a .gitignore file in the core.ignorecase=1 case. For example, it is
_not_ necessary to use strncmp_icase instead of strncmp on the leading
portion of the path.
What I meant when I said "If someone makes a change like that in the
future, these tests will notice", is that they will notice that they
must now use strncmp_icase when comparing the portion of the path
above the .gitattributes file.
> will make
> this kind of improvement considerably more complicated.
> Therefore, weighing the negligible benefit of declaring this
> schizophrenic behavior against the potential big pain of remaining
> backwards-compatible with this behavior, I suggest that we either (1)
> declare that when core.ignorecase=false then the *whole* filenames
> (including the path leading up to the .gitignore file) must match
> case-sensitively, or (2) declare the behavior in this situation to be
> undefined so that nobody thinks they should depend on it.
I do not plan to make git treat leading paths case-sensitively on a
case-insensitive file system when core.ignorecase=0 any more than I
plan to make git treat leading paths case-insensitively on a
case-sensitive file system when core.ignorecase=1. For justification,
I refer back to your original comment about perversion. :)
So, #2 gets my vote.
Maybe my commit message is not clear that it is describing the current
behavior and not defining it. Instead of
git should only match the portion of the path below the directory
holding the .gitignore file according to the setting of
core.ignorecase.
maybe I should say
git will currently only match the portion of the path...
I could also remove the following test from the CASE_INSENSITIVE_FS
tests since it is really a dontcare:
attr_check A/b/h a/b/h "-c core.ignorecase=0"
We don't care what happens when the user supplies A/b/h and a/b/h
exists on disk when core.ignorecase=0, we only care that A/b/h is
interpreted correctly when core.ignorecase=1.
-Brandon
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-09 15:16 ` Michael Haggerty
2011-10-10 18:01 ` Brandon Casey
@ 2011-10-11 0:00 ` Junio C Hamano
1 sibling, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2011-10-11 0:00 UTC (permalink / raw)
To: Michael Haggerty; +Cc: Brandon Casey, git, peff, j.sixt, Brandon Casey
Michael Haggerty <mhagger@alum.mit.edu> writes:
> On 10/06/2011 08:22 PM, Brandon Casey wrote:
>> The last set of tests is performed only on a case-insensitive filesystem.
>> Those tests make sure that git handles the case where the .gitignore file
>> resides in a subdirectory and the user supplies a path that does not match
>> the case in the filesystem. In that case^H^H^H^Hsituation, part of the
>> path supplied by the user is effectively interpreted case-insensitively,
>> and part of it is dependent on the setting of core.ignorecase. git should
>> only match the portion of the path below the directory holding the
>> .gitignore file according to the setting of core.ignorecase.
>
> ... It is hard to imagine that
> anybody *wants* part of a single filename to be matched
> case-insensitively and another part to be matched case-sensitively.
That is not necessarily coming from the user's wish. When a command that
takes a pathspec from the user is run from a subdirectory, almost always
the output from $(git rev-parse --show-prefix) is prefixed to them. This
value is read from the filesystem, and unless on a system whose readdir()
may lie to us, we do not _have_ to ignore the case of this part of the
substring of a resulting pathspec element to get a successful match, even
though we _do_ want to match the user-supplied part case insensitively
if/when the user says he wants us to with core.ignorecase.
Having said that, it may not hurt in practice if we matched the prefix
part case insensitvely, because prefix=foobar/ obtained on a filesystem
where core.ignorecase is true would mean there won't be FooBar/ and other
case-permuted names on the filesystem at the same time.
But of course I may be missing something...
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-10 18:01 ` Brandon Casey
@ 2011-10-11 3:44 ` Michael Haggerty
2011-10-11 15:53 ` [PATCH v4] " Brandon Casey
0 siblings, 1 reply; 13+ messages in thread
From: Michael Haggerty @ 2011-10-11 3:44 UTC (permalink / raw)
To: Brandon Casey; +Cc: Brandon Casey, gitster, git, peff, j.sixt
On 10/10/2011 08:01 PM, Brandon Casey wrote:
> On Sun, Oct 9, 2011 at 10:16 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> Maybe my commit message is not clear that it is describing the current
> behavior and not defining it. Instead of
>
> git should only match the portion of the path below the directory
> holding the .gitignore file according to the setting of
> core.ignorecase.
>
> maybe I should say
>
> git will currently only match the portion of the path...
>
> I could also remove the following test from the CASE_INSENSITIVE_FS
> tests since it is really a dontcare:
>
> attr_check A/b/h a/b/h "-c core.ignorecase=0"
>
> We don't care what happens when the user supplies A/b/h and a/b/h
> exists on disk when core.ignorecase=0, we only care that A/b/h is
> interpreted correctly when core.ignorecase=1.
Sounds good to me.
Thanks,
Michael
--
Michael Haggerty
mhagger@alum.mit.edu
http://softwareswirl.blogspot.com/
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH v4] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-11 3:44 ` Michael Haggerty
@ 2011-10-11 15:53 ` Brandon Casey
2011-10-11 16:54 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Brandon Casey @ 2011-10-11 15:53 UTC (permalink / raw)
To: gitster; +Cc: git, mhagger, Brandon Casey
From: Brandon Casey <drafnel@gmail.com>
When core.ignorecase is true, the file globs configured in the
.gitattributes file should be matched case-insensitively against the paths
in the working directory. Let's do so.
Plus, add some tests.
The last set of tests is performed only on a case-insensitive filesystem.
Those tests make sure that git handles the case where the .gitignore file
resides in a subdirectory and the user supplies a path that does not match
the case in the filesystem. In that case^H^H^H^Hsituation, part of the
path supplied by the user is effectively interpreted case-insensitively,
and part of it is dependent on the setting of core.ignorecase. git will
currently only match the portion of the path below the directory holding
the .gitignore file according to the setting of core.ignorecase.
This is also partly future-proofing. Currently, git builds the attr stack
based on the path supplied by the user, so we don't have to do anything
special (like use strcmp_icase) to handle the parts of that path that don't
match the filesystem with respect to case. If git instead built the attr
stack by scanning the repository, then the paths in the origin field would
not necessarily match the paths supplied by the user. If someone makes a
change like that in the future, these tests will notice.
Signed-off-by: Brandon Casey <drafnel@gmail.com>
---
On Mon, Oct 10, 2011 at 10:44 PM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
> On 10/10/2011 08:01 PM, Brandon Casey wrote:
>> On Sun, Oct 9, 2011 at 10:16 AM, Michael Haggerty <mhagger@alum.mit.edu> wrote:
>> Maybe my commit message is not clear that it is describing the current
>> behavior and not defining it. Instead of
>>
>> git should only match the portion of the path below the directory
>> holding the .gitignore file according to the setting of
>> core.ignorecase.
>>
>> maybe I should say
>>
>> git will currently only match the portion of the path...
>>
>> I could also remove the following test from the CASE_INSENSITIVE_FS
>> tests since it is really a dontcare:
>>
>> attr_check A/b/h a/b/h "-c core.ignorecase=0"
>>
>> We don't care what happens when the user supplies A/b/h and a/b/h
>> exists on disk when core.ignorecase=0, we only care that A/b/h is
>> interpreted correctly when core.ignorecase=1.
>
> Sounds good to me.
Ok, here it is.
Minor tweak which, hopefully, adds clarity to the commit message and
removes an unnecessary test.
On top of bc/attr-ignore-case^ 64589a03a8ffb3eb4fb2ff8f416ff638a9aaa439.
-Brandon
attr.c | 5 ++-
t/t0003-attributes.sh | 59 ++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 61 insertions(+), 3 deletions(-)
diff --git a/attr.c b/attr.c
index 124337d..76b079f 100644
--- a/attr.c
+++ b/attr.c
@@ -11,6 +11,7 @@
#include "cache.h"
#include "exec_cmd.h"
#include "attr.h"
+#include "dir.h"
const char git_attr__true[] = "(builtin)true";
const char git_attr__false[] = "\0(builtin)false";
@@ -631,7 +632,7 @@ static int path_matches(const char *pathname, int pathlen,
/* match basename */
const char *basename = strrchr(pathname, '/');
basename = basename ? basename + 1 : pathname;
- return (fnmatch(pattern, basename, 0) == 0);
+ return (fnmatch_icase(pattern, basename, 0) == 0);
}
/*
* match with FNM_PATHNAME; the pattern has base implicitly
@@ -645,7 +646,7 @@ static int path_matches(const char *pathname, int pathlen,
return 0;
if (baselen != 0)
baselen++;
- return fnmatch(pattern, pathname + baselen, FNM_PATHNAME) == 0;
+ return fnmatch_icase(pattern, pathname + baselen, FNM_PATHNAME) == 0;
}
static int macroexpand_one(int attr_nr, int rem);
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh
index ae2f1da..6946c4b 100755
--- a/t/t0003-attributes.sh
+++ b/t/t0003-attributes.sh
@@ -9,7 +9,7 @@ attr_check () {
path="$1"
expect="$2"
- git check-attr test -- "$path" >actual 2>err &&
+ git $3 check-attr test -- "$path" >actual 2>err &&
echo "$path: test: $2" >expect &&
test_cmp expect actual &&
test_line_count = 0 err
@@ -27,6 +27,7 @@ test_expect_success 'setup' '
echo "onoff test -test"
echo "offon -test test"
echo "no notest"
+ echo "A/e/F test=A/e/F"
) >.gitattributes &&
(
echo "g test=a/g" &&
@@ -93,6 +94,62 @@ test_expect_success 'attribute test' '
'
+test_expect_success 'attribute matching is case sensitive when core.ignorecase=0' '
+
+ test_must_fail attr_check F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/c/F f "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/G a/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/B/g a/b/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/G a/b/g "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/H a/b/h "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=0" &&
+ test_must_fail attr_check oNoFf unset "-c core.ignorecase=0" &&
+ test_must_fail attr_check oFfOn set "-c core.ignorecase=0" &&
+ attr_check NO unspecified "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check a/b/d/YES a/b/d/* "-c core.ignorecase=0" &&
+ test_must_fail attr_check a/E/f "A/e/F" "-c core.ignorecase=0"
+
+'
+
+test_expect_success 'attribute matching is case insensitive when core.ignorecase=1' '
+
+ attr_check F f "-c core.ignorecase=1" &&
+ attr_check a/F f "-c core.ignorecase=1" &&
+ attr_check a/c/F f "-c core.ignorecase=1" &&
+ attr_check a/G a/g "-c core.ignorecase=1" &&
+ attr_check a/B/g a/b/g "-c core.ignorecase=1" &&
+ attr_check a/b/G a/b/g "-c core.ignorecase=1" &&
+ attr_check a/b/H a/b/h "-c core.ignorecase=1" &&
+ attr_check a/b/D/g "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check oNoFf unset "-c core.ignorecase=1" &&
+ attr_check oFfOn set "-c core.ignorecase=1" &&
+ attr_check NO unspecified "-c core.ignorecase=1" &&
+ attr_check a/b/D/NO "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check a/b/d/YES unspecified "-c core.ignorecase=1" &&
+ attr_check a/E/f "A/e/F" "-c core.ignorecase=1"
+
+'
+
+test_expect_success 'check whether FS is case-insensitive' '
+ mkdir junk &&
+ echo good >junk/CamelCase &&
+ echo bad >junk/camelcase &&
+ if test "$(cat junk/CamelCase)" != good
+ then
+ test_set_prereq CASE_INSENSITIVE_FS
+ fi
+'
+
+test_expect_success CASE_INSENSITIVE_FS 'additional case insensitivity tests' '
+ test_must_fail attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=0" &&
+ test_must_fail attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=0" &&
+ attr_check A/b/h a/b/h "-c core.ignorecase=1" &&
+ attr_check a/B/D/g "a/b/d/*" "-c core.ignorecase=1" &&
+ attr_check A/B/D/NO "a/b/d/*" "-c core.ignorecase=1"
+'
+
test_expect_success 'unnormalized paths' '
attr_check ./f f &&
--
1.7.7.138.g7f41b6
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH v4] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-11 15:53 ` [PATCH v4] " Brandon Casey
@ 2011-10-11 16:54 ` Junio C Hamano
2011-10-12 20:18 ` Brandon Casey
0 siblings, 1 reply; 13+ messages in thread
From: Junio C Hamano @ 2011-10-11 16:54 UTC (permalink / raw)
To: Brandon Casey; +Cc: git, mhagger, Brandon Casey
Brandon Casey <casey@nrlssc.navy.mil> writes:
> ... Currently, git builds the attr stack
> based on the path supplied by the user, so we don't have to do anything
> special (like use strcmp_icase) to handle the parts of that path that don't
> match the filesystem with respect to case. If git instead built the attr
> stack by scanning the repository, then the paths in the origin field would
> not necessarily match the paths supplied by the user.
I find this description somewhat misleading. "check-attr" at the plumbing
level does take full path from the end user, but a common thing Git does
is to ask the system to learn the prefix to the current directory with
getcwd(3) append what fill_directory() enumerates as matching a pathspec
given by the user with readdir(3) to the prefix to form the full path, and
then feed that full path to git_check_attr().
Without anybody changing anything, we already do build the attr stack by
"scanning the repository" in that case, no?
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-11 16:54 ` Junio C Hamano
@ 2011-10-12 20:18 ` Brandon Casey
2011-10-12 20:24 ` Junio C Hamano
0 siblings, 1 reply; 13+ messages in thread
From: Brandon Casey @ 2011-10-12 20:18 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, mhagger, Brandon Casey
On 10/11/2011 11:54 AM, Junio C Hamano wrote:
> Brandon Casey <casey@nrlssc.navy.mil> writes:
>
>> ... Currently, git builds the attr stack
>> based on the path supplied by the user, so we don't have to do anything
>> special (like use strcmp_icase) to handle the parts of that path that don't
>> match the filesystem with respect to case. If git instead built the attr
>> stack by scanning the repository, then the paths in the origin field would
>> not necessarily match the paths supplied by the user.
>
> I find this description somewhat misleading. "check-attr" at the plumbing
> level does take full path from the end user, but a common thing Git does
> is to ask the system to learn the prefix to the current directory with
> getcwd(3) append what fill_directory() enumerates as matching a pathspec
> given by the user with readdir(3) to the prefix to form the full path, and
> then feed that full path to git_check_attr().
>
> Without anybody changing anything, we already do build the attr stack by
> "scanning the repository" in that case, no?
Well, kind of. What I meant by "scanning the repository", was having
two separate mechanisms: one to build the attr stack, and one to scan it
to get the attributes. Right now, the two operations are tied together
and the stack is built as needed, and it is built using the same path
string that the scan operation will use for checking for attributes.
So, the leading paths will match.
When I wrote that commit message, I really was only thinking about a
user-supplied path, but the focus should be on prepare_attr_stack().
The reason the leading paths to a .gitattributes file will necessarily
match is because the attr stack is built using the path supplied to
prepare_attr_stack(), and the same path string is used when scanning
the stack to check for attributes. So each path that is supplied,
regardless of whether its case matches the case in the file system or
in the repository, will have an entry in the attr stack.
Maybe that last paragraph in the commit message should just be dropped.
I think the preceding paragraph explains the purpose of the tests, and
this last one doesn't really add any value.
Do you want me to resubmit or can you fix it up? I ask not because I
am too lazy to do 'commit --amend' myself, but because you may prefer
to receive one less patch in your inbox if you can easily apply the
change yourself.
-Brandon
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH v4] attr.c: respect core.ignorecase when matching attribute patterns
2011-10-12 20:18 ` Brandon Casey
@ 2011-10-12 20:24 ` Junio C Hamano
0 siblings, 0 replies; 13+ messages in thread
From: Junio C Hamano @ 2011-10-12 20:24 UTC (permalink / raw)
To: Brandon Casey; +Cc: git, mhagger, Brandon Casey
Brandon Casey <casey@nrlssc.navy.mil> writes:
> On 10/11/2011 11:54 AM, Junio C Hamano wrote:
> ...
> Maybe that last paragraph in the commit message should just be dropped.
> I think the preceding paragraph explains the purpose of the tests, and
> this last one doesn't really add any value.
I wasn't saying the description was wrong per-se. It only makes difference
for "git check-attr" users, but it still _does_ make difference for them,
I think. So I kept the paragraph in the end.
> Do you want me to resubmit or can you fix it up? I ask not because I
> am too lazy to do 'commit --amend' myself, but because you may prefer
> to receive one less patch in your inbox if you can easily apply the
> change yourself.
It doesn't make much difference to me, as long as I don't forget a simple
and no-brainer amend I am supposed to do myself ;-).
Thanks.
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2011-10-12 20:24 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <VYN8m1JCy102-eaWWa-bsunEvt3zeXLJkVg7FZKZCtXT-Ww0vg7a8xA7NTvrZTiovKTnJ9Hlom0@cipher.nrlssc.navy.mil>
2011-10-06 18:22 ` [PATCH v3 1/5] attr.c: avoid inappropriate access to strbuf "buf" member Brandon Casey
2011-10-06 18:22 ` [PATCH v3 2/5] cleanup: use internal memory allocation wrapper functions everywhere Brandon Casey
2011-10-06 18:22 ` [PATCH v3 3/5] builtin/mv.c: plug miniscule memory leak Brandon Casey
2011-10-06 18:22 ` [PATCH v3 4/5] attr: read core.attributesfile from git_default_core_config Brandon Casey
2011-10-06 18:22 ` [PATCH v3 5/5] attr.c: respect core.ignorecase when matching attribute patterns Brandon Casey
2011-10-09 15:16 ` Michael Haggerty
2011-10-10 18:01 ` Brandon Casey
2011-10-11 3:44 ` Michael Haggerty
2011-10-11 15:53 ` [PATCH v4] " Brandon Casey
2011-10-11 16:54 ` Junio C Hamano
2011-10-12 20:18 ` Brandon Casey
2011-10-12 20:24 ` Junio C Hamano
2011-10-11 0:00 ` [PATCH v3 5/5] " Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).