Inter-revision diff: patch 4

Comparing v2 (message) to v4 (message)

--- v2
+++ v4
@@ -1,60 +1,77 @@
 From: Derrick Stolee <dstolee@microsoft.com>
 
-When walking trees using traverse_trees_recursive() and
-unpack_callback(), we must not attempt to walk into a sparse directory
-entry. There are no index entries within that directory to compare to
-the tree object at that position, so skip over the entries of that tree.
+Before moving to update 'git status' and 'git add' to work with sparse
+indexes, add an explicit test that ensures the sparse-index works the
+same as a normal sparse-checkout when the worktree contains directories
+and files outside of the sparse cone.
 
-This code is used in many places, so the only way to test it is to start
-removing the command_requres_full_index option from one builtin at a
-time and carefully test that its use of unpack_trees() behaves correctly
-with a sparse-index. Such tests will be added by later changes.
+Specifically, 'folder1/a' is a file in our test repo, but 'folder1' is
+not in the sparse cone. When 'folder1/a' is modified, the file is not
+shown as modified and adding it will fail. This is new behavior as of
+a20f704 (add: warn when asked to update SKIP_WORKTREE entries,
+2021-04-08). Before that change, these adds would be silently ignored.
+
+Untracked files are fine: adding new files both with 'git add .' and
+'git add folder1/' works just as in a full checkout. This may not be
+entirely desirable, but we are not intending to change behavior at the
+moment, only document it. A future change could alter the behavior to
+be more sensible, and this test could be modified to satisfy the new
+expected behavior.
 
 Signed-off-by: Derrick Stolee <dstolee@microsoft.com>
 ---
- unpack-trees.c | 10 ++++++++--
- 1 file changed, 8 insertions(+), 2 deletions(-)
+ t/t1092-sparse-checkout-compatibility.sh | 38 ++++++++++++++++++++++++
+ 1 file changed, 38 insertions(+)
 
-diff --git a/unpack-trees.c b/unpack-trees.c
-index 3af797093095..67777570f829 100644
---- a/unpack-trees.c
-+++ b/unpack-trees.c
-@@ -1256,6 +1256,7 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
- 	struct cache_entry *src[MAX_UNPACK_TREES + 1] = { NULL, };
- 	struct unpack_trees_options *o = info->data;
- 	const struct name_entry *p = names;
-+	unsigned unpack_tree = 1;
+diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh
+index 98257695979a..fba98d5484ae 100755
+--- a/t/t1092-sparse-checkout-compatibility.sh
++++ b/t/t1092-sparse-checkout-compatibility.sh
+@@ -238,6 +238,44 @@ test_expect_success 'add, commit, checkout' '
+ 	test_all_match git checkout -
+ '
  
- 	/* Find first entry with a real name (we could use "mask" too) */
- 	while (!p->mode)
-@@ -1297,12 +1298,16 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
- 					}
- 				}
- 				src[0] = ce;
++test_expect_success 'status/add: outside sparse cone' '
++	init_repos &&
 +
-+				if (S_ISSPARSEDIR(ce->ce_mode))
-+					unpack_tree = 0;
- 			}
- 			break;
- 		}
- 	}
++	# adding a "missing" file outside the cone should fail
++	test_sparse_match test_must_fail git add folder1/a &&
++
++	# folder1 is at HEAD, but outside the sparse cone
++	run_on_sparse mkdir folder1 &&
++	cp initial-repo/folder1/a sparse-checkout/folder1/a &&
++	cp initial-repo/folder1/a sparse-index/folder1/a &&
++
++	test_sparse_match git status &&
++
++	write_script edit-contents <<-\EOF &&
++	echo text >>$1
++	EOF
++	run_on_sparse ../edit-contents folder1/a &&
++	run_on_all ../edit-contents folder1/new &&
++
++	test_sparse_match git status --porcelain=v2 &&
++
++	# This "git add folder1/a" fails with a warning
++	# in the sparse repos, differing from the full
++	# repo. This is intentional.
++	test_sparse_match test_must_fail git add folder1/a &&
++	test_sparse_match test_must_fail git add --refresh folder1/a &&
++	test_all_match git status --porcelain=v2 &&
++
++	test_all_match git add . &&
++	test_all_match git status --porcelain=v2 &&
++	test_all_match git commit -m folder1/new &&
++
++	run_on_all ../edit-contents folder1/newer &&
++	test_all_match git add folder1/ &&
++	test_all_match git status --porcelain=v2 &&
++	test_all_match git commit -m folder1/newer
++'
++
+ test_expect_success 'checkout and reset --hard' '
+ 	init_repos &&
  
--	if (unpack_nondirectories(n, mask, dirmask, src, names, info) < 0)
-+	if (unpack_tree &&
-+	    unpack_nondirectories(n, mask, dirmask, src, names, info) < 0)
- 		return -1;
- 
- 	if (o->merge && src[0]) {
-@@ -1332,7 +1337,8 @@ static int unpack_callback(int n, unsigned long mask, unsigned long dirmask, str
- 			}
- 		}
- 
--		if (traverse_trees_recursive(n, dirmask, mask & ~dirmask,
-+		if (unpack_tree &&
-+		    traverse_trees_recursive(n, dirmask, mask & ~dirmask,
- 					     names, info) < 0)
- 			return -1;
- 		return mask;
 -- 
 gitgitgadget
 
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help