diff: activate diff.renames by default
[gitweb.git] / dir.c
diff --git a/dir.c b/dir.c
index b8b4576cd21f6761a2960dcc1648c1525fb76118..f0b6d0a3eab704311ed2c93a3da5db0683b3125c 100644 (file)
--- a/dir.c
+++ b/dir.c
@@ -880,25 +880,6 @@ int match_pathname(const char *pathname, int pathlen,
                 */
                if (!patternlen && !namelen)
                        return 1;
-               /*
-                * This can happen when we ignore some exclude rules
-                * on directories in other to see if negative rules
-                * may match. E.g.
-                *
-                * /abc
-                * !/abc/def/ghi
-                *
-                * The pattern of interest is "/abc". On the first
-                * try, we should match path "abc" with this pattern
-                * in the "if" statement right above, but the caller
-                * ignores it.
-                *
-                * On the second try with paths within "abc",
-                * e.g. "abc/xyz", we come here and try to match it
-                * with "/abc".
-                */
-               if (!patternlen && namelen && *name == '/')
-                       return 1;
        }
 
        return fnmatch_icase_mem(pattern, patternlen,
@@ -906,48 +887,6 @@ int match_pathname(const char *pathname, int pathlen,
                                 WM_PATHNAME) == 0;
 }
 
-/*
- * Return non-zero if pathname is a directory and an ancestor of the
- * literal path in a (negative) pattern. This is used to keep
- * descending in "foo" and "foo/bar" when the pattern is
- * "!foo/bar/.gitignore". "foo/notbar" will not be descended however.
- */
-static int match_neg_path(const char *pathname, int pathlen, int *dtype,
-                         const char *base, int baselen,
-                         const char *pattern, int prefix, int patternlen,
-                         int flags)
-{
-       assert((flags & EXC_FLAG_NEGATIVE) && !(flags & EXC_FLAG_NODIR));
-
-       if (*dtype == DT_UNKNOWN)
-               *dtype = get_dtype(NULL, pathname, pathlen);
-       if (*dtype != DT_DIR)
-               return 0;
-
-       if (*pattern == '/') {
-               pattern++;
-               patternlen--;
-               prefix--;
-       }
-
-       if (baselen) {
-               if (((pathlen < baselen && base[pathlen] == '/') ||
-                    pathlen == baselen) &&
-                   !strncmp_icase(pathname, base, pathlen))
-                       return 1;
-               pathname += baselen + 1;
-               pathlen  -= baselen + 1;
-       }
-
-
-       if (prefix &&
-           ((pathlen < prefix && pattern[pathlen] == '/') &&
-            !strncmp_icase(pathname, pattern, pathlen)))
-               return 1;
-
-       return 0;
-}
-
 /*
  * Scan the given exclude list in reverse to see whether pathname
  * should be ignored.  The first match (i.e. the last on the list), if
@@ -961,7 +900,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
                                                       struct exclude_list *el)
 {
        struct exclude *exc = NULL; /* undecided */
-       int i, matched_negative_path = 0;
+       int i;
 
        if (!el->nr)
                return NULL;    /* undefined */
@@ -996,18 +935,7 @@ static struct exclude *last_exclude_matching_from_list(const char *pathname,
                        exc = x;
                        break;
                }
-
-               if ((x->flags & EXC_FLAG_NEGATIVE) && !matched_negative_path &&
-                   match_neg_path(pathname, pathlen, dtype, x->base,
-                                  x->baselen ? x->baselen - 1 : 0,
-                                  exclude, prefix, x->patternlen, x->flags))
-                       matched_negative_path = 1;
-       }
-       if (exc &&
-           !(exc->flags & EXC_FLAG_NEGATIVE) &&
-           !(exc->flags & EXC_FLAG_NODIR) &&
-           matched_negative_path)
-               exc = NULL;
+       }
        return exc;
 }
 
@@ -1911,31 +1839,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)
@@ -1993,7 +1957,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;
        }