]> git.proxmox.com Git - libgit2.git/commitdiff
Merge pull request #729 from arrbee/fix-728
authorVicent Martí <tanoku@gmail.com>
Fri, 25 May 2012 00:43:17 +0000 (17:43 -0700)
committerVicent Martí <tanoku@gmail.com>
Fri, 25 May 2012 00:43:17 +0000 (17:43 -0700)
Fix bugs for status

src/attr.c
src/attr_file.c
src/attr_file.h
src/diff.c
tests-clar/attr/attr_expect.h
tests-clar/attr/file.c
tests-clar/attr/lookup.c
tests-clar/attr/repo.c
tests-clar/core/env.c
tests-clar/status/worktree.c

index 093f64d5c90f7d7417de21f30bbeb2b1c3d87c78..fb66511964a7129e06e401e5224649b7f7ca5d91 100644 (file)
@@ -403,9 +403,14 @@ int git_attr_cache__push_file(
                goto finish;
        }
 
-       if (!file &&
-               (error = git_attr_file__new(&file, source, relfile, &cache->pool)) < 0)
-               goto finish;
+       /* if we got here, we have to parse and/or reparse the file */
+       if (file)
+               git_attr_file__clear_rules(file);
+       else {
+               error = git_attr_file__new(&file, source, relfile, &cache->pool);
+               if (error < 0)
+                       goto finish;
+       }
 
        if (parse && (error = parse(repo, content, file)) < 0)
                goto finish;
index 5030ad5de0fdc00ce5fcb010c62892d0d8591df7..ca2f8fb581753537c8cd86cc43fab5e0101a5e94 100644 (file)
@@ -139,18 +139,23 @@ int git_attr_file__new_and_load(
        return error;
 }
 
