author | Junio C Hamano <gitster@pobox.com> | |
Tue, 10 Jan 2012 22:14:26 +0000 (14:14 -0800) | ||
committer | Junio C Hamano <gitster@pobox.com> | |
Tue, 10 Jan 2012 22:14:26 +0000 (14:14 -0800) |
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 | 2 | |||
---|---|---|---|---|
Documentation/config.txt | patch | | diff1 | | diff2 | | blob | history |
attr.c | patch | | diff1 | | diff2 | | blob | history |
t/t0003-attributes.sh | patch | | diff1 | | diff2 | | blob | history |
diff --cc Documentation/config.txt
Simple merge
diff --cc attr.c
index 76b079f0f530e1372b2866f40cce21ec5266394c,2ce73651381c8ebfa6dfed6c2013b72059861b2b..96eda0ef078f998c020666f89eea29ac4b1bfb53
+++ b/attr.c
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) {
- struct attr_stack *elem;
+ struct attr_stack *elem;
- elem = read_attr_from_array(builtin_attr);
- elem->origin = NULL;
- elem->prev = attr_stack;
- attr_stack = elem;
+ if (attr_stack)
+ return;
- if (git_attr_system()) {
- elem = read_attr_from_file(git_etc_gitattributes(), 1);
- if (elem) {
- elem->origin = NULL;
- elem->prev = attr_stack;
- attr_stack = elem;
- }
- }
+ elem = read_attr_from_array(builtin_attr);
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
- if (git_attributes_file) {
- elem = read_attr_from_file(git_attributes_file, 1);
- if (elem) {
- elem->origin = NULL;
- elem->prev = attr_stack;
- attr_stack = elem;
- }
+ if (git_attr_system()) {
+ elem = read_attr_from_file(git_etc_gitattributes(), 1);
+ if (elem) {
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
}
+ }
- if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
- elem = read_attr(GITATTRIBUTES_FILE, 1);
- elem->origin = xstrdup("");
- 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;
attr_stack = elem;
- debug_push(elem);
}
+ }
- elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
- if (!elem)
- elem = xcalloc(1, sizeof(*elem));
- elem->origin = NULL;
+ 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);
}
+
+ elem = read_attr_from_file(git_path(INFOATTRIBUTES_FILE), 1);
+ if (!elem)
+ elem = xcalloc(1, sizeof(*elem));
+ elem->origin = NULL;
+ elem->prev = attr_stack;
+ attr_stack = elem;
}
-static void prepare_attr_stack(const char *path, int dirlen)
+static void prepare_attr_stack(const char *path)
{
struct attr_stack *elem, *info;
- int len;
- struct strbuf pathbuf;
+ int dirlen, len;
+ const char *cp;
- strbuf_init(&pathbuf, dirlen+2+strlen(GITATTRIBUTES_FILE));
+ cp = strrchr(path, '/');
+ if (!cp)
+ dirlen = 0;
+ else
+ dirlen = cp - path;
/*
* At the bottom of the attribute stack is the built-in
* Read from parent directories and push them down
*/
if (!is_bare_repository() || direction == GIT_ATTR_INDEX) {
+ /*
+ * bootstrap_attr_stack() should have added, and the
+ * above loop should have stopped before popping, the
+ * root element whose attr_stack->origin is set to an
+ * empty string.
+ */
+ struct strbuf pathbuf = STRBUF_INIT;
+
+ assert(attr_stack->origin);
while (1) {
- char *cp;
-
len = strlen(attr_stack->origin);
if (dirlen <= len)
break;
diff --cc t/t0003-attributes.sh
index 6946c4b82f9291f6618d49de2e3892a2c203d337,61b5a2eba633d52ebf53efb3c0539f8abf4094ea..19265c77cf0b1df828eea188d5f880cbb7497c63
+++ b/t/t0003-attributes.sh
'
+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 &&
+ attr_check ./a/g a/g &&
+ attr_check a/./g a/g &&
+ attr_check a/c/../b/g a/b/g
+
+'
+
+test_expect_success 'relative paths' '
+
+ (cd a && attr_check ../f f) &&
+ (cd a && attr_check f f) &&
+ (cd a && attr_check i a/i) &&
+ (cd a && attr_check g a/g) &&
+ (cd a && attr_check b/g a/b/g) &&
+ (cd b && attr_check ../a/f f) &&
+ (cd b && attr_check ../a/g a/g) &&
+ (cd b && attr_check ../a/b/g a/b/g)
+
+'
+
+ test_expect_success 'prefixes are not confused with leading directories' '
+ attr_check a_plus/g unspecified &&
+ cat >expect <<-\EOF &&
+ a/g: test: a/g
+ a_plus/g: test: unspecified
+ EOF
+ git check-attr test a/g a_plus/g >actual &&
+ test_cmp expect actual
+ '
+
test_expect_success 'core.attributesfile' '
attr_check global unspecified &&
git config core.attributesfile "$HOME/global-gitattributes" &&