Skip to content

Commit aa8e08e

Browse files
committed
Merge branch 'cc/split-index-config' into pu
The experimental "split index" feature has gained a few configuration variables to make it easier to use. * cc/split-index-config: (21 commits) Documentation/git-update-index: explain splitIndex.* Documentation/config: add splitIndex.sharedIndexExpire read-cache: use freshen_shared_index() in read_index_from() read-cache: refactor read_index_from() t1700: test shared index file expiration read-cache: unlink old sharedindex files config: add git_config_get_expiry() from gc.c read-cache: touch shared index files when used sha1_file: make check_and_freshen_file() non static Documentation/config: add splitIndex.maxPercentChange t1700: add tests for splitIndex.maxPercentChange read-cache: regenerate shared index if necessary config: add git_config_get_max_percent_split_change() Documentation/git-update-index: talk about core.splitIndex config var Documentation/config: add information for core.splitIndex t1700: add tests for core.splitIndex update-index: warn in case of split-index incoherency read-cache: add and then use tweak_split_index() split-index: add {add,remove}_split_index() functions config: add git_config_get_split_index() ...
2 parents 8832987 + d3b9e9f commit aa8e08e

File tree

11 files changed

+442
-42
lines changed

11 files changed

+442
-42
lines changed

Documentation/config.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,10 @@ core.trustctime::
334334
crawlers and some backup systems).
335335
See linkgit:git-update-index[1]. True by default.
336336

337+
core.splitIndex::
338+
If true, the split-index feature of the index will be used.
339+
See linkgit:git-update-index[1]. False by default.
340+
337341
core.untrackedCache::
338342
Determines what to do about the untracked cache feature of the
339343
index. It will be kept, if this variable is unset or set to
@@ -2841,6 +2845,30 @@ showbranch.default::
28412845
The default set of branches for linkgit:git-show-branch[1].
28422846
See linkgit:git-show-branch[1].
28432847

2848+
splitIndex.maxPercentChange::
2849+
When the split index feature is used, this specifies the
2850+
percent of entries the split index can contain compared to the
2851+
whole number of entries in both the split index and the shared
2852+
index before a new shared index is written.
2853+
The value should be between 0 and 100. If the value is 0 then
2854+
a new shared index is always written, if it is 100 a new
2855+
shared index is never written.
2856+
By default the value is 20, so a new shared index is written
2857+
if the number of entries in the split index would be greater
2858+
than 20 percent of the total number of entries.
2859+
See linkgit:git-update-index[1].
2860+
2861+
splitIndex.sharedIndexExpire::
2862+
When the split index feature is used, shared index files with
2863+
a mtime older than this time will be removed when a new shared
2864+
index file is created. The value "now" expires all entries
2865+
immediately, and "never" suppresses expiration altogether.
2866+
The default value is "one.week.ago".
2867+
Note that each time a split index based on a shared index file
2868+
is either created or read from, the mtime of the shared index
2869+
file is updated to the current time.
2870+
See linkgit:git-update-index[1].
2871+
28442872
status.relativePaths::
28452873
By default, linkgit:git-status[1] shows paths relative to the
28462874
current directory. Setting this variable to `false` shows paths

Documentation/git-update-index.txt

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -163,14 +163,16 @@ may not support it yet.
163163

164164
--split-index::
165165
--no-split-index::
166-
Enable or disable split index mode. If enabled, the index is
167-
split into two files, $GIT_DIR/index and $GIT_DIR/sharedindex.<SHA-1>.
168-
Changes are accumulated in $GIT_DIR/index while the shared
169-
index file contains all index entries stays unchanged. If
170-
split-index mode is already enabled and `--split-index` is
171-
given again, all changes in $GIT_DIR/index are pushed back to
172-
the shared index file. This mode is designed for very large
173-
indexes that take a significant amount of time to read or write.
166+
Enable or disable split index mode. If split-index mode is
167+
already enabled and `--split-index` is given again, all
168+
changes in $GIT_DIR/index are pushed back to the shared index
169+
file.
170+
+
171+
These options take effect whatever the value of the `core.splitIndex`
172+
configuration variable (see linkgit:git-config[1]). But a warning is
173+
emitted when the change goes against the configured value, as the
174+
configured value will take effect next time the index is read and this
175+
will remove the intended effect of the option.
174176

175177
--untracked-cache::
176178
--no-untracked-cache::
@@ -388,6 +390,31 @@ Although this bit looks similar to assume-unchanged bit, its goal is
388390
different from assume-unchanged bit's. Skip-worktree also takes
389391
precedence over assume-unchanged bit when both are set.
390392

393+
Split index
394+
-----------
395+
396+
This mode is designed for very large indexes that take a significant
397+
amount of time to read or write.
398+
399+
In this mode, the index is split into two files, $GIT_DIR/index and
400+
$GIT_DIR/sharedindex.<SHA-1>. Changes are accumulated in
401+
$GIT_DIR/index, the split index, while the shared index file contains
402+
all index entries and stays unchanged.
403+
404+
All changes in the split index are pushed back to the shared index
405+
file when the number of entries in the split index reaches a level
406+
specified by the splitIndex.maxPercentChange config variable (see
407+
linkgit:git-config[1]).
408+
409+
Each time a new shared index file is created, the old shared index
410+
files are deleted if their mtime is older than what is specified by
411+
the splitIndex.sharedIndexExpire config variable (see
412+
linkgit:git-config[1]).
413+
414+
To avoid deleting a shared index file that is still used, its mtime is
415+
updated to the current time everytime a new split index based on the
416+
shared index file is either created or read from.
417+
391418
Untracked cache
392419
---------------
393420