-void git_attr_file__free(git_attr_file *file)
+void git_attr_file__clear_rules(git_attr_file *file)
 {
        unsigned int i;
        git_attr_rule *rule;
 
-       if (!file)
-               return;
-
        git_vector_foreach(&file->rules, i, rule)
                git_attr_rule__free(rule);
 
        git_vector_free(&file->rules);
+}
+
+void git_attr_file__free(git_attr_file *file)
+{
+       if (!file)
+               return;
+
+       git_attr_file__clear_rules(file);
 
        if (file->pool_is_allocated) {
                git_pool_clear(file->pool);
@@ -338,10 +343,13 @@ int git_attr_fnmatch__parse(
        const char **base)
 {
        const char *pattern, *scan;
-       int slash_count;
+       int slash_count, allow_space;
 
        assert(spec && base && *base);
 
+       spec->flags = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE);
+       allow_space = (spec->flags != 0);
+
        pattern = *base;
 
        while (git__isspace(*pattern)) pattern++;
@@ -350,8 +358,6 @@ int git_attr_fnmatch__parse(
                return GIT_ENOTFOUND;
        }
 
-       spec->flags = 0;
-
        if (*pattern == '[') {
                if (strncmp(pattern, "[attr]", 6) == 0) {
                        spec->flags = spec->flags | GIT_ATTR_FNMATCH_MACRO;
@@ -368,8 +374,10 @@ int git_attr_fnmatch__parse(
        slash_count = 0;
        for (scan = pattern; *scan != '\0'; ++scan) {
                /* scan until (non-escaped) white space */
-               if (git__isspace(*scan) && *(scan - 1) != '\\')
-                       break;
+               if (git__isspace(*scan) && *(scan - 1) != '\\') {
+                       if (!allow_space || (*scan != ' ' && *scan != '\t'))
+                               break;
+               }
 
                if (*scan == '/') {
                        spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
index 3718f4bda1a2ef35ce4a01174d59b75de6344206..7939f838a0c539ecbdd3f1c053bc85577b6a8cf6 100644 (file)
@@ -22,6 +22,7 @@
 #define GIT_ATTR_FNMATCH_MACRO         (1U << 3)
 #define GIT_ATTR_FNMATCH_IGNORE                (1U << 4)
 #define GIT_ATTR_FNMATCH_HASWILD       (1U << 5)
+#define GIT_ATTR_FNMATCH_ALLOWSPACE    (1U << 6)
 
 typedef struct {
        char *pattern;
@@ -88,6 +89,8 @@ extern int git_attr_file__new_and_load(
 
 extern void git_attr_file__free(git_attr_file *file);
 
+extern void git_attr_file__clear_rules(git_attr_file *file);
+
 extern int git_attr_file__parse_buffer(
        git_repository *repo, const char *buf, git_attr_file *file);
 
index 0b2f8fb5052c3c01188808c79ed8f82611f68848..90baa9588344ff47b315b7146056dbf33ffc159a 100644 (file)
@@ -342,6 +342,7 @@ static git_diff_list *git_diff_list_alloc(
                git_attr_fnmatch *match = git__calloc(1, sizeof(git_attr_fnmatch));
                if (!match)
                        goto fail;
+               match->flags = GIT_ATTR_FNMATCH_ALLOWSPACE;
                ret = git_attr_fnmatch__parse(match, &diff->pool, NULL, &pattern);
                if (ret == GIT_ENOTFOUND) {
                        git__free(match);
index df1e1044be48d4a7616299b7f615ecce7a856e80..70f1ab4f56f0386b92e1c4be80e293391b10f919 100644 (file)
@@ -18,19 +18,20 @@ struct attr_expected {
 GIT_INLINE(void) attr_check_expected(
        enum attr_expect_t expected,
        const char *expected_str,
+       const char *name,
        const char *value)
 {
        switch (expected) {
        case EXPECT_TRUE:
-               cl_assert(GIT_ATTR_TRUE(value));
+               cl_assert_(GIT_ATTR_TRUE(value), name);
                break;
 
        case EXPECT_FALSE:
-               cl_assert(GIT_ATTR_FALSE(value));
+               cl_assert_(GIT_ATTR_FALSE(value), name);
                break;
 
        case EXPECT_UNDEFINED:
-               cl_assert(GIT_ATTR_UNSPECIFIED(value));
+               cl_assert_(GIT_ATTR_UNSPECIFIED(value), name);
                break;
 
        case EXPECT_STRING:
index d19708838310a9de319a7c88b068f06806977005..8866fd9bd6e99216f85bc2d77ee2759f9b6c9446 100644 (file)
@@ -114,7 +114,7 @@ static void check_one_assign(
        cl_assert_equal_s(name, assign->name);
        cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
 
-       attr_check_expected(expected, expected_str, assign->value);
+       attr_check_expected(expected, expected_str, assign->name, assign->value);
 }
 
 void test_attr_file__assign_variants(void)
index b2a6aac64c3b01de6a551aa5fee44405450cf3c6..40aac0b6e451420b8f1e7cec8b5ea486efd10605 100644 (file)
@@ -44,7 +44,7 @@ static void run_test_cases(git_attr_file *file, struct attr_expected *cases, int
                error = git_attr_file__lookup_one(file,&path,c->attr,&value);
                cl_git_pass(error);
 
-               attr_check_expected(c->expected, c->expected_str, value);
+               attr_check_expected(c->expected, c->expected_str, c->attr, value);
 
                git_attr_path__free(&path);
        }
index a88dfb3f937ce87dc9ec352dfd57f28ac417c17a..c37ff544afa8a9e12e71206da18183528d1d6c7f 100644 (file)
@@ -65,7 +65,7 @@ void test_attr_repo__get_one(void)
        for (scan = test_cases; scan->path != NULL; scan++) {
                const char *value;
                cl_git_pass(git_attr_get(&value, g_repo, 0, scan->path, scan->attr));
-               attr_check_expected(scan->expected, scan->expected_str, value);
+               attr_check_expected(scan->expected, scan->expected_str, scan->attr, value);
        }
 
        cl_assert(git_attr_cache__is_cached(g_repo, 0, ".git/info/attributes"));
index 0d58e560b5907e6e9f1af4968962922b5e1fde45..fb483e89e31bf63b47803a20d75a4b174dfd7e1c 100644 (file)
@@ -52,8 +52,11 @@ static int cl_setenv(const char *name, const char *value)
 
 #endif
 
-static char *env_home = NULL;
+#ifdef GIT_WIN32
 static char *env_userprofile = NULL;
+#else
+static char *env_home = NULL;
+#endif
 
 void test_core_env__initialize(void)
 {
index 6cc6259b88e9d1e03d66cc6a297897b96ad40295..b3ebdb78121967a996cae8e127febbde0457cc17 100644 (file)
@@ -516,3 +516,68 @@ void test_status_worktree__status_file_with_clean_index_and_empty_workdir(void)
        cl_git_pass(p_rmdir("wd"));
        cl_git_pass(p_unlink("my-index"));
 }
+
+
+void test_status_worktree__space_in_filename(void)
+{
+       git_repository *repo;
+       git_index *index;
+       status_entry_single result;
+       unsigned int status_flags;
+
+#define FILE_WITH_SPACE "LICENSE - copy.md"
+
+       cl_git_pass(git_repository_init(&repo, "with_space", 0));
+       cl_git_mkfile("with_space/" FILE_WITH_SPACE, "I have a space in my name\n");
+
+       /* file is new to working directory */
+
+       memset(&result, 0, sizeof(result));
+       cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+       cl_assert_equal_i(1, result.count);
+       cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+       cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+       cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+       /* ignore the file */
+
+       cl_git_rewritefile("with_space/.gitignore", "*.md\n.gitignore\n");
+
+       memset(&result, 0, sizeof(result));
+       cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+       cl_assert_equal_i(2, result.count);
+       cl_assert(result.status == GIT_STATUS_IGNORED);
+
+       cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+       cl_assert(status_flags == GIT_STATUS_IGNORED);
+
+       /* don't ignore the file */
+
+       cl_git_rewritefile("with_space/.gitignore", ".gitignore\n");
+
+       memset(&result, 0, sizeof(result));
+       cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+       cl_assert_equal_i(2, result.count);
+       cl_assert(result.status == GIT_STATUS_WT_NEW);
+
+       cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+       cl_assert(status_flags == GIT_STATUS_WT_NEW);
+
+       /* add the file to the index */
+
+       cl_git_pass(git_repository_index(&index, repo));
+       cl_git_pass(git_index_add(index, FILE_WITH_SPACE, 0));
+       cl_git_pass(git_index_write(index));
+
+       memset(&result, 0, sizeof(result));
+       cl_git_pass(git_status_foreach(repo, cb_status__single, &result));
+       cl_assert_equal_i(2, result.count);
+       cl_assert(result.status == GIT_STATUS_INDEX_NEW);
+
+       cl_git_pass(git_status_file(&status_flags, repo, FILE_WITH_SPACE));
+       cl_assert(status_flags == GIT_STATUS_INDEX_NEW);
+
+       git_index_free(index);
+       git_repository_free(repo);
+}