diff options
-rw-r--r-- | include/git2/checkout.h | 16 | ||||
-rw-r--r-- | src/attr_file.c | 12 | ||||
-rw-r--r-- | src/hash.h | 2 | ||||
-rw-r--r-- | src/hash/hash_win32.c | 15 | ||||
-rw-r--r-- | src/hash/hash_win32.h | 15 | ||||
-rw-r--r-- | src/util.c | 29 | ||||
-rw-r--r-- | src/util.h | 5 | ||||
-rw-r--r-- | src/xdiff/xdiffi.c | 2 | ||||
-rw-r--r-- | tests/attr/ignore.c | 25 |
9 files changed, 70 insertions, 51 deletions
diff --git a/include/git2/checkout.h b/include/git2/checkout.h index 3fb3fc127..e49111c5d 100644 --- a/include/git2/checkout.h +++ b/include/git2/checkout.h @@ -106,10 +106,22 @@ GIT_BEGIN_DECL typedef enum { GIT_CHECKOUT_NONE = 0, /**< default is a dry run, no actual updates */ - /** Allow safe updates that cannot overwrite uncommitted data */ + /** + * Allow safe updates that cannot overwrite uncommitted data. + * If the uncommitted changes don't conflict with the checked out files, + * the checkout will still proceed, leaving the changes intact. + * + * Mutually exclusive with GIT_CHECKOUT_FORCE. + * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE. + */ GIT_CHECKOUT_SAFE = (1u << 0), - /** Allow all updates to force working directory to look like index */ + /** + * Allow all updates to force working directory to look like index. + * + * Mutually exclusive with GIT_CHECKOUT_SAFE. + * GIT_CHECKOUT_FORCE takes precedence over GIT_CHECKOUT_SAFE. + */ GIT_CHECKOUT_FORCE = (1u << 1), diff --git a/src/attr_file.c b/src/attr_file.c index 40c72ea04..8619647a3 100644 --- a/src/attr_file.c +++ b/src/attr_file.c @@ -429,18 +429,6 @@ bool git_attr_fnmatch__match( return (p_fnmatch(match->pattern, relpath, flags) != FNM_NOMATCH); } - /* if path is a directory prefix of a negated pattern, then match */ - if ((match->flags & GIT_ATTR_FNMATCH_NEGATIVE) && path->is_dir) { - size_t pathlen = strlen(relpath); - bool prefixed = (pathlen <= match->length) && - ((match->flags & GIT_ATTR_FNMATCH_ICASE) ? - !strncasecmp(match->pattern, relpath, pathlen) : - !strncmp(match->pattern, relpath, pathlen)); - - if (prefixed && git_path_at_end_of_segment(&match->pattern[pathlen])) - return true; - } - return (p_fnmatch(match->pattern, filename, flags) != FNM_NOMATCH); } diff --git a/src/hash.h b/src/hash.h index 0502e352e..bd3e3b5de 100644 --- a/src/hash.h +++ b/src/hash.h @@ -31,8 +31,6 @@ void git_hash_ctx_cleanup(git_hash_ctx *ctx); # include "hash/hash_generic.h" #endif -int git_hash_global_init(void); - typedef struct { void *data; size_t len; diff --git a/src/hash/hash_win32.c b/src/hash/hash_win32.c index 4b6830358..792298f39 100644 --- a/src/hash/hash_win32.c +++ b/src/hash/hash_win32.c @@ -109,21 +109,6 @@ static void git_hash_global_shutdown(void) hash_cryptoapi_prov_shutdown(); } -int git_hash_global_init(void) -{ - int error = 0; - - if (hash_prov.type != INVALID) - return 0; - - if ((error = hash_cng_prov_init()) < 0) - error = hash_cryptoapi_prov_init(); - - git__on_shutdown(git_hash_global_shutdown); - - return error; -} - /* CryptoAPI: available in Windows XP and newer */ GIT_INLINE(int) hash_ctx_cryptoapi_init(git_hash_ctx *ctx) diff --git a/src/hash/hash_win32.h b/src/hash/hash_win32.h index 9704204e2..6cddcaa72 100644 --- a/src/hash/hash_win32.h +++ b/src/hash/hash_win32.h @@ -138,4 +138,19 @@ struct git_hash_ctx { } ctx; }; +GIT_INLINE(int) git_hash_global_init(void) +{ + int error = 0; + + if (hash_prov.type != INVALID) + return 0; + + if ((error = hash_cng_prov_init()) < 0) + error = hash_cryptoapi_prov_init(); + + git__on_shutdown(git_hash_global_shutdown); + + return error; +} + #endif diff --git a/src/util.c b/src/util.c index a49269b98..508dce504 100644 --- a/src/util.c +++ b/src/util.c @@ -204,13 +204,6 @@ int git__strntol32(int32_t *result, const char *nptr, size_t nptr_len, const cha return error; } -int git__strcmp(const char *a, const char *b) -{ - while (*a && *b && *a == *b) - ++a, ++b; - return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b); -} - int git__strcasecmp(const char *a, const char *b) { while (*a && *b && git__tolower(*a) == git__tolower(*b)) @@ -240,15 +233,6 @@ int git__strcasesort_cmp(const char *a, const char *b) return cmp; } -int git__strncmp(const char *a, const char *b, size_t sz) -{ - while (sz && *a && *b && *a == *b) - --sz, ++a, ++b; - if (!sz) - return 0; - return (int)(*(const unsigned char *)a) - (int)(*(const unsigned char *)b); -} - int git__strncasecmp(const char *a, const char *b, size_t sz) { int al, bl; @@ -301,7 +285,18 @@ GIT_INLINE(int) prefixcmp(const char *str, size_t str_n, const char *prefix, boo int git__prefixcmp(const char *str, const char *prefix) { - return prefixcmp(str, SIZE_MAX, prefix, false); + unsigned char s, p; + + while (1) { + p = *prefix++; + s = *str++; + + if (!p) + return 0; + + if (s != p) + return s - p; + } } int git__prefixncmp(const char *str, size_t str_n, const char *prefix) diff --git a/src/util.h b/src/util.h index 4314295f1..d4fe6eee7 100644 --- a/src/util.h +++ b/src/util.h @@ -150,12 +150,13 @@ extern int git__bsearch_r( void *payload, size_t *position); +#define git__strcmp strcmp +#define git__strncmp strncmp + extern int git__strcmp_cb(const void *a, const void *b); extern int git__strcasecmp_cb(const void *a, const void *b); -extern int git__strcmp(const char *a, const char *b); extern int git__strcasecmp(const char *a, const char *b); -extern int git__strncmp(const char *a, const char *b, size_t sz); extern int git__strncasecmp(const char *a, const char *b, size_t sz); extern int git__strcasesort_cmp(const char *a, const char *b); diff --git a/src/xdiff/xdiffi.c b/src/xdiff/xdiffi.c index 9a7f53808..916295b44 100644 --- a/src/xdiff/xdiffi.c +++ b/src/xdiff/xdiffi.c @@ -36,7 +36,7 @@ #elif defined(__GNUC__) # define XDL_INLINE(type) static __inline__ type #else -#define XDG_INLINE(type) static type +# define XDL_INLINE(type) static type #endif typedef struct s_xdpsplit { diff --git a/tests/attr/ignore.c b/tests/attr/ignore.c index 165e2ba09..110304a81 100644 --- a/tests/attr/ignore.c +++ b/tests/attr/ignore.c @@ -372,3 +372,28 @@ void test_attr_ignore__case_sensitive_unignore_does_nothing(void) assert_is_ignored(true, "case/file"); } + +void test_attr_ignore__ignored_subdirfiles_with_subdir_rule(void) +{ + cl_git_rewritefile( + "attr/.gitignore", + "dir/*\n" + "!dir/sub1/sub2/**\n"); + + assert_is_ignored(true, "dir/a.test"); + assert_is_ignored(true, "dir/sub1/a.test"); + assert_is_ignored(true, "dir/sub1/sub2"); +} + +void test_attr_ignore__ignored_subdirfiles_with_negations(void) +{ + cl_git_rewritefile( + "attr/.gitignore", + "dir/*\n" + "!dir/a.test\n"); + + assert_is_ignored(false, "dir/a.test"); + assert_is_ignored(true, "dir/b.test"); + assert_is_ignored(true, "dir/sub1/c.test"); +} + |