if (sb.len)
return sb.buf;
- if (uname(&uts))
+ 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);
return remove_dir_recurse(path, flag, NULL);
}
+static GIT_PATH_FUNC(git_path_info_exclude, "info/exclude")
+
void setup_standard_excludes(struct dir_struct *dir)
{
const char *path;
dir->untracked ? &dir->ss_excludes_file : NULL);
/* per repository user preference */
- path = git_path("info/exclude");
+ path = git_path_info_exclude();
if (!access_or_warn(path, R_OK, 0))
add_excludes_from_file_1(dir, path,
dir->untracked ? &dir->ss_info_exclude : NULL);
return uc;
}
+static void invalidate_one_directory(struct untracked_cache *uc,
+ struct untracked_cache_dir *ucd)
+{
+ uc->dir_invalidated++;
+ ucd->valid = 0;
+ ucd->untracked_nr = 0;
+}
+
+/*
+ * Normally when an entry is added or removed from a directory,
+ * invalidating that directory is enough. No need to touch its
+ * ancestors. When a directory is shown as "foo/bar/" in git-status
+ * however, deleting or adding an entry may have cascading effect.
+ *
+ * Say the "foo/bar/file" has become untracked, we need to tell the
+ * untracked_cache_dir of "foo" that "bar/" is not an untracked
+ * directory any more (because "bar" is managed by foo as an untracked
+ * "file").
+ *
+ * Similarly, if "foo/bar/file" moves from untracked to tracked and it
+ * was the last untracked entry in the entire "foo", we should show
+ * "foo/" instead. Which means we have to invalidate past "bar" up to
+ * "foo".
+ *
+ * This function traverses all directories from root to leaf. If there
+ * is a chance of one of the above cases happening, we invalidate back
+ * to root. Otherwise we just invalidate the leaf. There may be a more
+ * sophisticated way than checking for SHOW_OTHER_DIRECTORIES to
+ * detect these cases and avoid unnecessary invalidation, for example,
+ * checking for the untracked entry named "bar/" in "foo", but for now
+ * stick to something safe and simple.
+ */
+static int invalidate_one_component(struct untracked_cache *uc,
+ struct untracked_cache_dir *dir,
+ const char *path, int len)
+{
+ const char *rest = strchr(path, '/');
+
+ if (rest) {
+ int component_len = rest - path;
+ struct untracked_cache_dir *d =
+ lookup_untracked(uc, dir, path, component_len);
+ int ret =
+ invalidate_one_component(uc, d, rest + 1,
+ len - (component_len + 1));
+ if (ret)
+ invalidate_one_directory(uc, dir);
+ return ret;
+ }
+
+ invalidate_one_directory(uc, dir);
+ return uc->dir_flags & DIR_SHOW_OTHER_DIRECTORIES;
+}
+
void untracked_cache_invalidate_path(struct index_state *istate,
const char *path)
{
- const char *sep;
- struct untracked_cache_dir *d;
if (!istate->untracked || !istate->untracked->root)
return;
- sep = strrchr(path, '/');
- if (sep)
- d = lookup_untracked(istate->untracked,
- istate->untracked->root,
- path, sep - path);
- else
- d = istate->untracked->root;
- istate->untracked->dir_invalidated++;
- d->valid = 0;
- d->untracked_nr = 0;
+ invalidate_one_component(istate->untracked, istate->untracked->root,
+ path, strlen(path));
}
void untracked_cache_remove_from_index(struct index_state *istate,