builtin/gc.c

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,6 @@ static void report_pack_garbage(unsigned seen_bits, const char *path)
6262
string_list_append(&pack_garbage, path);
6363
}
6464

65-
static void git_config_date_string(const char *key, const char **output)
66-
{
67-
if (git_config_get_string_const(key, output))
68-
return;
69-
if (strcmp(*output, "now")) {
70-
unsigned long now = approxidate("now");
71-
if (approxidate(*output) >= now)
72-
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
73-
}
74-
}
75-
7665
static void process_log_file(void)
7766
{
7867
struct stat st;
@@ -111,8 +100,8 @@ static void gc_config(void)
111100
git_config_get_int("gc.auto", &gc_auto_threshold);
112101
git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
113102
git_config_get_bool("gc.autodetach", &detach_auto);
114-
git_config_date_string("gc.pruneexpire", &prune_expire);
115-
git_config_date_string("gc.worktreepruneexpire", &prune_worktrees_expire);
103+
git_config_get_expiry("gc.pruneexpire", &prune_expire);
104+
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
116105
git_config(git_default_config, NULL);
117106
}
118107

builtin/update-index.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,17 +1099,20 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
10991099
}
11001100

11011101
if (split_index > 0) {
1102-
init_split_index(&the_index);
1103-
the_index.cache_changed |= SPLIT_INDEX_ORDERED;
1104-
} else if (!split_index && the_index.split_index) {
1105-
/*
1106-
* can't discard_split_index(&the_index); because that
1107-
* will destroy split_index->base->cache[], which may
1108-
* be shared with the_index.cache[]. So yeah we're
1109-
* leaking a bit here.
1110-
*/
1111-
the_index.split_index = NULL;
1112-
the_index.cache_changed |= SOMETHING_CHANGED;
1102+
if (git_config_get_split_index() == 0)
1103+
warning(_("core.splitIndex is set to false; "
1104+
"remove or change it, if you really want to "
1105+
"enable split index"));
1106+
if (the_index.split_index)
1107+
the_index.cache_changed |= SPLIT_INDEX_ORDERED;
1108+
else
1109+
add_split_index(&the_index);
1110+
} else if (!split_index) {
1111+
if (git_config_get_split_index() == 1)
1112+
warning(_("core.splitIndex is set to true; "
1113+
"remove or change it, if you really want to "
1114+
"disable split index"));
1115+
remove_split_index(&the_index);
11131116
}
11141117

11151118
switch (untracked_cache) {

cache.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,6 +1273,9 @@ extern int has_pack_index(const unsigned char *sha1);
12731273

12741274
extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect);
12751275

1276+
/* Helper to check and "touch" a file */
1277+
extern int check_and_freshen_file(const char *fn, int freshen);
1278+
12761279
extern const signed char hexval_table[256];
12771280
static inline unsigned int hexval(unsigned char c)
12781281
{
@@ -1926,6 +1929,11 @@ extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
19261929
extern int git_config_get_maybe_bool(const char *key, int *dest);
19271930
extern int git_config_get_pathname(const char *key, const char **dest);
19281931
extern int git_config_get_untracked_cache(void);
1932+
extern int git_config_get_split_index(void);
1933+
extern int git_config_get_max_percent_split_change(void);
1934+
1935+
/* This dies if the configured or default date is in the future */
1936+
extern int git_config_get_expiry(const char *key, const char **output);
19291937

19301938
/*
19311939
* This is a hack for test programs like test-dump-untracked-cache to

config.c

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1712,6 +1712,19 @@ int git_config_get_pathname(const char *key, const char **dest)
17121712
return ret;
17131713
}
17141714

1715+
int git_config_get_expiry(const char *key, const char **output)
1716+
{
1717+
int ret = git_config_get_string_const(key, output);
1718+
if (ret)
1719+
return ret;
1720+
if (strcmp(*output, "now")) {
1721+
unsigned long now = approxidate("now");
1722+
if (approxidate(*output) >= now)
1723+
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
1724+
}
1725+
return ret;
1726+
}
1727+
17151728
int git_config_get_untracked_cache(void)
17161729
{
17171730
int val = -1;
@@ -1728,14 +1741,39 @@ int git_config_get_untracked_cache(void)
17281741
if (!strcasecmp(v, "keep"))
17291742
return -1;
17301743

1731-
error("unknown core.untrackedCache value '%s'; "
1732-
"using 'keep' default value", v);
1744+
error(_("unknown core.untrackedCache value '%s'; "
1745+
"using 'keep' default value"), v);
17331746
return -1;
17341747
}
17351748

17361749
return -1; /* default value */
17371750
}
17381751

1752+
int git_config_get_split_index(void)
1753+
{
1754+
int val;
1755+
1756+
if (!git_config_get_maybe_bool("core.splitindex", &val))
1757+
return val;
1758+
1759+
return -1; /* default value */
1760+
}
1761+
1762+
int git_config_get_max_percent_split_change(void)
1763+
{
1764+
int val = -1;
1765+
1766+
if (!git_config_get_int("splitindex.maxpercentchange", &val)) {
1767+
if (0 <= val && val <= 100)
1768+
return val;
1769+
1770+
return error(_("splitIndex.maxPercentChange value '%d' "
1771+
"should be between 0 and 100"), val);
1772+
}
1773+
1774+
return -1; /* default value */
1775+
}
1776+
17391777
NORETURN
17401778
void git_die_config_linenr(const char *key, const char *filename, int linenr)
17411779
{

0 commit comments

Comments
 (0)