-
Notifications
You must be signed in to change notification settings - Fork 191
[RFC] Sparse Index #847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[RFC] Sparse Index #847
Changes from all commits
3c31623
ebbe856
b3696c8
e3b169c
e1e2f2b
8bbd1cd
175c3c6
80aac5b
dcdc9f2
9cd38fb
09893b4
9b2ae1b
d15f67c
54ca484
71b33bb
45cf57c
036653c
30e3685
fc2d0da
ba8e255
dfbafbd
b40872d
6b9f935
926a2e1
e245703
5f53b08
05e7548
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -45,6 +45,20 @@ To avoid interfering with other worktrees, it first enables the | |
| When `--cone` is provided, the `core.sparseCheckoutCone` setting is | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this): |
||
| also set, allowing for better performance with a limited set of | ||
| patterns (see 'CONE PATTERN SET' below). | ||
| + | ||
| Use the `--[no-]sparse-index` option to toggle the use of the sparse | ||
| index format. This reduces the size of the index to be more closely | ||
| aligned with your sparse-checkout definition. This can have significant | ||
| performance advantages for commands such as `git status` or `git add`. | ||
| This feature is still experimental. Some commands might be slower with | ||
| a sparse index until they are properly integrated with the feature. | ||
| + | ||
| **WARNING:** Using a sparse index requires modifying the index in a way | ||
| that is not completely understood by other tools. Enabling sparse index | ||
| enables the `extensions.spareseIndex` config value, which might cause | ||
| other tools to stop working with your repository. If you have trouble with | ||
| this compatibility, then run `git sparse-checkout sparse-index disable` to | ||
| remove this config and rewrite your index to not be sparse. | ||
|
|
||
| 'set':: | ||
| Write a set of patterns to the sparse-checkout file, as given as | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3523,6 +3523,8 @@ static int load_current(struct apply_state *state, | |
| if (!patch->is_new) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this): |
||
| BUG("patch to %s is not a creation", patch->old_name); | ||
|
|
||
| ensure_full_index(state->repo->index); | ||
|
|
||
| pos = index_name_pos(state->repo->index, name, strlen(name)); | ||
| if (pos < 0) | ||
| return error(_("%s: does not exist in index"), name); | ||
|
|
@@ -3692,7 +3694,11 @@ static int check_preimage(struct apply_state *state, | |
| } | ||
|
|
||
| if (state->check_index && !previous) { | ||
| int pos = index_name_pos(state->repo->index, old_name, | ||
| int pos; | ||
|
|
||
| ensure_full_index(state->repo->index); | ||
|
|
||
| pos = index_name_pos(state->repo->index, old_name, | ||
| strlen(old_name)); | ||
| if (pos < 0) { | ||
| if (patch->is_new < 0) | ||
|
|
@@ -3751,6 +3757,8 @@ static int check_to_create(struct apply_state *state, | |
| if (state->check_index && (!ok_if_exists || !state->cached)) { | ||
| int pos; | ||
|
|
||
| ensure_full_index(state->repo->index); | ||
|
|
||
| pos = index_name_pos(state->repo->index, new_name, strlen(new_name)); | ||
| if (pos >= 0) { | ||
| struct cache_entry *ce = state->repo->index->cache[pos]; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -491,6 +491,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) | |
| add_new_files = !take_worktree_changes && !refresh_only && !add_renormalize; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): |
||
| require_pathspec = !(take_worktree_changes || (0 < addremove_explicit)); | ||
|
|
||
| prepare_repo_settings(the_repository); | ||
| the_repository->settings.command_requires_full_index = 0; | ||
|
|
||
| hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); | ||
|
|
||
| /* | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -14,6 +14,7 @@ | |
| #include "unpack-trees.h" | ||
| #include "wt-status.h" | ||
| #include "quote.h" | ||
| #include "sparse-index.h" | ||
|
|
||
| static const char *empty_base = ""; | ||
|
|
||
|
|
@@ -110,6 +111,8 @@ static int update_working_directory(struct pattern_list *pl) | |
| if (is_index_unborn(r->index)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this): |
||
| return UPDATE_SPARSITY_SUCCESS; | ||
|
|
||
| r->index->sparse_checkout_patterns = pl; | ||
|
|
||
| memset(&o, 0, sizeof(o)); | ||
| o.verbose_update = isatty(2); | ||
| o.update = 1; | ||
|
|
@@ -120,6 +123,7 @@ static int update_working_directory(struct pattern_list *pl) | |
| o.pl = pl; | ||
|
|
||
| setup_work_tree(); | ||
| ensure_full_index(r->index); | ||
|
|
||
| repo_hold_locked_index(r, &lock_file, LOCK_DIE_ON_ERROR); | ||
|
|
||
|
|
@@ -138,6 +142,7 @@ static int update_working_directory(struct pattern_list *pl) | |
| else | ||
| rollback_lock_file(&lock_file); | ||
|
|
||
| r->index->sparse_checkout_patterns = NULL; | ||
| return result; | ||
| } | ||
|
|
||
|
|
@@ -280,12 +285,13 @@ static int set_config(enum sparse_checkout_mode mode) | |
| } | ||
|
|
||
| static char const * const builtin_sparse_checkout_init_usage[] = { | ||
| N_("git sparse-checkout init [--cone]"), | ||
| N_("git sparse-checkout init [--cone] [--[no-]sparse-index]"), | ||
| NULL | ||
| }; | ||
|
|
||
| static struct sparse_checkout_init_opts { | ||
| int cone_mode; | ||
| int sparse_index; | ||
| } init_opts; | ||
|
|
||
| static int sparse_checkout_init(int argc, const char **argv) | ||
|
|
@@ -300,11 +306,15 @@ static int sparse_checkout_init(int argc, const char **argv) | |
| static struct option builtin_sparse_checkout_init_options[] = { | ||
| OPT_BOOL(0, "cone", &init_opts.cone_mode, | ||
| N_("initialize the sparse-checkout in cone mode")), | ||
| OPT_BOOL(0, "sparse-index", &init_opts.sparse_index, | ||
| N_("toggle the use of a sparse index")), | ||
| OPT_END(), | ||
| }; | ||
|
|
||
| repo_read_index(the_repository); | ||
|
|
||
| init_opts.sparse_index = -1; | ||
|
|
||
| argc = parse_options(argc, argv, NULL, | ||
| builtin_sparse_checkout_init_options, | ||
| builtin_sparse_checkout_init_usage, 0); | ||
|
|
@@ -323,6 +333,15 @@ static int sparse_checkout_init(int argc, const char **argv) | |
| sparse_filename = get_sparse_checkout_filename(); | ||
| res = add_patterns_from_file_to_list(sparse_filename, "", 0, &pl, NULL); | ||
|
|
||
| if (init_opts.sparse_index >= 0) { | ||
| if (set_sparse_index_config(the_repository, init_opts.sparse_index) < 0) | ||
| die(_("failed to modify sparse-index config")); | ||
|
|
||
| /* force an index rewrite */ | ||
| repo_read_index(the_repository); | ||
| the_repository->index->updated_workdir = 1; | ||
| } | ||
|
|
||
| /* If we already have a sparse-checkout file, use it. */ | ||
| if (res >= 0) { | ||
| free(sparse_filename); | ||
|
|
@@ -517,19 +536,18 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m) | |
| { | ||
| int result; | ||
| int changed_config = 0; | ||
| struct pattern_list pl; | ||
| memset(&pl, 0, sizeof(pl)); | ||
| struct pattern_list *pl = xcalloc(1, sizeof(*pl)); | ||
|
|
||
| switch (m) { | ||
| case ADD: | ||
| if (core_sparse_checkout_cone) | ||
| add_patterns_cone_mode(argc, argv, &pl); | ||
| add_patterns_cone_mode(argc, argv, pl); | ||
| else | ||
| add_patterns_literal(argc, argv, &pl); | ||
| add_patterns_literal(argc, argv, pl); | ||
| break; | ||
|
|
||
| case REPLACE: | ||
| add_patterns_from_input(&pl, argc, argv); | ||
| add_patterns_from_input(pl, argc, argv); | ||
| break; | ||
| } | ||
|
|
||
|
|
@@ -539,12 +557,13 @@ static int modify_pattern_list(int argc, const char **argv, enum modify_type m) | |
| changed_config = 1; | ||
| } | ||
|
|
||
| result = write_patterns_and_update(&pl); | ||
| result = write_patterns_and_update(pl); | ||
|
|
||
| if (result && changed_config) | ||
| set_config(MODE_NO_PATTERNS); | ||
|
|
||
| clear_pattern_list(&pl); | ||
| clear_pattern_list(pl); | ||
| free(pl); | ||
| return result; | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,7 @@ | |
| #include "object-store.h" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Derrick Stolee wrote (reply to this): There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the Git mailing list, Elijah Newren wrote (reply to this): |
||
| #include "replace-object.h" | ||
| #include "promisor-remote.h" | ||
| #include "sparse-index.h" | ||
|
|
||
| #ifndef DEBUG_CACHE_TREE | ||
| #define DEBUG_CACHE_TREE 0 | ||
|
|
@@ -255,6 +256,24 @@ static int update_one(struct cache_tree *it, | |
|
|
||
| *skip_count = 0; | ||
|
|
||
| /* | ||
| * If the first entry of this region is a sparse directory | ||
| * entry corresponding exactly to 'base', then this cache_tree | ||
| * struct is a "leaf" in the data structure, pointing to the | ||
| * tree OID specified in the entry. | ||
| */ | ||
| if (entries > 0) { | ||
| const struct cache_entry *ce = cache[0]; | ||
|
|
||
| if (S_ISSPARSEDIR(ce) && | ||
| ce->ce_namelen == baselen && | ||
| !strncmp(ce->name, base, baselen)) { | ||
| it->entry_count = 1; | ||
| oidcpy(&it->oid, &ce->oid); | ||
| return 1; | ||
| } | ||
| } | ||
|
|
||
| if (0 <= it->entry_count && has_object_file(&it->oid)) | ||
| return it->entry_count; | ||
|
|
||
|
|
@@ -442,6 +461,8 @@ int cache_tree_update(struct index_state *istate, int flags) | |
| if (i) | ||
| return i; | ||
|
|
||
| ensure_full_index(istate); | ||
|
|
||
| if (!istate->cache_tree) | ||
| istate->cache_tree = cache_tree(); | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On the Git mailing list, Elijah Newren wrote (reply to this):