pack-objects: use reachability bitmap index when generating non-stdout pack
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index 3087b7eb2e8f6fa8f3b3fb16310f621e80db301e..6172b3438d356d0359c2158708c718c6694e183a 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -53,24 +53,16 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir,
        int check_only, const struct path_simplify *simplify);
 static int get_dtype(struct dirent *de, const char *path, int len);
 
-/* helper string functions with support for the ignore_case flag */
-int strcmp_icase(const char *a, const char *b)
+int fspathcmp(const char *a, const char *b)
 {
        return ignore_case ? strcasecmp(a, b) : strcmp(a, b);
 }
 
-int strncmp_icase(const char *a, const char *b, size_t count)
+int fspathncmp(const char *a, const char *b, size_t count)
 {
        return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count);
 }
 
-int fnmatch_icase(const char *pattern, const char *string, int flags)
-{
-       return wildmatch(pattern, string,
-                        flags | (ignore_case ? WM_CASEFOLD : 0),
-                        NULL);
-}
-
 int git_fnmatch(const struct pathspec_item *item,
                const char *pattern, const char *string,
                int prefix)
@@ -457,7 +449,7 @@ int no_wildcard(const char *string)
 
 void parse_exclude_pattern(const char **pattern,
                           int *patternlen,
-                          int *flags,
+                          unsigned *flags,
                           int *nowildcardlen)
 {
        const char *p = *pattern;
@@ -498,7 +490,7 @@ void add_exclude(const char *string, const char *base,
 {
        struct exclude *x;
        int patternlen;
-       int flags;
+       unsigned flags;
        int nowildcardlen;
 
        parse_exclude_pattern(&string, &patternlen, &flags, &nowildcardlen);
@@ -798,16 +790,16 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname)
 
 int match_basename(const char *basename, int basenamelen,
                   const char *pattern, int prefix, int patternlen,
-                  int flags)
+                  unsigned flags)
 {
        if (prefix == patternlen) {
                if (patternlen == basenamelen &&
-                   !strncmp_icase(pattern, basename, basenamelen))
+                   !fspathncmp(pattern, basename, basenamelen))
                        return 1;
        } else if (flags & EXC_FLAG_ENDSWITH) {
                /* "*literal" matching against "fooliteral" */
                if (patternlen - 1 <= basenamelen &&
-                   !strncmp_icase(pattern + 1,
+                   !fspathncmp(pattern + 1,
                                   basename + basenamelen - (patternlen - 1),
                                   patternlen - 1))
                        return 1;
@@ -823,7 +815,7 @@ int match_basename(const char *basename, int basenamelen,
 int match_pathname(const char *pathname, int pathlen,
                   const char *base, int baselen,
                   const char *pattern, int prefix, int patternlen,
-                  int flags)
+                  unsigned flags)
 {
        const char *name;
        int namelen;
@@ -844,7 +836,7 @@ int match_pathname(const char *pathname, int pathlen,
         */
        if (pathlen < baselen + 1 ||
            (baselen && pathname[baselen] != '/') ||
-           strncmp_icase(pathname, base, baselen))
+           fspathncmp(pathname, base, baselen))
                return 0;
 
        namelen = baselen ? pathlen - baselen - 1 : pathlen;
@@ -858,7 +850,7 @@ int match_pathname(const char *pathname, int pathlen,
                if (prefix > namelen)
                        return 0;
 
-               if (strncmp_icase(pattern, name, prefix))
+               if (fspathncmp(pattern, name, prefix))
                        return 0;
                pattern += prefix;
                patternlen -= prefix;
@@ -1829,31 +1821,67 @@ static const char *get_ident_string(void)
                return sb.buf;
        if (uname(&uts) < 0)
                die_errno(_("failed to get kernel name and information"));
-       strbuf_addf(&sb, "Location %s, system %s %s %s", get_git_work_tree(),
-                   uts.sysname, uts.release, uts.version);
+       strbuf_addf(&sb, "Location %s, system %s", get_git_work_tree(),
+                   uts.sysname);
        return sb.buf;
 }
 
 static int ident_in_untracked(const struct untracked_cache *uc)
 {
-       const char *end = uc->ident.buf + uc->ident.len;
-       const char *p   = uc->ident.buf;
+       /*
+        * Previous git versions may have saved many NUL separated
+        * strings in the "ident" field, but it is insane to manage
+        * many locations, so just take care of the first one.
+        */
 
-       for (p = uc->ident.buf; p < end; p += strlen(p) + 1)
-               if (!strcmp(p, get_ident_string()))
-                       return 1;
-       return 0;
+       return !strcmp(uc->ident.buf, get_ident_string());
 }
 
-void add_untracked_ident(struct untracked_cache *uc)
+static void set_untracked_ident(struct untracked_cache *uc)
 {
-       if (ident_in_untracked(uc))
-               return;
+       strbuf_reset(&uc->ident);
        strbuf_addstr(&uc->ident, get_ident_string());
-       /* this strbuf contains a list of strings, save NUL too */
+
+       /*
+        * This strbuf used to contain a list of NUL separated
+        * strings, so save NUL too for backward compatibility.
+        */
        strbuf_addch(&uc->ident, 0);
 }
 
+static void new_untracked_cache(struct index_state *istate)
+{
+       struct untracked_cache *uc = xcalloc(1, sizeof(*uc));
+       strbuf_init(&uc->ident, 100);
+       uc->exclude_per_dir = ".gitignore";
+       /* should be the same flags used by git-status */
+       uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
+       set_untracked_ident(uc);
+       istate->untracked = uc;
+       istate->cache_changed |= UNTRACKED_CHANGED;
+}
+
+void add_untracked_cache(struct index_state *istate)
+{
+       if (!istate->untracked) {
+               new_untracked_cache(istate);
+       } else {
+               if (!ident_in_untracked(istate->untracked)) {
+                       free_untracked_cache(istate->untracked);
+                       new_untracked_cache(istate);
+               }
+       }
+}
+
+void remove_untracked_cache(struct index_state *istate)
+{
+       if (istate->untracked) {
+               free_untracked_cache(istate->untracked);
+               istate->untracked = NULL;
+               istate->cache_changed |= UNTRACKED_CHANGED;
+       }
+}
+
 static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,
                                                      int base_len,
                                                      const struct pathspec *pathspec)
@@ -1911,7 +1939,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
                return NULL;
 
        if (!ident_in_untracked(dir->untracked)) {
-               warning(_("Untracked cache is disabled on this system."));
+               warning(_("Untracked cache is disabled on this system or location."));
                return NULL;
        }