Skip to content

Commit 94c9b5a

Browse files
committed
Merge branch 'cc/split-index-config'
The experimental "split index" feature has gained a few configuration variables to make it easier to use. * cc/split-index-config: (22 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 32c43f5 + b460139 commit 94c9b5a

11 files changed

Lines changed: 540 additions & 131 deletions

File tree

Documentation/config.txt

Lines changed: 29 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
@@ -2850,6 +2854,31 @@ showbranch.default::
28502854
The default set of branches for linkgit:git-show-branch[1].
28512855
See linkgit:git-show-branch[1].
28522856

2857+
splitIndex.maxPercentChange::
2858+
When the split index feature is used, this specifies the
2859+
percent of entries the split index can contain compared to the
2860+
total number of entries in both the split index and the shared
2861+
index before a new shared index is written.
2862+
The value should be between 0 and 100. If the value is 0 then
2863+
a new shared index is always written, if it is 100 a new
2864+
shared index is never written.
2865+
By default the value is 20, so a new shared index is written
2866+
if the number of entries in the split index would be greater
2867+
than 20 percent of the total number of entries.
2868+
See linkgit:git-update-index[1].
2869+
2870+
splitIndex.sharedIndexExpire::
2871+
When the split index feature is used, shared index files that
2872+
were not modified since the time this variable specifies will
2873+
be removed when a new shared index file is created. The value
2874+
"now" expires all entries immediately, and "never" suppresses
2875+
expiration altogether.
2876+
The default value is "2.weeks.ago".
2877+
Note that a shared index file is considered modified (for the
2878+
purpose of expiration) each time a new split-index file is
2879+
either created based on it or read from it.
2880+
See linkgit:git-update-index[1].
2881+
28532882
status.relativePaths::
28542883
By default, linkgit:git-status[1] shows paths relative to the
28552884
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 repositories with very large indexes, and
397+
aims at reducing the time it takes to repeatedly write these indexes.
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 modification time is older than what is
411+
specified by 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
415+
modification time is updated to the current time everytime a new split
416+
index based on the shared index file is either created or read from.
417+
391418
Untracked cache
392419
---------------
393420

builtin/gc.c

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,6 @@ static void report_pack_garbage(unsigned seen_bits, const char *path)
6464
string_list_append(&pack_garbage, path);
6565
}
6666

67-
static void git_config_date_string(const char *key, const char **output)
68-
{
69-
if (git_config_get_string_const(key, output))
70-
return;
71-
if (strcmp(*output, "now")) {
72-
unsigned long now = approxidate("now");
73-
if (approxidate(*output) >= now)
74-
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
75-
}
76-
}
77-
7867
static void process_log_file(void)
7968
{
8069
struct stat st;
@@ -131,9 +120,9 @@ static void gc_config(void)
131120
git_config_get_int("gc.auto", &gc_auto_threshold);
132121
git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
133122
git_config_get_bool("gc.autodetach", &detach_auto);
134-
git_config_date_string("gc.pruneexpire", &prune_expire);
135-
git_config_date_string("gc.worktreepruneexpire", &prune_worktrees_expire);
136-
git_config_date_string("gc.logexpiry", &gc_log_expire);
123+
git_config_get_expiry("gc.pruneexpire", &prune_expire);
124+
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
125+
git_config_get_expiry("gc.logexpiry", &gc_log_expire);
137126

138127
git_config(git_default_config, NULL);
139128
}

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
@@ -1270,6 +1270,9 @@ extern int has_pack_index(const unsigned char *sha1);
12701270

12711271
extern void assert_sha1_type(const unsigned char *sha1, enum object_type expect);
12721272

1273+
/* Helper to check and "touch" a file */
1274+
extern int check_and_freshen_file(const char *fn, int freshen);
1275+
12731276
extern const signed char hexval_table[256];
12741277
static inline unsigned int hexval(unsigned char c)
12751278
{
@@ -1956,6 +1959,11 @@ extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
19561959
extern int git_config_get_maybe_bool(const char *key, int *dest);
19571960
extern int git_config_get_pathname(const char *key, const char **dest);
19581961
extern int git_config_get_untracked_cache(void);
1962+
extern int git_config_get_split_index(void);
1963+
extern int git_config_get_max_percent_split_change(void);
1964+
1965+
/* This dies if the configured or default date is in the future */
1966+
extern int git_config_get_expiry(const char *key, const char **output);
19591967

19601968
/*
19611969
* 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
@@ -1803,6 +1803,19 @@ int git_config_get_pathname(const char *key, const char **dest)
18031803
return ret;
18041804
}
18051805

1806+
int git_config_get_expiry(const char *key, const char **output)
1807+
{
1808+
int ret = git_config_get_string_const(key, output);
1809+
if (ret)
1810+
return ret;
1811+
if (strcmp(*output, "now")) {
1812+
unsigned long now = approxidate("now");
1813+
if (approxidate(*output) >= now)
1814+
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
1815+
}
1816+
return ret;
1817+
}
1818+
18061819
int git_config_get_untracked_cache(void)
18071820
{
18081821
int val = -1;
@@ -1819,14 +1832,39 @@ int git_config_get_untracked_cache(void)
18191832
if (!strcasecmp(v, "keep"))
18201833
return -1;
18211834

1822-
error("unknown core.untrackedCache value '%s'; "
1823-
"using 'keep' default value", v);
1835+
error(_("unknown core.untrackedCache value '%s'; "
1836+
"using 'keep' default value"), v);
18241837
return -1;
18251838
}
18261839

18271840
return -1; /* default value */
18281841
}
18291842

1843+
int git_config_get_split_index(void)
1844+
{
1845+
int val;
1846+
1847+
if (!git_config_get_maybe_bool("core.splitindex", &val))
1848+
return val;
1849+
1850+
return -1; /* default value */
1851+
}
1852+
1853+
int git_config_get_max_percent_split_change(void)
1854+
{
1855+
int val = -1;
1856+
1857+
if (!git_config_get_int("splitindex.maxpercentchange", &val)) {
1858+
if (0 <= val && val <= 100)
1859+
return val;
1860+
1861+
return error(_("splitIndex.maxPercentChange value '%d' "
1862+
"should be between 0 and 100"), val);
1863+
}
1864+
1865+
return -1; /* default value */
1866+
}
1867+
18301868
NORETURN
18311869
void git_die_config_linenr(const char *key, const char *filename, int linenr)
18321870
{

0 commit comments

Comments
 (0)