Skip to content

Commit 0e0f761

Browse files
chriscoolgitster
authored andcommitted
dir: simplify untracked cache "ident" field
It is not a good idea to compare kernel versions and disable the untracked cache if it changes, as people may upgrade and still want the untracked cache to work. So let's just compare work tree locations and kernel name to decide if we should disable it. Also storing many locations in the ident field and comparing to any of them can be dangerous if GIT_WORK_TREE is used with different values. So let's just store one location, the location of the current work tree. The downside is that untracked cache can only be used by one type of OS for now. Exporting a git repo to different clients via a network to e.g. Linux and Windows means that only one can use the untracked cache. If the location changed in the ident field and we still want an untracked cache, let's delete the cache and recreate it. Note that if an untracked cache has been created by a previous Git version, then the kernel version is stored in the ident field. As we now compare with just the kernel name the comparison will fail and the untracked cache will be disabled until it's recreated. Helped-by: Torsten Bögershausen <[email protected]> Signed-off-by: Christian Couder <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 07b29bf commit 0e0f761

File tree

2 files changed

+24
-16
lines changed

2 files changed

+24
-16
lines changed

dir.c

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,28 +1913,31 @@ static const char *get_ident_string(void)
19131913
return sb.buf;
19141914
if (uname(&uts) < 0)
19151915
die_errno(_("failed to get kernel name and information"));
1916-
strbuf_addf(&sb, "Location %s, system %s %s %s", get_git_work_tree(),
1917-
uts.sysname, uts.release, uts.version);
1916+
strbuf_addf(&sb, "Location %s, system %s", get_git_work_tree(),
1917+
uts.sysname);
19181918
return sb.buf;
19191919
}
19201920

19211921
static int ident_in_untracked(const struct untracked_cache *uc)
19221922
{
1923-
const char *end = uc->ident.buf + uc->ident.len;
1924-
const char *p = uc->ident.buf;
1923+
/*
1924+
* Previous git versions may have saved many NUL separated
1925+
* strings in the "ident" field, but it is insane to manage
1926+
* many locations, so just take care of the first one.
1927+
*/
19251928

1926-
for (p = uc->ident.buf; p < end; p += strlen(p) + 1)
1927-
if (!strcmp(p, get_ident_string()))
1928-
return 1;
1929-
return 0;
1929+
return !strcmp(uc->ident.buf, get_ident_string());
19301930
}
19311931

1932-
void add_untracked_ident(struct untracked_cache *uc)
1932+
static void set_untracked_ident(struct untracked_cache *uc)
19331933
{
1934-
if (ident_in_untracked(uc))
1935-
return;
1934+
strbuf_reset(&uc->ident);
19361935
strbuf_addstr(&uc->ident, get_ident_string());
1937-
/* this strbuf contains a list of strings, save NUL too */
1936+
1937+
/*
1938+
* This strbuf used to contain a list of NUL separated
1939+
* strings, so save NUL too for backward compatibility.
1940+
*/
19381941
strbuf_addch(&uc->ident, 0);
19391942
}
19401943

@@ -1945,15 +1948,21 @@ static void new_untracked_cache(struct index_state *istate)
19451948
uc->exclude_per_dir = ".gitignore";
19461949
/* should be the same flags used by git-status */
19471950
uc->dir_flags = DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES;
1951+
set_untracked_ident(uc);
19481952
istate->untracked = uc;
1953+
istate->cache_changed |= UNTRACKED_CHANGED;
19491954
}
19501955

19511956
void add_untracked_cache(struct index_state *istate)
19521957
{
19531958
if (!istate->untracked) {
19541959
new_untracked_cache(istate);
1955-
add_untracked_ident(istate->untracked);
1956-
istate->cache_changed |= UNTRACKED_CHANGED;
1960+
} else {
1961+
if (!ident_in_untracked(istate->untracked)) {
1962+
free_untracked_cache(istate->untracked);
1963+
new_untracked_cache(istate);
1964+
}
1965+
}
19571966
}
19581967

19591968
void remove_untracked_cache(struct index_state *istate)
@@ -2022,7 +2031,7 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d
20222031
return NULL;
20232032

20242033
if (!ident_in_untracked(dir->untracked)) {
2025-
warning(_("Untracked cache is disabled on this system."));
2034+
warning(_("Untracked cache is disabled on this system or location."));
20262035
return NULL;
20272036
}
20282037

dir.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,6 @@ void untracked_cache_add_to_index(struct index_state *, const char *);
307307
void free_untracked_cache(struct untracked_cache *);
308308
struct untracked_cache *read_untracked_extension(const void *data, unsigned long sz);
309309
void write_untracked_extension(struct strbuf *out, struct untracked_cache *untracked);
310-
void add_untracked_ident(struct untracked_cache *);
311310
void add_untracked_cache(struct index_state *istate);
312311
void remove_untracked_cache(struct index_state *istate);
313312
#endif

0 commit comments

Comments
 (0)