Browse Source

read-tree: make three-way merge sparse-aware

Enable use of 'merged_sparse_dir' in 'threeway_merge'. As with two-way
merge, the contents of each conflicted sparse directory are merged without
referencing the index, avoiding sparse index expansion.

As with two-way merge, the 't/t1092-sparse-checkout-compatibility.sh' test
'read-tree --merge with edit/edit conflicts in sparse directories' confirms
that three-way merges with edit/edit changes (both with and without
conflicts) inside a sparse directory result in the correct index state or
error message. To ensure the index is not unnecessarily expanded, add
three-way merge cases to 'sparse index is not expanded: read-tree'.

Signed-off-by: Victoria Dye <vdye@github.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Victoria Dye 3 years ago committed by Junio C Hamano
parent
commit
f27c170f64
  1. 5
      builtin/read-tree.c
  2. 4
      t/t1092-sparse-checkout-compatibility.sh
  3. 34
      unpack-trees.c

5
builtin/read-tree.c

@ -234,11 +234,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix) @@ -234,11 +234,6 @@ int cmd_read_tree(int argc, const char **argv, const char *cmd_prefix)
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;
}

4
t/t1092-sparse-checkout-compatibility.sh

@ -1413,7 +1413,9 @@ test_expect_success 'sparse index is not expanded: read-tree' ' @@ -1413,7 +1413,9 @@ 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 "base update-folder2" \
for MERGE_TREES in "base HEAD update-folder2" \
"base HEAD rename-base" \
"base update-folder2" \
"base rename-base" \
"update-folder2"
do

34
unpack-trees.c

@ -2643,16 +2643,24 @@ int threeway_merge(const struct cache_entry * const *stages, @@ -2643,16 +2643,24 @@ int threeway_merge(const struct cache_entry * const *stages,
*/
/* #14, #14ALT, #2ALT */
if (remote && !df_conflict_head && head_match && !remote_match) {
if (index && !same(index, remote) && !same(index, head))
return reject_merge(index, o);
if (index && !same(index, remote) && !same(index, head)) {
if (S_ISSPARSEDIR(index->ce_mode))
return merged_sparse_dir(stages, 4, o);
else
return reject_merge(index, o);
}
return merged_entry(remote, index, o);
}
/*
* If we have an entry in the index cache, then we want to
* make sure that it matches head.
*/
if (index && !same(index, head))
return reject_merge(index, o);
if (index && !same(index, head)) {
if (S_ISSPARSEDIR(index->ce_mode))
return merged_sparse_dir(stages, 4, o);
else
return reject_merge(index, o);
}

if (head) {
/* #5ALT, #15 */
@ -2714,11 +2722,21 @@ int threeway_merge(const struct cache_entry * const *stages, @@ -2714,11 +2722,21 @@ int threeway_merge(const struct cache_entry * const *stages,

}

/* Below are "no merge" cases, which require that the index be
* up-to-date to avoid the files getting overwritten with
* conflict resolution files.
*/
/* Handle "no merge" cases (see t/t1000-read-tree-m-3way.sh) */
if (index) {
/*
* If we've reached the "no merge" cases and we're merging
* a sparse directory, we may have an "edit/edit" conflict that
* can be resolved by individually merging directory contents.
*/
if (S_ISSPARSEDIR(index->ce_mode))
return merged_sparse_dir(stages, 4, o);

/*
* If we're not merging a sparse directory, ensure the index is
* up-to-date to avoid files getting overwritten with conflict
* resolution files
*/
if (verify_uptodate(index, o))
return -1;
}

Loading…
Cancel
Save