summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/technical/index-format.txt4
-rw-r--r--builtin/update-index.c16
-rw-r--r--dir.c55
-rw-r--r--dir.h2
-rw-r--r--git-compat-util.h1
-rw-r--r--test-dump-untracked-cache.c1
6 files changed, 72 insertions, 7 deletions
diff --git a/Documentation/technical/index-format.txt b/Documentation/technical/index-format.txt
index db59a13600..b7093af8b2 100644
--- a/Documentation/technical/index-format.txt
+++ b/Documentation/technical/index-format.txt
@@ -242,6 +242,10 @@ Git index format
The extension starts with
+ - A sequence of NUL-terminated strings, preceded by the size of the
+ sequence in variable width encoding. Each string describes the
+ environment where the cache can be used.
+
- Stat data of $GIT_DIR/info/exclude. See "Index entry" section from
ctime field until "file size".
diff --git a/builtin/update-index.c b/builtin/update-index.c
index c6951ad3ce..790a6aa9db 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -1104,7 +1104,7 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
the_index.split_index = NULL;
the_index.cache_changed |= SOMETHING_CHANGED;
}
- if (untracked_cache > 0 && !the_index.untracked) {
+ if (untracked_cache > 0) {
struct untracked_cache *uc;
if (untracked_cache < 2) {
@@ -1112,11 +1112,15 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
if (!test_if_untracked_cache_is_supported())
return 1;
}
- uc = xcalloc(1, sizeof(*uc));
- 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;
- the_index.untracked = uc;
+ if (!the_index.untracked) {
+ 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;
+ the_index.untracked = uc;
+ }
+ add_untracked_ident(the_index.untracked);
the_index.cache_changed |= UNTRACKED_CHANGED;
} else if (!untracked_cache && the_index.untracked) {
the_index.untracked = NULL;
diff --git a/dir.c b/dir.c
index 2cf8f35cc7..e9eaf97efe 100644
--- a/dir.c
+++ b/dir.c
@@ -1794,6 +1794,40 @@ static int treat_leading_path(struct dir_struct *dir,
return rc;
}
+static const char *get_ident_string(void)
+{
+ static struct strbuf sb = STRBUF_INIT;
+ struct utsname uts;
+
+ if (sb.len)
+ return sb.buf;
+ if (uname(&uts))
+ 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 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;
+
+ for (p = uc->ident.buf; p < end; p += strlen(p) + 1)
+ if (!strcmp(p, get_ident_string()))
+ return 1;
+ return 0;
+}
+
+void add_untracked_ident(struct untracked_cache *uc)
+{
+ if (ident_in_untracked(uc))
+ return;
+ strbuf_addstr(&uc->ident, get_ident_string());
+ /* this strbuf contains a list of strings, save NUL too */
+ strbuf_addch(&uc->ident, 0);
+}
+
static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *dir,
int base_len,
const struct pathspec *pathspec)
@@ -1860,6 +1894,11 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
if (ce_skip_worktree(active_cache[i]))
return NULL;
+ if (!ident_in_untracked(dir->untracked)) {
+ warning(_("Untracked cache is disabled on this system."));
+ return NULL;
+ }
+
if (!dir->untracked->root) {
const int len = sizeof(*dir->untracked->root);
dir->untracked->root = xmalloc(len);
@@ -2268,6 +2307,11 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra
hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.sha1);
ouc->dir_flags = htonl(untracked->dir_flags);
memcpy(ouc->exclude_per_dir, untracked->exclude_per_dir, len + 1);
+
+ varint_len = encode_varint(untracked->ident.len, varbuf);
+ strbuf_add(out, varbuf, varint_len);
+ strbuf_add(out, untracked->ident.buf, untracked->ident.len);
+
strbuf_add(out, ouc, ouc_size(len));
free(ouc);
ouc = NULL;
@@ -2453,17 +2497,26 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long
struct untracked_cache *uc;
struct read_data rd;
const unsigned char *next = data, *end = (const unsigned char *)data + sz;
- int len;
+ const char *ident;
+ int ident_len, len;
if (sz <= 1 || end[-1] != '\0')
return NULL;
end--;
+ ident_len = decode_varint(&next);
+ if (next + ident_len > end)
+ return NULL;
+ ident = (const char *)next;
+ next += ident_len;
+
ouc = (const struct ondisk_untracked_cache *)next;
if (next + ouc_size(0) > end)
return NULL;
uc = xcalloc(1, sizeof(*uc));
+ strbuf_init(&uc->ident, ident_len);
+ strbuf_add(&uc->ident, ident, ident_len);
load_sha1_stat(&uc->ss_info_exclude, &ouc->info_exclude_stat,
ouc->info_exclude_sha1);
load_sha1_stat(&uc->ss_excludes_file, &ouc->excludes_file_stat,
diff --git a/dir.h b/dir.h
index 2ce7dd3d27..6ccbc454ac 100644
--- a/dir.h
+++ b/dir.h
@@ -127,6 +127,7 @@ struct untracked_cache {
struct sha1_stat ss_info_exclude;
struct sha1_stat ss_excludes_file;
const char *exclude_per_dir;
+ struct strbuf ident;
/*
* dir_struct#flags must match dir_flags or the untracked
* cache is ignored.
@@ -305,4 +306,5 @@ void untracked_cache_add_to_index(struct index_state *, const char *);
void free_untracked_cache(struct untracked_cache *);
struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);
void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
+void add_untracked_ident(struct untracked_cache *);
#endif
diff --git a/git-compat-util.h b/git-compat-util.h
index a3095be962..1663537791 100644
--- a/git-compat-util.h
+++ b/git-compat-util.h
@@ -134,6 +134,7 @@
#elif defined(_MSC_VER)
#include "compat/msvc.h"
#else
+#include <sys/utsname.h>
#include <sys/wait.h>
#include <sys/resource.h>
#include <sys/socket.h>
diff --git a/test-dump-untracked-cache.c b/test-dump-untracked-cache.c
index 710441ee05..25d855d98b 100644
--- a/test-dump-untracked-cache.c
+++ b/test-dump-untracked-cache.c
@@ -44,6 +44,7 @@ int main(int ac, char **av)
{
struct untracked_cache *uc;
struct strbuf base = STRBUF_INIT;
+ setup_git_directory();
if (read_cache() < 0)
die("unable to read index file");
uc = the_index.untracked;