* [PATCH v4 10/22] config: add git_config_get_max_percent_split_change()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This new function will be used in a following commit to get the
value of the "splitIndex.maxPercentChange" config variable.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
cache.h | 1 +
config.c | 15 +++++++++++++++
2 files changed, 16 insertions(+)
diff --git a/cache.h b/cache.h
index 014aa7ea11..955e80913e 100644
--- a/cache.h
+++ b/cache.h
@@ -1883,6 +1883,7 @@ 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 is a hack for test programs like test-dump-untracked-cache to
diff --git a/config.c b/config.c
index 2a97696be7..35b6f02960 100644
--- a/config.c
+++ b/config.c
@@ -1746,6 +1746,21 @@ int git_config_get_split_index(void)
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)
{
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 11/22] read-cache: regenerate shared index if necessary
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
When writing a new split-index and there is a big number of cache
entries in the split-index compared to the shared index, it is a
good idea to regenerate the shared index.
By default when the ratio reaches 20%, we will push back all
the entries from the split-index into a new shared index file
instead of just creating a new split-index file.
The threshold can be configured using the
"splitIndex.maxPercentChange" config variable.
We need to adjust the existing tests in t1700 by setting
"splitIndex.maxPercentChange" to 100 at the beginning of t1700,
as the existing tests are assuming that the shared index is
regenerated only when `git update-index --split-index` is used.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 32 ++++++++++++++++++++++++++++++++
t/t1700-split-index.sh | 1 +
2 files changed, 33 insertions(+)
diff --git a/read-cache.c b/read-cache.c
index 99bc274b8d..aeb413a508 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2212,6 +2212,36 @@ static int write_shared_index(struct index_state *istate,
return ret;
}
+static const int default_max_percent_split_change = 20;
+
+static int too_many_not_shared_entries(struct index_state *istate)
+{
+ int i, not_shared = 0;
+ int max_split = git_config_get_max_percent_split_change();
+
+ switch (max_split) {
+ case -1:
+ /* not or badly configured: use the default value */
+ max_split = default_max_percent_split_change;
+ break;
+ case 0:
+ return 1; /* 0% means always write a new shared index */
+ case 100:
+ return 0; /* 100% means never write a new shared index */
+ default:
+ break; /* just use the configured value */
+ }
+
+ /* Count not shared entries */
+ for (i = 0; i < istate->cache_nr; i++) {
+ struct cache_entry *ce = istate->cache[i];
+ if (!ce->index)
+ not_shared++;
+ }
+
+ return (int64_t)istate->cache_nr * max_split < (int64_t)not_shared * 100;
+}
+
int write_locked_index(struct index_state *istate, struct lock_file *lock,
unsigned flags)
{
@@ -2229,6 +2259,8 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
if ((v & 15) < 6)
istate->cache_changed |= SPLIT_INDEX_ORDERED;
}
+ if (too_many_not_shared_entries(istate))
+ istate->cache_changed |= SPLIT_INDEX_ORDERED;
if (istate->cache_changed & SPLIT_INDEX_ORDERED) {
int ret = write_shared_index(istate, lock, flags);
if (ret)
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 1659986d8d..df19b812fd 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -8,6 +8,7 @@ test_description='split index mode tests'
sane_unset GIT_TEST_SPLIT_INDEX
test_expect_success 'enable split index' '
+ git config splitIndex.maxPercentChange 100 &&
git update-index --split-index &&
test-dump-split-index .git/index >actual &&
indexversion=$(test-index-version <.git/index) &&
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 05/22] read-cache: add and then use tweak_split_index()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This will make us use the split-index feature or not depending
on the value of the "core.splitIndex" config variable.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/read-cache.c b/read-cache.c
index 9054369dd0..99bc274b8d 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1558,10 +1558,27 @@ static void tweak_untracked_cache(struct index_state *istate)
}
}
+static void tweak_split_index(struct index_state *istate)
+{
+ switch (git_config_get_split_index()) {
+ case -1: /* unset: do nothing */
+ break;
+ case 0: /* false */
+ remove_split_index(istate);
+ break;
+ case 1: /* true */
+ add_split_index(istate);
+ break;
+ default: /* unknown value: do nothing */
+ break;
+ }
+}
+
static void post_read_index_from(struct index_state *istate)
{
check_ce_order(istate);
tweak_untracked_cache(istate);
+ tweak_split_index(istate);
}
/* remember to discard_cache() before reading a different cache! */
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 06/22] update-index: warn in case of split-index incoherency
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
When users are using `git update-index --(no-)split-index`, they
may expect the split-index feature to be used or not according to
the option they just used, but this might not be the case if the
new "core.splitIndex" config variable has been set. In this case
let's warn about what will happen and why.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/update-index.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/builtin/update-index.c b/builtin/update-index.c
index 24fdadfa4b..d74d72cc7f 100644
--- a/builtin/update-index.c
+++ b/builtin/update-index.c
@@ -1099,12 +1099,21 @@ int cmd_update_index(int argc, const char **argv, const char *prefix)
}
if (split_index > 0) {
+ 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)
+ } 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) {
case UC_UNSPECIFIED:
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 07/22] t1700: add tests for core.splitIndex
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t1700-split-index.sh | 37 +++++++++++++++++++++++++++++++++++++
1 file changed, 37 insertions(+)
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index cb68b8dc1e..1659986d8d 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -200,4 +200,41 @@ test_expect_success 'unify index, two files remain' '
test_cmp expect actual
'
+test_expect_success 'set core.splitIndex config variable to true' '
+ git config core.splitIndex true &&
+ : >three &&
+ git update-index --add three &&
+ git ls-files --stage >ls-files.actual &&
+ cat >ls-files.expect <<-EOF &&
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 three
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
+ EOF
+ test_cmp ls-files.expect ls-files.actual &&
+ BASE=$(test-dump-split-index .git/index | grep "^base") &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'set core.splitIndex config variable to false' '
+ git config core.splitIndex false &&
+ git update-index --force-remove three &&
+ git ls-files --stage >ls-files.actual &&
+ cat >ls-files.expect <<-EOF &&
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 one
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 two
+ EOF
+ test_cmp ls-files.expect ls-files.actual &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ not a split index
+ EOF
+ test_cmp expect actual
+'
+
test_done
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 08/22] Documentation/config: add information for core.splitIndex
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/config.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 015346c417..61a863adeb 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -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
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 09/22] Documentation/git-update-index: talk about core.splitIndex config var
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/git-update-index.txt | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index 7386c93162..e091b2a409 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -171,6 +171,12 @@ may not support it yet.
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.
++
+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::
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 00/22] Add configuration options for split-index
From: Christian Couder @ 2017-02-27 17:59 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
Goal
~~~~
We want to make it possible to use the split-index feature
automatically by just setting a new "core.splitIndex" configuration
variable to true.
This can be valuable as split-index can help significantly speed up
`git rebase` especially along with the work to libify `git apply`
that has been merged to master
(see https://github.com/git/git/commit/81358dc238372793b1590efa149cc1581d1fbd98)
and is now in v2.11.
Design
~~~~~~
The design is similar as the previous work that introduced
"core.untrackedCache".
The new "core.splitIndex" configuration option can be either true,
false or undefined which is the default.
When it is true, the split index is created, if it does not already
exists, when the index is read. When it is false, the split index is
removed if it exists, when the index is read. Otherwise it is left as
is.
Along with this new configuration variable, the two following options
are also introduced:
- splitIndex.maxPercentChange
This is to avoid having too many changes accumulating in the split
index while in split index mode. The git-update-index
documentation says:
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.
but it is probably better to not expect the user to think about it
and to have a mechanism that pushes back all changes to the shared
index file automatically when some threshold is reached.
The default threshold is when the number of entries in the split
index file reaches 20% of the number of entries in the shared
index file. The new "splitIndex.maxPercentChange" config option
lets people tweak this value.
- splitIndex.sharedIndexExpire
To make sure that old sharedindex files are eventually removed
when a new one has been created, we "touch" the shared index file
every time a split index file using the shared index file is
either created or read from. Then we can delete shared indexes
with an mtime older than one week (by default), when we create a
new shared index file. The new "splitIndex.sharedIndexExpire"
config option lets people tweak this grace period.
This idea was suggested by Duy in:
https://public-inbox.org/git/CACsJy8BqMFASHf5kJgUh+bd7XG98CafNydE964VJyPXz-emEvA@mail.gmail.com/
and after some experiments, I agree that it is much simpler than
what I thought could be done during our discussion.
Junio also thinks that we have to do "time-based GC" in:
https://public-inbox.org/git/xmqqeg33ccjj.fsf@gitster.mtv.corp.google.com/
Note that this patch series doesn't address a leak when removing a
split-index, but Duy wrote that he has a patch to fix this leak:
https://public-inbox.org/git/CACsJy8AisF2ZVs7JdnVFp5wdskkbVQQQ=DBq5UzE1MOsCfBMtQ@mail.gmail.com/
Highlevel view of the patches in the series
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Except for patch 1/22 and 1/22, there are 3 big steps, one for each
new configuration variable introduced.
There only small differences between this patch series and the v3
patch series sent a few months ago.
- Patch 1/22 marks a message for translation. It is not new and
can be applied separately.
- Patch 2/22 improves the existing indentation style of t1700 by
using different here document style. It is a new preparatory
patch suggested by Junio.
Step 1 is:
- Patches 3/22 to 6/22 introduce the functions that are reading
the "core.splitIndex" configuration variable and tweaking the
split index depending on its value.
- Patch 7/22 adds a few tests for the new feature.
- Patches 8/22 and 9/22 add some documentation for the new
feature.
There is no change since v3 in this step.
Step 2 is:
- Patches 10/22 and 11/22 introduce the functions that are reading
the "splitIndex.maxPercentChange" configuration variable and
regenerating a new shared index file depending on its value.
Patch 11/12 has a few changes suggested by Junio since v3, see
https://public-inbox.org/git/CAP8UFD3_1EN=0EsD12Cew1MuW8yhtPAZw0M_g3wmvKFk-uGXxw@mail.gmail.com/
- Patch 12/22 adds a few tests for the new feature.
- Patch 13/22 add some documentation for the new feature. The
added documentation has been reworded a little bit since v3 as
suggested by Junio.
Step 3 is:
- Patches 14/22 to 17/22 introduce the functions that are reading
the "splitIndex.sharedIndexExpire" configuration variable and
expiring old shared index files depending on its value.
Patch 15/22 has a few changes suggested by Ramsay and Junio in
http://public-inbox.org/git/a1a44640-ff6c-2294-72ac-46322eff8505@ramsayjones.plus.com/
http://public-inbox.org/git/xmqqbmunq6mg.fsf@gitster.mtv.corp.google.com/
The main change is that the new freshen_shared_index() will now
warn if the split-index file has been written but the shared
index file could't be freshened.
Another change is that in 17/22 the new
"splitIndex.sharedIndexExpire" config variable now defaults to
"2.weeks.ago" instead of "one.week.ago" in v3.
- Patch 18/22 adds a few tests for the new feature. It is changed
a bit to account for the change in 17/22.
Also some flakyness in one of the tests has been fixed by using
a 5 second, instead of 1 second, delay, thanks to Ramsay and
Peff, see
http://public-inbox.org/git/818851a6-c3ef-618e-4146-518fbe6bd837@ramsayjones.plus.com/
- Patches 19/22 and 20/22 were new patches in v3. They update the
mtime of the shared index file when a split index based on the
shared index file is read from. 19/22 is a refactoring to make
the actual change in 20/22 easier.
Patch 20/22 has been changed a little bit since v3 to take into
account changes in 17/22.
- Patches 21/22 and 22/22 add some documentation for the new
feature. Patch 21/22 has been changed to avoid using "mtime" as
suggested by Junio.
Links
~~~~~
This patch series is also available here:
https://github.com/chriscool/git/commits/config-split-index
The previous versions were:
RFC: https://github.com/chriscool/git/commits/config-split-index7
v1: https://github.com/chriscool/git/commits/config-split-index72
v2: https://github.com/chriscool/git/commits/config-split-index99
v3: https://github.com/chriscool/git/commits/config-split-index102
On the mailing list the related patch series and discussions were:
RFC: https://public-inbox.org/git/20160711172254.13439-1-chriscool@tuxfamily.org/
v1: https://public-inbox.org/git/20161023092648.12086-1-chriscool@tuxfamily.org/
v2: https://public-inbox.org/git/20161217145547.11748-1-chriscool@tuxfamily.org/
v3: https://public-inbox.org/git/20161226102222.17150-1-chriscool@tuxfamily.org/
Christian Couder (22):
config: mark an error message up for translation
t1700: change here document style
config: add git_config_get_split_index()
split-index: add {add,remove}_split_index() functions
read-cache: add and then use tweak_split_index()
update-index: warn in case of split-index incoherency
t1700: add tests for core.splitIndex
Documentation/config: add information for core.splitIndex
Documentation/git-update-index: talk about core.splitIndex config var
config: add git_config_get_max_percent_split_change()
read-cache: regenerate shared index if necessary
t1700: add tests for splitIndex.maxPercentChange
Documentation/config: add splitIndex.maxPercentChange
sha1_file: make check_and_freshen_file() non static
read-cache: touch shared index files when used
config: add git_config_get_expiry() from gc.c
read-cache: unlink old sharedindex files
t1700: test shared index file expiration
read-cache: refactor read_index_from()
read-cache: use freshen_shared_index() in read_index_from()
Documentation/config: add splitIndex.sharedIndexExpire
Documentation/git-update-index: explain splitIndex.*
Documentation/config.txt | 29 ++++
Documentation/git-update-index.txt | 43 ++++-
builtin/gc.c | 15 +-
builtin/update-index.c | 25 +--
cache.h | 8 +
config.c | 42 ++++-
read-cache.c | 157 ++++++++++++++++--
sha1_file.c | 2 +-
split-index.c | 22 +++
split-index.h | 2 +
t/t1700-split-index.sh | 324 +++++++++++++++++++++++++++----------
11 files changed, 539 insertions(+), 130 deletions(-)
--
2.12.0.22.g0672473d40
^ permalink raw reply
* [PATCH v4 02/22] t1700: change here document style
From: Christian Couder @ 2017-02-27 17:59 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This improves test indentation by getting rid of the outdated
here document style.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t1700-split-index.sh | 170 ++++++++++++++++++++++++-------------------------
1 file changed, 85 insertions(+), 85 deletions(-)
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 292a0720fc..cb68b8dc1e 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -19,12 +19,12 @@ test_expect_success 'enable split index' '
own=8299b0bcd1ac364e5f1d7768efb62fa2da79a339
base=39d890139ee5356c7ef572216cebcd27aa41f9df
fi &&
- cat >expect <<EOF &&
-own $own
-base $base
-replacements:
-deletions:
-EOF
+ cat >expect <<-EOF &&
+ own $own
+ base $base
+ replacements:
+ deletions:
+ EOF
test_cmp expect actual
'
@@ -32,51 +32,51 @@ test_expect_success 'add one file' '
: >one &&
git update-index --add one &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-base $base
-100644 $EMPTY_BLOB 0 one
-replacements:
-deletions:
-EOF
+ cat >expect <<-EOF &&
+ base $base
+ 100644 $EMPTY_BLOB 0 one
+ replacements:
+ deletions:
+ EOF
test_cmp expect actual
'
test_expect_success 'disable split index' '
git update-index --no-split-index &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
BASE=$(test-dump-split-index .git/index | grep "^own" | sed "s/own/base/") &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-not a split index
-EOF
+ cat >expect <<-EOF &&
+ not a split index
+ EOF
test_cmp expect actual
'
test_expect_success 'enable split index again, "one" now belongs to base index"' '
git update-index --split-index &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-$BASE
-replacements:
-deletions:
-EOF
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
test_cmp expect actual
'
@@ -84,18 +84,18 @@ test_expect_success 'modify original file, base index untouched' '
echo modified >one &&
git update-index one &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- q_to_tab >expect <<EOF &&
-$BASE
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
-replacements: 0
-deletions:
-EOF
+ q_to_tab >expect <<-EOF &&
+ $BASE
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ replacements: 0
+ deletions:
+ EOF
test_cmp expect actual
'
@@ -103,54 +103,54 @@ test_expect_success 'add another file, which stays index' '
: >two &&
git update-index --add two &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
-100644 $EMPTY_BLOB 0 two
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ 100644 $EMPTY_BLOB 0 two
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- q_to_tab >expect <<EOF &&
-$BASE
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
-100644 $EMPTY_BLOB 0 two
-replacements: 0
-deletions:
-EOF
+ q_to_tab >expect <<-EOF &&
+ $BASE
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ 100644 $EMPTY_BLOB 0 two
+ replacements: 0
+ deletions:
+ EOF
test_cmp expect actual
'
test_expect_success 'remove file not in base index' '
git update-index --force-remove two &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- q_to_tab >expect <<EOF &&
-$BASE
-100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
-replacements: 0
-deletions:
-EOF
+ q_to_tab >expect <<-EOF &&
+ $BASE
+ 100644 2e0996000b7e9019eabcad29391bf0f5c7702f0b 0Q
+ replacements: 0
+ deletions:
+ EOF
test_cmp expect actual
'
test_expect_success 'remove file in base index' '
git update-index --force-remove one &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-EOF
+ cat >ls-files.expect <<-EOF &&
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-$BASE
-replacements:
-deletions: 0
-EOF
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions: 0
+ EOF
test_cmp expect actual
'
@@ -158,18 +158,18 @@ test_expect_success 'add original file back' '
: >one &&
git update-index --add one &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-$BASE
-100644 $EMPTY_BLOB 0 one
-replacements:
-deletions: 0
-EOF
+ cat >expect <<-EOF &&
+ $BASE
+ 100644 $EMPTY_BLOB 0 one
+ replacements:
+ deletions: 0
+ EOF
test_cmp expect actual
'
@@ -177,26 +177,26 @@ test_expect_success 'add new file' '
: >two &&
git update-index --add two &&
git ls-files --stage >actual &&
- cat >expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-100644 $EMPTY_BLOB 0 two
-EOF
+ cat >expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ 100644 $EMPTY_BLOB 0 two
+ EOF
test_cmp expect actual
'
test_expect_success 'unify index, two files remain' '
git update-index --no-split-index &&
git ls-files --stage >ls-files.actual &&
- cat >ls-files.expect <<EOF &&
-100644 $EMPTY_BLOB 0 one
-100644 $EMPTY_BLOB 0 two
-EOF
+ cat >ls-files.expect <<-EOF &&
+ 100644 $EMPTY_BLOB 0 one
+ 100644 $EMPTY_BLOB 0 two
+ EOF
test_cmp ls-files.expect ls-files.actual &&
test-dump-split-index .git/index | sed "/^own/d" >actual &&
- cat >expect <<EOF &&
-not a split index
-EOF
+ cat >expect <<-EOF &&
+ not a split index
+ EOF
test_cmp expect actual
'
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 12/22] t1700: add tests for splitIndex.maxPercentChange
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t1700-split-index.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index df19b812fd..21f43903f8 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -238,4 +238,76 @@ test_expect_success 'set core.splitIndex config variable to false' '
test_cmp expect actual
'
+test_expect_success 'set core.splitIndex config variable to true' '
+ git config core.splitIndex true &&
+ : >three &&
+ git update-index --add three &&
+ BASE=$(test-dump-split-index .git/index | grep "^base") &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual &&
+ : >four &&
+ git update-index --add four &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 four
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'check behavior with splitIndex.maxPercentChange unset' '
+ git config --unset splitIndex.maxPercentChange &&
+ : >five &&
+ git update-index --add five &&
+ BASE=$(test-dump-split-index .git/index | grep "^base") &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual &&
+ : >six &&
+ git update-index --add six &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ 100644 e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 0 six
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual
+'
+
+test_expect_success 'check splitIndex.maxPercentChange set to 0' '
+ git config splitIndex.maxPercentChange 0 &&
+ : >seven &&
+ git update-index --add seven &&
+ BASE=$(test-dump-split-index .git/index | grep "^base") &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual &&
+ : >eight &&
+ git update-index --add eight &&
+ BASE=$(test-dump-split-index .git/index | grep "^base") &&
+ test-dump-split-index .git/index | sed "/^own/d" >actual &&
+ cat >expect <<-EOF &&
+ $BASE
+ replacements:
+ deletions:
+ EOF
+ test_cmp expect actual
+'
+
test_done
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 14/22] sha1_file: make check_and_freshen_file() non static
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This function will be used in a commit soon, so let's make
it available globally.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
cache.h | 3 +++
sha1_file.c | 2 +-
2 files changed, 4 insertions(+), 1 deletion(-)
diff --git a/cache.h b/cache.h
index 955e80913e..6b25b50aab 100644
--- a/cache.h
+++ b/cache.h
@@ -1229,6 +1229,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)
{
diff --git a/sha1_file.c b/sha1_file.c
index ec957db5e1..192073ea95 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -593,7 +593,7 @@ static int freshen_file(const char *fn)
* either does not exist on disk, or has a stale mtime and may be subject to
* pruning).
*/
-static int check_and_freshen_file(const char *fn, int freshen)
+int check_and_freshen_file(const char *fn, int freshen)
{
if (access(fn, F_OK))
return 0;
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 16/22] config: add git_config_get_expiry() from gc.c
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This function will be used in a following commit to get the expiration
time of the shared index files from the config, and it is generic
enough to be put in "config.c".
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
builtin/gc.c | 15 ++-------------
cache.h | 3 +++
config.c | 13 +++++++++++++
3 files changed, 18 insertions(+), 13 deletions(-)
diff --git a/builtin/gc.c b/builtin/gc.c
index 331f219260..66dff6a8af 100644
--- a/builtin/gc.c
+++ b/builtin/gc.c
@@ -62,17 +62,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;
@@ -111,8 +100,8 @@ 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_get_expiry("gc.pruneexpire", &prune_expire);
+ git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire);
git_config(git_default_config, NULL);
}
diff --git a/cache.h b/cache.h
index 6b25b50aab..8994e7d373 100644
--- a/cache.h
+++ b/cache.h
@@ -1888,6 +1888,9 @@ 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
* ensure that they do not modify the untracked cache when reading it.
diff --git a/config.c b/config.c
index 35b6f02960..f20d7d88f7 100644
--- a/config.c
+++ b/config.c
@@ -1712,6 +1712,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;
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 19/22] read-cache: refactor read_index_from()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
It looks better and is simpler to review when we don't compute
the same things many times in the function.
It will also help make the following commit simpler.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 45fc831010..3ea20701a3 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1691,6 +1691,8 @@ int read_index_from(struct index_state *istate, const char *path)
{
struct split_index *split_index;
int ret;
+ char *base_sha1_hex;
+ const char *base_path;
/* istate->initialized covers both .git/index and .git/sharedindex.xxx */
if (istate->initialized)
@@ -1708,15 +1710,15 @@ int read_index_from(struct index_state *istate, const char *path)
discard_index(split_index->base);
else
split_index->base = xcalloc(1, sizeof(*split_index->base));
- ret = do_read_index(split_index->base,
- git_path("sharedindex.%s",
- sha1_to_hex(split_index->base_sha1)), 1);
+
+ base_sha1_hex = sha1_to_hex(split_index->base_sha1);
+ base_path = git_path("sharedindex.%s", base_sha1_hex);
+ ret = do_read_index(split_index->base, base_path, 1);
if (hashcmp(split_index->base_sha1, split_index->base->sha1))
die("broken index, expect %s in %s, got %s",
- sha1_to_hex(split_index->base_sha1),
- git_path("sharedindex.%s",
- sha1_to_hex(split_index->base_sha1)),
+ base_sha1_hex, base_path,
sha1_to_hex(split_index->base->sha1));
+
merge_base_index(istate);
post_read_index_from(istate);
return ret;
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 22/22] Documentation/git-update-index: explain splitIndex.*
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/config.txt | 2 +-
Documentation/git-update-index.txt | 37 +++++++++++++++++++++++++++++--------
2 files changed, 30 insertions(+), 9 deletions(-)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 0e9982c5e3..2ccb053d92 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2853,7 +2853,7 @@ splitIndex.sharedIndexExpire::
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
- created based on it.
+ either created based on it or read from it.
See linkgit:git-update-index[1].
status.relativePaths::
diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt
index e091b2a409..1579abf3c3 100644
--- a/Documentation/git-update-index.txt
+++ b/Documentation/git-update-index.txt
@@ -163,14 +163,10 @@ 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
@@ -394,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
---------------
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 20/22] read-cache: use freshen_shared_index() in read_index_from()
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
This way a share index file will not be garbage collected if
we still read from an index it is based from.
As we need to read the current index before creating a new
one, the tests have to be adjusted, so that we don't expect
an old shared index file to be deleted right away when we
create a new one.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 1 +
t/t1700-split-index.sh | 14 +++++++-------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index 3ea20701a3..d1152161f6 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1719,6 +1719,7 @@ int read_index_from(struct index_state *istate, const char *path)
base_sha1_hex, base_path,
sha1_to_hex(split_index->base->sha1));
+ freshen_shared_index(base_sha1_hex, 0);
merge_base_index(istate);
post_read_index_from(istate);
return ret;
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 480d3a8dc3..ea1aeacff0 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -313,17 +313,17 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
test_expect_success 'shared index files expire after 2 weeks by default' '
: >ten &&
git update-index --add ten &&
- test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
just_under_2_weeks_ago=$((5-14*86400)) &&
test-chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
: >eleven &&
git update-index --add eleven &&
- test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
just_over_2_weeks_ago=$((-1-14*86400)) &&
test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
: >twelve &&
git update-index --add twelve &&
- test $(ls .git/sharedindex.* | wc -l) = 1
+ test $(ls .git/sharedindex.* | wc -l) -le 2
'
test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
@@ -331,12 +331,12 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
: >thirteen &&
git update-index --add thirteen &&
- test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
just_over_16_days_ago=$((-1-16*86400)) &&
test-chmtime =$just_over_16_days_ago .git/sharedindex.* &&
: >fourteen &&
git update-index --add fourteen &&
- test $(ls .git/sharedindex.* | wc -l) = 1
+ test $(ls .git/sharedindex.* | wc -l) -le 2
'
test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
@@ -345,13 +345,13 @@ test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"
test-chmtime =$just_10_years_ago .git/sharedindex.* &&
: >fifteen &&
git update-index --add fifteen &&
- test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 2 &&
git config splitIndex.sharedIndexExpire now &&
just_1_second_ago=-1 &&
test-chmtime =$just_1_second_ago .git/sharedindex.* &&
: >sixteen &&
git update-index --add sixteen &&
- test $(ls .git/sharedindex.* | wc -l) = 1
+ test $(ls .git/sharedindex.* | wc -l) -le 2
'
test_done
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* Re: [PATCH 1/5] grep: illustrate bug when recursing with relative pathspec
From: Brandon Williams @ 2017-02-27 18:14 UTC (permalink / raw)
To: Duy Nguyen; +Cc: Git Mailing List, Stefan Beller
In-Reply-To: <CACsJy8Df6hhTzx5BNx385T4cuCg5w3nvOioXB=q+NCoW9kA6_w@mail.gmail.com>
On 02/26, Duy Nguyen wrote:
> On Sat, Feb 25, 2017 at 6:50 AM, Brandon Williams <bmwill@google.com> wrote:
> > When using the --recurse-submodules flag with a relative pathspec which
> > includes "..", an error is produced inside the child process spawned for
> > a submodule. When creating the pathspec struct in the child, the ".."
> > is interpreted to mean "go up a directory" which causes an error stating
> > that the path ".." is outside of the repository.
> >
> > While it is true that ".." is outside the scope of the submodule, it is
> > confusing to a user who originally invoked the command where ".." was
> > indeed still inside the scope of the superproject. Since the child
> > process luanched for the submodule has some context that it is operating
>
> s/luanched/launched/
>
> I would prefer 1/5 t to be merged with 3/5 though. The problem
We can definitely merge them and I agree that it may be easier for
looking through the logs if they are merged.
> description is very light there, and the test demonstration in the
> diff is simply switching from failure to success, which forces the
> reader to come back here. It's easier to find here now, but it'll be a
> bit harder when it enters master and we have to read it from git-log,
> I think.
>
> I'm still munching through the super-prefix patches. From how you
> changed match_pathspec call in 0281e487fd (grep: optionally recurse
> into submodules - 2016-12-16), I guess pathspecs should be handled
> with super-prefix instead of the submodule's prefix (which is empty
> anyway, I guess). The right solution wrt. handling relative paths may
> be teach pathspec about super-prefix (and even original super's cwd)
> then let it processes path in supermodule's context.
>
> Does it handle relative paths with wildcards correctly btw? Ones that
> cross submodules? I have a feeling it doesn't, but I haven't seen how
> exactly super-prefix works yet.
I'm not 100% sure about the relative paths with wildcards. I did notice
that this series solves one problem and introduces another (recursing
from a subdirectory doesn't work with this series) so I need to
rethink the solution a little bit. And I'll take into account wildcards
as well.
>
> There's another problem with passing pathspec from one process to
> another. The issue with preserving the prefix, see 233c3e6c59
> (parse_pathspec: preserve prefix length via PATHSPEC_PREFIX_ORIGIN -
> 2013-07-14). :(icase) needs this because given a path
> "<prefix>/foobar", only the "foobar" part is considered case
> insensitive, the prefix part is always case-sensitive. For example, if
> you have 4 paths "abc/def", "abc/DEF", "ABC/def" and "ABC/DEF" and are
> standing at "abc", you would want ":(icase)def" to match the first two
> only, not all of them.
Hmm...yeah its a really difficult thing to get 100% correct (as I'm now
noticing). It also makes it a little more challenging because you don't
have the same state in both processes (child and parent). I'm thinking
I may have to a little bit more work, which is more involved, to
properly handle the pathspecs passed to the children. As in we may not
be able to pass the raw pathspec used in the parent to the child and
instead may have to do a little pre-processing on it.
> > underneath a superproject, this error could be avoided.
> >
> > Signed-off-by: Brandon Williams <bmwill@google.com>
> > ---
> > t/t7814-grep-recurse-submodules.sh | 42 ++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 42 insertions(+)
> >
> > diff --git a/t/t7814-grep-recurse-submodules.sh b/t/t7814-grep-recurse-submodules.sh
> > index 67247a01d..418ba68fe 100755
> > --- a/t/t7814-grep-recurse-submodules.sh
> > +++ b/t/t7814-grep-recurse-submodules.sh
> > @@ -227,6 +227,48 @@ test_expect_success 'grep history with moved submoules' '
> > test_cmp expect actual
> > '
> >
> > +test_expect_failure 'grep using relative path' '
> > + test_when_finished "rm -rf parent sub" &&
> > + git init sub &&
> > + echo "foobar" >sub/file &&
> > + git -C sub add file &&
> > + git -C sub commit -m "add file" &&
> > +
> > + git init parent &&
> > + echo "foobar" >parent/file &&
> > + git -C parent add file &&
> > + mkdir parent/src &&
> > + echo "foobar" >parent/src/file2 &&
> > + git -C parent add src/file2 &&
> > + git -C parent submodule add ../sub &&
> > + git -C parent commit -m "add files and submodule" &&
> > +
> > + # From top works
> > + cat >expect <<-\EOF &&
> > + file:foobar
> > + src/file2:foobar
> > + sub/file:foobar
> > + EOF
> > + git -C parent grep --recurse-submodules -e "foobar" >actual &&
> > + test_cmp expect actual &&
> > +
> > + # Relative path to top errors out
>
> After 3/5, it's not "errors out" any more, is it?
>
Correct, will fix the comment.
> > + cat >expect <<-\EOF &&
> > + ../file:foobar
> > + file2:foobar
> > + ../sub/file:foobar
> > + EOF
> > + git -C parent/src grep --recurse-submodules -e "foobar" -- .. >actual &&
> > + test_cmp expect actual &&
> > +
> > + # Relative path to submodule errors out
>
> ditto
>
> > + cat >expect <<-\EOF &&
> > + ../sub/file:foobar
> > + EOF
> > + git -C parent/src grep --recurse-submodules -e "foobar" -- ../sub >actual &&
> > + test_cmp expect actual
> > +'
> > +
> > test_incompatible_with_recurse_submodules ()
> > {
> > test_expect_success "--recurse-submodules and $1 are incompatible" "
> > --
> > 2.11.0.483.g087da7b7c-goog
> >
>
>
>
> --
> Duy
--
Brandon Williams
^ permalink raw reply
* Re: [PATCH] strbuf: add strbuf_add_real_path()
From: Brandon Williams @ 2017-02-27 18:22 UTC (permalink / raw)
To: René Scharfe; +Cc: Git List, Junio C Hamano
In-Reply-To: <4d191b86-d36c-e3ec-99c6-d15baa6b659a@web.de>
On 02/25, René Scharfe wrote:
> Add a function for appending the canonized absolute pathname of a given
> path to a strbuf. It keeps the existing contents intact, as expected of
> a function of the strbuf_add() family, while avoiding copying the result
> if the given strbuf is empty. It's more consistent with the rest of the
> strbuf API than strbuf_realpath(), which it's wrapping.
>
> Also add a semantic patch demonstrating its intended usage and apply it
> to the current tree. Using strbuf_add_real_path() instead of calling
> strbuf_addstr() and real_path() avoids an extra copy to a static buffer.
>
Seems like a reasonable thing to do. When I wrote strbuf_realpath() I
think I looked at the strbuf_getcwd() function for what it did (since it
handled paths) and it simply uses the provided buffer disregarding what
is already stored in it.
> Signed-off-by: Rene Scharfe <l.s.r@web.de>
> ---
> contrib/coccinelle/strbuf.cocci | 6 ++++++
> setup.c | 2 +-
> strbuf.c | 11 +++++++++++
> strbuf.h | 14 ++++++++++++++
> 4 files changed, 32 insertions(+), 1 deletion(-)
>
> diff --git a/contrib/coccinelle/strbuf.cocci b/contrib/coccinelle/strbuf.cocci
> index 63995f22ff..1d580e49b0 100644
> --- a/contrib/coccinelle/strbuf.cocci
> +++ b/contrib/coccinelle/strbuf.cocci
> @@ -38,3 +38,9 @@ expression E1, E2, E3;
> @@
> - strbuf_addstr(E1, find_unique_abbrev(E2, E3));
> + strbuf_add_unique_abbrev(E1, E2, E3);
> +
> +@@
> +expression E1, E2;
> +@@
> +- strbuf_addstr(E1, real_path(E2));
> ++ strbuf_add_real_path(E1, E2);
> diff --git a/setup.c b/setup.c
> index 967f289f1e..f14cbcd338 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -254,7 +254,7 @@ int get_common_dir_noenv(struct strbuf *sb, const char *gitdir)
> if (!is_absolute_path(data.buf))
> strbuf_addf(&path, "%s/", gitdir);
> strbuf_addbuf(&path, &data);
> - strbuf_addstr(sb, real_path(path.buf));
> + strbuf_add_real_path(sb, path.buf);
> ret = 1;
> } else {
> strbuf_addstr(sb, gitdir);
> diff --git a/strbuf.c b/strbuf.cq
> index 8fec6579f7..ace58e7367 100644
> --- a/strbuf.c
> +++ b/strbuf.c
> @@ -707,6 +707,17 @@ void strbuf_add_absolute_path(struct strbuf *sb, const char *path)
> strbuf_addstr(sb, path);
> }
>
> +void strbuf_add_real_path(struct strbuf *sb, const char *path)
> +{
> + if (sb->len) {
> + struct strbuf resolved = STRBUF_INIT;
> + strbuf_realpath(&resolved, path, 1);
> + strbuf_addbuf(sb, &resolved);
> + strbuf_release(&resolved);
> + } else
> + strbuf_realpath(sb, path, 1);
I know its not required but I would have braces on the 'else' branch
since they were needed on the 'if' branch. But that's up to you and
your style :)
> +}
> +
> int printf_ln(const char *fmt, ...)
> {
> int ret;
> diff --git a/strbuf.h b/strbuf.h
> index cf1b5409e7..cf8e4bf532 100644
> --- a/strbuf.h
> +++ b/strbuf.h
> @@ -441,6 +441,20 @@ extern int strbuf_getcwd(struct strbuf *sb);
> */
> extern void strbuf_add_absolute_path(struct strbuf *sb, const char *path);
>
> +/**
> + * Canonize `path` (make it absolute, resolve symlinks, remove extra
> + * slashes) and append it to `sb`. Die with an informative error
> + * message if there is a problem.
> + *
> + * The directory part of `path` (i.e., everything up to the last
> + * dir_sep) must denote a valid, existing directory, but the last
> + * component need not exist.
> + *
> + * Callers that don't mind links should use the more lightweight
> + * strbuf_add_absolute_path() instead.
> + */
> +extern void strbuf_add_real_path(struct strbuf *sb, const char *path);
> +
>
> /**
> * Normalize in-place the path contained in the strbuf. See
> --
> 2.12.0
>
--
Brandon Williams
^ permalink raw reply
* [PATCH v4 18/22] t1700: test shared index file expiration
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
t/t1700-split-index.sh | 44 ++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 44 insertions(+)
diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh
index 21f43903f8..480d3a8dc3 100755
--- a/t/t1700-split-index.sh
+++ b/t/t1700-split-index.sh
@@ -310,4 +310,48 @@ test_expect_success 'check splitIndex.maxPercentChange set to 0' '
test_cmp expect actual
'
+test_expect_success 'shared index files expire after 2 weeks by default' '
+ : >ten &&
+ git update-index --add ten &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ just_under_2_weeks_ago=$((5-14*86400)) &&
+ test-chmtime =$just_under_2_weeks_ago .git/sharedindex.* &&
+ : >eleven &&
+ git update-index --add eleven &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ just_over_2_weeks_ago=$((-1-14*86400)) &&
+ test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+ : >twelve &&
+ git update-index --add twelve &&
+ test $(ls .git/sharedindex.* | wc -l) = 1
+'
+
+test_expect_success 'check splitIndex.sharedIndexExpire set to 16 days' '
+ git config splitIndex.sharedIndexExpire "16.days.ago" &&
+ test-chmtime =$just_over_2_weeks_ago .git/sharedindex.* &&
+ : >thirteen &&
+ git update-index --add thirteen &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ just_over_16_days_ago=$((-1-16*86400)) &&
+ test-chmtime =$just_over_16_days_ago .git/sharedindex.* &&
+ : >fourteen &&
+ git update-index --add fourteen &&
+ test $(ls .git/sharedindex.* | wc -l) = 1
+'
+
+test_expect_success 'check splitIndex.sharedIndexExpire set to "never" and "now"' '
+ git config splitIndex.sharedIndexExpire never &&
+ just_10_years_ago=$((-365*10*86400)) &&
+ test-chmtime =$just_10_years_ago .git/sharedindex.* &&
+ : >fifteen &&
+ git update-index --add fifteen &&
+ test $(ls .git/sharedindex.* | wc -l) -gt 1 &&
+ git config splitIndex.sharedIndexExpire now &&
+ just_1_second_ago=-1 &&
+ test-chmtime =$just_1_second_ago .git/sharedindex.* &&
+ : >sixteen &&
+ git update-index --add sixteen &&
+ test $(ls .git/sharedindex.* | wc -l) = 1
+'
+
test_done
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* Re: [PATCH 10/10] submodule--helper clone: check for configured submodules using helper
From: Brandon Williams @ 2017-02-27 18:38 UTC (permalink / raw)
To: Stefan Beller; +Cc: git@vger.kernel.org
In-Reply-To: <CAGZ79kYmmeVOYSPTvAbGpRQn1YL9yjPOkT5xCoSDmtNzQ1t2fw@mail.gmail.com>
On 02/23, Stefan Beller wrote:
> On Thu, Feb 23, 2017 at 3:47 PM, Brandon Williams <bmwill@google.com> wrote:
>
> > @@ -795,14 +794,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
> > }
> >
> > /*
> > - * Looking up the url in .git/config.
> > + * Check if the submodule has been initialized.
> > * We must not fall back to .gitmodules as we only want
> > * to process configured submodules.
>
> This sentence "we must not ..." is also no longer accurate,
> as we do exactly that when using sub->url instead of just url
> below.
You're right, I'll fix that.
--
Brandon Williams
^ permalink raw reply
* Re: [PATCH v5 1/1] config: add conditional include
From: Junio C Hamano @ 2017-02-27 18:42 UTC (permalink / raw)
To: Jeff King; +Cc: Duy Nguyen, Git Mailing List, Sebastian Schuberth, Matthieu Moy
In-Reply-To: <20170226060726.mvdip4vnbdngypzx@sigill.intra.peff.net>
Jeff King <peff@peff.net> writes:
> I don't think driving that with a two-entry table is the right thing
> here. We are as likely to add another "foobar:" entry as we are to add
> another modifier "/i" modifier to "gitdir:", and it is unclear whether
> that modifier would be mutually exclusive with "/i".
OK, I didn't take /i as something that was meant as a modifier; I
took the "gitdir:" and "gitdir/i:" are totally different tests that
are spelled similarly, but for the implementation expediency, called
into a single helper function without having a layer that presents
the same function signature in the middle to make it drivable by a
table.
Let's leave it to the review of a future patch that wants to add a
third condition then. At that time, we will have more things to
look at to make a better decision.
^ permalink raw reply
* [PATCH v4 13/22] Documentation/config: add splitIndex.maxPercentChange
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
Documentation/config.txt | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/Documentation/config.txt b/Documentation/config.txt
index 61a863adeb..8e745bda52 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2831,6 +2831,19 @@ 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].
+
status.relativePaths::
By default, linkgit:git-status[1] shows paths relative to the
current directory. Setting this variable to `false` shows paths
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* Re: [PATCH] gitweb tests: Skip tests when we don't have Time::HiRes
From: Ævar Arnfjörð Bjarmason @ 2017-02-27 18:25 UTC (permalink / raw)
To: Jakub Narębski; +Cc: Git Mailing List, Junio C Hamano
In-Reply-To: <4b34e3a0-3da7-d821-2a7f-9a420ac1d3f6@gmail.com>
On Mon, Feb 27, 2017 at 6:48 PM, Jakub Narębski <jnareb@gmail.com> wrote:
> W dniu 27.02.2017 o 13:37, Ævar Arnfjörð Bjarmason pisze:
>> Change the gitweb tests to skip when we can't load the Time::HiRes
>> module.
>
> Could you tell us in the commit message why this module is needed?
> Is it because gitweb loads it unconditionally, or does that at least
> in the default configuration, or is it used in tests, or...?
>
> [I see it is somewhat addressed below]
>
>>
>> This module has bee in perl core since v5.8, which is the oldest
>
> s/bee/been/
I'll clarify that in a re-roll & fix the typo, pending any other
comments. Thanks!
>> version we support, however CentOS (and perhaps some other
>> distributions) carve it into its own non-core-perl package that's not
>> installed along with /usr/bin/perl by default. Without this we'll hard
>> fail the gitweb tests when trying to load the module.
>
> I see that it because gitweb.perl as the following at line 20:
>
> use Time::HiRes qw(gettimeofday tv_interval);
>
>>
>> Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
>
> Good catch (if a strange one...).
This and the associated cvs tests failing as root patch I submitted
were discovered when trying to build git in the standard mock build
environment on CentOS. It creates a chroot and rpm installs just the
packages you declare, so issues like these crop up.
>> ---
>> t/gitweb-lib.sh | 5 +++++
>> 1 file changed, 5 insertions(+)
>>
>> diff --git a/t/gitweb-lib.sh b/t/gitweb-lib.sh
>> index d5dab5a94f..116c3890e6 100644
>> --- a/t/gitweb-lib.sh
>> +++ b/t/gitweb-lib.sh
>> @@ -114,4 +114,9 @@ perl -MCGI -MCGI::Util -MCGI::Carp -e 0 >/dev/null 2>&1 || {
>> test_done
>> }
>>
>> +perl -mTime::HiRes -e 0 >/dev/null 2>&1 || {
>> + skip_all='skipping gitweb tests, Time::HiRes module unusable'
>
> Is "unusable" a good description, instead of "not found"?
Yeah it's odd, but I just copied the several lines above that use that phrasing.
>> + test_done
>> +}
>> +
>> gitweb_init
>>
>
^ permalink raw reply
* Re: [PATCH 0/5] recursing submodules with relative pathspec (grep and ls-files)
From: Brandon Williams @ 2017-02-27 17:52 UTC (permalink / raw)
To: git; +Cc: sbeller, pclouds
In-Reply-To: <20170224235100.52627-1-bmwill@google.com>
On 02/24, Brandon Williams wrote:
> It was discovered that when using the --recurse-submodules flag with `git grep`
> and `git ls-files` and specifying a relative path when not at the root causes
> the child processes spawned to error out with an error like:
>
> fatal: ..: '..' is outside repository
>
> While true that ".." is outside the scope of the submodule repository, it
> probably doesn't make much sense to the user who gave that pathspec with
> respect to the superproject. Since the child processes that are spawned to
> handle the submodules have some context that they are executing underneath a
> superproject (via the 'super_prefix'), they should be able to prevent dying
> under this circumstance.
>
> This series fixes this bug in both git grep and git ls-files as well as
> correctly formatting the output from submodules to handle the relative paths
> with "..".
>
> One of the changes made to fix this was to add an additional flag for the
> parse_pathspec() function in order to treat all paths provided as being from
> the root of the repository. I hesitantly selected the name 'PATHSPEC_FROMROOT'
> but I'm not fond of it since its too similar to the pathspec magic define
> 'PATHSPEC_FROMTOP'. So I'm open for naming suggestions.
>
> Brandon Williams (5):
> grep: illustrate bug when recursing with relative pathspec
> pathspec: add PATHSPEC_FROMROOT flag
> grep: fix bug when recuring with relative pathspec
> ls-files: illustrate bug when recursing with relative pathspec
> ls-files: fix bug when recuring with relative pathspec
>
> builtin/grep.c | 8 ++++--
> builtin/ls-files.c | 8 ++++--
> pathspec.c | 2 +-
> pathspec.h | 2 ++
> t/t3007-ls-files-recurse-submodules.sh | 50 ++++++++++++++++++++++++++++++++++
> t/t7814-grep-recurse-submodules.sh | 42 ++++++++++++++++++++++++++++
> 6 files changed, 107 insertions(+), 5 deletions(-)
>
Turns out that this series doesn't address all of the issues. This
series also seems to introduce broken behavior when recursing from a
subdirectory. So I need to think about this problem a little bit more
and reroll.
--
Brandon Williams
^ permalink raw reply
* [PATCH v4 15/22] read-cache: touch shared index files when used
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
When a split-index file is created, let's update the mtime of the
shared index file that the split-index file is referencing.
In a following commit we will make shared index file expire
depending on their mtime, so updating the mtime makes sure that
the shared index file will not be deleted soon.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 29 ++++++++++++++++++++++++++---
1 file changed, 26 insertions(+), 3 deletions(-)
diff --git a/read-cache.c b/read-cache.c
index aeb413a508..5f295af4c6 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -1674,6 +1674,19 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
die("index file corrupt");
}
+/*
+ * Signal that the shared index is used by updating its mtime.
+ *
+ * This way, shared index can be removed if they have not been used
+ * for some time.
+ */
+static void freshen_shared_index(char *base_sha1_hex, int warn)
+{
+ const char *shared_index = git_path("sharedindex.%s", base_sha1_hex);
+ if (!check_and_freshen_file(shared_index, 1) && warn)
+ warning("Could not freshen shared index '%s'", shared_index);
+}
+
int read_index_from(struct index_state *istate, const char *path)
{
struct split_index *split_index;
@@ -2245,6 +2258,7 @@ static int too_many_not_shared_entries(struct index_state *istate)
int write_locked_index(struct index_state *istate, struct lock_file *lock,
unsigned flags)
{
+ int new_shared_index, ret;
struct split_index *si = istate->split_index;
if (!si || alternate_index_output ||
@@ -2261,13 +2275,22 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock,
}
if (too_many_not_shared_entries(istate))
istate->cache_changed |= SPLIT_INDEX_ORDERED;
- if (istate->cache_changed & SPLIT_INDEX_ORDERED) {
- int ret = write_shared_index(istate, lock, flags);
+
+ new_shared_index = istate->cache_changed & SPLIT_INDEX_ORDERED;
+
+ if (new_shared_index) {
+ ret = write_shared_index(istate, lock, flags);
if (ret)
return ret;
}
- return write_split_index(istate, lock, flags);
+ ret = write_split_index(istate, lock, flags);
+
+ /* Freshen the shared index only if the split-index was written */
+ if (!ret && !new_shared_index)
+ freshen_shared_index(sha1_to_hex(si->base_sha1), 1);
+
+ return ret;
}
/*
--
2.12.0.22.g0672473d40
^ permalink raw reply related
* [PATCH v4 17/22] read-cache: unlink old sharedindex files
From: Christian Couder @ 2017-02-27 18:00 UTC (permalink / raw)
To: git
Cc: Junio C Hamano, Nguyen Thai Ngoc Duy,
Ævar Arnfjörð Bjarmason, Ramsay Jones, Jeff King,
Christian Couder
In-Reply-To: <20170227180019.18666-1-chriscool@tuxfamily.org>
Everytime split index is turned on, it creates a "sharedindex.XXXX"
file in the git directory. This change makes sure that shared index
files that haven't been used for a long time are removed when a new
shared index file is created.
The new "splitIndex.sharedIndexExpire" config variable is created
to tell the delay after which an unused shared index file can be
deleted. It defaults to "2.weeks.ago".
A previous commit made sure that each time a split index file is
created the mtime of the shared index file it references is updated.
This makes sure that recently used shared index file will not be
deleted.
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
---
read-cache.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 63 insertions(+), 1 deletion(-)
diff --git a/read-cache.c b/read-cache.c
index 5f295af4c6..45fc831010 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -2199,6 +2199,65 @@ static int write_split_index(struct index_state *istate,
return ret;
}
+static const char *shared_index_expire = "2.weeks.ago";
+
+static unsigned long get_shared_index_expire_date(void)
+{
+ static unsigned long shared_index_expire_date;
+ static int shared_index_expire_date_prepared;
+
+ if (!shared_index_expire_date_prepared) {
+ git_config_get_expiry("splitindex.sharedindexexpire",
+ &shared_index_expire);
+ shared_index_expire_date = approxidate(shared_index_expire);
+ shared_index_expire_date_prepared = 1;
+ }
+
+ return shared_index_expire_date;
+}
+
+static int can_delete_shared_index(const char *shared_index_path)
+{
+ struct stat st;
+ unsigned long expiration;
+
+ /* Check timestamp */
+ expiration = get_shared_index_expire_date();
+ if (!expiration)
+ return 0;
+ if (stat(shared_index_path, &st))
+ return error_errno(_("could not stat '%s"), shared_index_path);
+ if (st.st_mtime > expiration)
+ return 0;
+
+ return 1;
+}
+
+static int clean_shared_index_files(const char *current_hex)
+{
+ struct dirent *de;
+ DIR *dir = opendir(get_git_dir());
+
+ if (!dir)
+ return error_errno(_("unable to open git dir: %s"), get_git_dir());
+
+ while ((de = readdir(dir)) != NULL) {
+ const char *sha1_hex;
+ const char *shared_index_path;
+ if (!skip_prefix(de->d_name, "sharedindex.", &sha1_hex))
+ continue;
+ if (!strcmp(sha1_hex, current_hex))
+ continue;
+ shared_index_path = git_path("%s", de->d_name);
+ if (can_delete_shared_index(shared_index_path) > 0 &&
+ unlink(shared_index_path))
+ error_errno(_("unable to unlink: %s"), shared_index_path);
+ }
+ closedir(dir);
+
+ return 0;
+}
+
static struct tempfile temporary_sharedindex;
static int write_shared_index(struct index_state *istate,
@@ -2220,8 +2279,11 @@ static int write_shared_index(struct index_state *istate,
}
ret = rename_tempfile(&temporary_sharedindex,
git_path("sharedindex.%s", sha1_to_hex(si->base->sha1)));
- if (!ret)
+ if (!ret) {
hashcpy(si->base_sha1, si->base->sha1);
+ clean_shared_index_files(sha1_to_hex(si->base->sha1));
+ }
+
return ret;
}
--
2.12.0.22.g0672473d40
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox