From: Victoria Dye <vdye@xxxxxxxxxx> Enable use of sparse index in 'git read-tree'. The integration in this patch is limited only to usage of 'read-tree' that does not need additional functional changes for the sparse index to behave as expected (i.e., produce the same user-facing results as a non-sparse index sparse-checkout). To ensure no unexpected behavior occurs, the index is explicitly expanded when: * '--no-sparse-checkout' is specified (because it disables sparse-checkout) * '--prefix' is specified (if the prefix is inside a sparse directory, the prefixed tree cannot be properly traversed) * two or more <tree-ish> arguments are specified ('twoway_merge' and 'threeway_merge' do not yet support merging sparse directories) Signed-off-by: Victoria Dye <vdye@xxxxxxxxxx> --- builtin/read-tree.c | 21 +++++++++++++++++++-- t/t1092-sparse-checkout-compatibility.sh | 11 +++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/builtin/read-tree.c b/builtin/read-tree.c index c1a401971c2..0a52cab7752 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -160,8 +160,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) argc = parse_options(argc, argv, cmd_prefix, read_tree_options, read_tree_usage, 0); - hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); - prefix_set = opts.prefix ? 1 : 0; if (1 < opts.merge + opts.reset + prefix_set) die("Which one? -m, --reset, or --prefix?"); @@ -173,6 +171,11 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if (opts.reset) opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED; + prepare_repo_settings(the_repository); + the_repository->settings.command_requires_full_index = 0; + + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR); + /* * NEEDSWORK * @@ -214,6 +217,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) if (opts.merge && !opts.index_only) setup_work_tree(); + /* TODO: audit sparse index behavior in unpack_trees */ + if (opts.skip_sparse_checkout || opts.prefix) + ensure_full_index(&the_index); + if (opts.merge) { switch (stage - 1) { case 0: @@ -223,11 +230,21 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) opts.fn = opts.prefix ? bind_merge : oneway_merge; break; case 2: + /* + * TODO: update twoway_merge to handle edit/edit conflicts in + * sparse directories. + */ + ensure_full_index(&the_index); opts.fn = twoway_merge; opts.initial_checkout = is_cache_unborn(); break; case 3: default: + /* + * TODO: update threeway_merge to handle edit/edit conflicts in + * sparse directories. + */ + ensure_full_index(&the_index); opts.fn = threeway_merge; break; } diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 9bb5aeb979c..86241b01a59 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1409,6 +1409,17 @@ test_expect_success 'sparse index is not expanded: fetch/pull' ' ensure_not_expanded pull full base ' +test_expect_success 'sparse index is not expanded: read-tree' ' + init_repos && + + ensure_not_expanded checkout -b test-branch update-folder1 && + for MERGE_TREES in "update-folder2" + do + ensure_not_expanded read-tree -mu $MERGE_TREES && + ensure_not_expanded reset --hard || return 1 + done +' + test_expect_success 'ls-files' ' init_repos && -- gitgitgadget