Skip to content

Commit

Permalink
Merge branch 'cc/split-index-config'
Browse files Browse the repository at this point in the history
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()
  ...
  • Loading branch information
gitster committed Mar 17, 2017
2 parents 32c43f5 + b460139 commit 94c9b5a
Show file tree
Hide file tree
Showing 11 changed files with 540 additions and 131 deletions.
29 changes: 29 additions & 0 deletions Documentation/config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,10 @@ core.trustctime::
crawlers and some backup systems).
See linkgit:git-update-index[1]. True by default.

core.splitIndex::
If true, the split-index feature of the index will be used.
See linkgit:git-update-index[1]. False by default.

core.untrackedCache::
Determines what to do about the untracked cache feature of the
index. It will be kept, if this variable is unset or set to
Expand Down Expand Up @@ -2850,6 +2854,31 @@ showbranch.default::
The default set of branches for linkgit:git-show-branch[1].
See linkgit:git-show-branch[1].

splitIndex.maxPercentChange::
When the split index feature is used, this specifies the
percent of entries the split index can contain compared to the
total number of entries in both the split index and the shared
index before a new shared index is written.
The value should be between 0 and 100. If the value is 0 then
a new shared index is always written, if it is 100 a new
shared index is never written.
By default the value is 20, so a new shared index is written
if the number of entries in the split index would be greater
than 20 percent of the total number of entries.
See linkgit:git-update-index[1].

splitIndex.sharedIndexExpire::
When the split index feature is used, shared index files that
were not modified since the time this variable specifies will
be removed when a new shared index file is created. The value
"now" expires all entries immediately, and "never" suppresses
expiration altogether.
The default value is "2.weeks.ago".
Note that a shared index file is considered modified (for the
purpose of expiration) each time a new split-index file is
either created based on it or read from it.
See linkgit:git-update-index[1].

status.relativePaths::
By default, linkgit:git-status[1] shows paths relative to the
current directory. Setting this variable to `false` shows paths
Expand Down
43 changes: 35 additions & 8 deletions Documentation/git-update-index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,16 @@ may not support it yet.

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

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

Split index
-----------

This mode is designed for repositories with very large indexes, and
aims at reducing the time it takes to repeatedly write these indexes.

In this mode, the index is split into two files, $GIT_DIR/index and
$GIT_DIR/sharedindex.<SHA-1>. Changes are accumulated in
$GIT_DIR/index, the split index, while the shared index file contains
all index entries and stays unchanged.

All changes in the split index are pushed back to the shared index
file when the number of entries in the split index reaches a level
specified by the splitIndex.maxPercentChange config variable (see
linkgit:git-config[1]).

Each time a new shared index file is created, the old shared index
files are deleted if their modification time is older than what is
specified by the splitIndex.sharedIndexExpire config variable (see
linkgit:git-config[1]).

To avoid deleting a shared index file that is still used, its
modification time is updated to the current time everytime a new split
index based on the shared index file is either created or read from.

Untracked cache
---------------

Expand Down
17 changes: 3 additions & 14 deletions builtin/gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,6 @@ static void report_pack_garbage(unsigned seen_bits, const char *path)
string_list_append(&pack_garbage, path);
}

static void git_config_date_string(const char *key, const char **output)
{
if (git_config_get_string_const(key, output))
return;
if (strcmp(*output, "now")) {
unsigned long now = approxidate("now");
if (approxidate(*output) >= now)
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
}
}

static void process_log_file(void)
{
struct stat st;
Expand Down Expand Up @@ -131,9 +120,9 @@ static void gc_config(void)
git_config_get_int("gc.auto", &gc_auto_threshold);
git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit);
git_config_get_bool("gc.autodetach", &detach_auto);
git_config_date_string("gc.pruneexpire", &prune_expire);
git_config_date_string("gc.worktreepruneexpire", &prune_worktrees_expire);
git_config_date_string("gc.logexpiry", &gc_log_expire);
git_config_get_expiry("gc.pruneexpire", &prune_expire);
git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
git_config_get_expiry("gc.logexpiry", &gc_log_expire);

git_config(git_default_config, NULL);
}
Expand Down
25 changes: 14 additions & 11 deletions builtin/update-index.c
Original file line number Diff line number Diff line change
Expand Up @@ -1099,17 +1099,20 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
}

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

switch (untracked_cache) {
Expand Down
8 changes: 8 additions & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -1270,6 +1270,9 @@ extern int has_pack_index(const unsigned char *sha1);

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

/* Helper to check and "touch" a file */
extern int check_and_freshen_file(const char *fn, int freshen);

extern const signed char hexval_table[256];
static inline unsigned int hexval(unsigned char c)
{
Expand Down Expand Up @@ -1956,6 +1959,11 @@ extern int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest);
extern int git_config_get_maybe_bool(const char *key, int *dest);
extern int git_config_get_pathname(const char *key, const char **dest);
extern int git_config_get_untracked_cache(void);
extern int git_config_get_split_index(void);
extern int git_config_get_max_percent_split_change(void);

/* This dies if the configured or default date is in the future */
extern int git_config_get_expiry(const char *key, const char **output);

/*
* This is a hack for test programs like test-dump-untracked-cache to
Expand Down
42 changes: 40 additions & 2 deletions config.c
Original file line number Diff line number Diff line change
Expand Up @@ -1803,6 +1803,19 @@ int git_config_get_pathname(const char *key, const char **dest)
return ret;
}

int git_config_get_expiry(const char *key, const char **output)
{
int ret = git_config_get_string_const(key, output);
if (ret)
return ret;
if (strcmp(*output, "now")) {
unsigned long now = approxidate("now");
if (approxidate(*output) >= now)
git_die_config(key, _("Invalid %s: '%s'"), key, *output);
}
return ret;
}

int git_config_get_untracked_cache(void)
{
int val = -1;
Expand All @@ -1819,14 +1832,39 @@ int git_config_get_untracked_cache(void)
if (!strcasecmp(v, "keep"))
return -1;

error("unknown core.untrackedCache value '%s'; "
"using 'keep' default value", v);
error(_("unknown core.untrackedCache value '%s'; "
"using 'keep' default value"), v);
return -1;
}

return -1; /* default value */
}

int git_config_get_split_index(void)
{
int val;

if (!git_config_get_maybe_bool("core.splitindex", &val))
return val;

return -1; /* default value */
}

int git_config_get_max_percent_split_change(void)
{
int val = -1;

if (!git_config_get_int("splitindex.maxpercentchange", &val)) {
if (0 <= val && val <= 100)
return val;

return error(_("splitIndex.maxPercentChange value '%d' "
"should be between 0 and 100"), val);
}

return -1; /* default value */
}

NORETURN
void git_die_config_linenr(const char *key, const char *filename, int linenr)
{
Expand Down

0 comments on commit 94c9b5a

Please sign in to comment.