read-tree: integrate with sparse index

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@github.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Victoria Dye committed Mar 1, 2022 at 20:24 UTC 2c66a7c8cefa27ef56efbc76bdfe13696b9dac3a
2 files changed +30 -2
builtin/read-tree.c
+19 -2
@@ -160,8 +160,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
160 argc = parse_options(argc, argv, cmd_prefix, read_tree_options,
161 read_tree_usage, 0);
162
163 - hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
164 -
163 prefix_set = opts.prefix ? 1 : 0;
164 if (1 < opts.merge + opts.reset + prefix_set)
165 die("Which one? -m, --reset, or --prefix?");
@@ -173,6 +171,11 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
171 if (opts.reset)
172 opts.reset = UNPACK_RESET_OVERWRITE_UNTRACKED;
173
174 + prepare_repo_settings(the_repository);
175 + the_repository->settings.command_requires_full_index = 0;
176 +
177 + hold_locked_index(&lock_file, LOCK_DIE_ON_ERROR);
178 +
179 /*
180 * NEEDSWORK
181 *
@@ -214,6 +217,10 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
217 if (opts.merge && !opts.index_only)
218 setup_work_tree();
219
220 + /* TODO: audit sparse index behavior in unpack_trees */
221 + if (opts.skip_sparse_checkout || opts.prefix)
222 + ensure_full_index(&the_index);
223 +
224 if (opts.merge) {
225 switch (stage - 1) {
226 case 0:
@@ -223,11 +230,21 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
230 opts.fn = opts.prefix ? bind_merge : oneway_merge;
231 break;
232 case 2:
233 + /*
234 + * TODO: update twoway_merge to handle edit/edit conflicts in
235 + * sparse directories.
236 + */
237 + ensure_full_index(&the_index);
238 opts.fn = twoway_merge;
239 opts.initial_checkout = is_cache_unborn();
240 break;
241 case 3:
242 default:
243 + /*
244 + * TODO: update threeway_merge to handle edit/edit conflicts in
245 + * sparse directories.
246 + */
247 + ensure_full_index(&the_index);
248 opts.fn = threeway_merge;
249 break;
250 }
t/t1092-sparse-checkout-compatibility.sh
+11
@@ -1409,6 +1409,17 @@ test_expect_success 'sparse index is not expanded: fetch/pull' '
1409 ensure_not_expanded pull full base
1410 '
1411
1412 +test_expect_success 'sparse index is not expanded: read-tree' '
1413 + init_repos &&
1414 +
1415 + ensure_not_expanded checkout -b test-branch update-folder1 &&
1416 + for MERGE_TREES in "update-folder2"
1417 + do
1418 + ensure_not_expanded read-tree -mu $MERGE_TREES &&
1419 + ensure_not_expanded reset --hard || return 1
1420 + done
1421 +'
1422 +
1423 test_expect_success 'ls-files' '
1424 init_repos &&
1425