git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC PATCH 2/5] unpack-trees: fix accidental loss of user changes

From
Elijah Newren <newren@gmail.com>
Date
Jan 9, 2022, 04:57 UTC
Message-ID
<20220109045732.2497526-3-newren@gmail.com>
In-Reply-To
<20220109045732.2497526-1-newren@gmail.com>

For sparse-checkouts, we don't want unpack-trees to error out on files that are missing from the worktree, so there has traditionally been logic to make it skip the verify_uptodate() check for these. Unfortunately, it was skipping the verify_uptodate() check for files that were expected to *become* SKIP_WORKTREE. For files that were not already SKIP_WORKTREE, that can cause us to later delete the file in apply_sparse_checkout(). Only skip the check for files that were already SKIP_WORKTREE as well to avoid lightly discarding important changes users may have made to files.

Note 1: unpack-trees.c is already a bit complex, and the logic around CE_SKIP_WORKTREE and CE_NEW_SKIP_WORKTREE in that file are no exception. I also tried just replacing CE_NEW_SKIP_WORKTREE with CE_SKIP_WORKTREE in the verify_uptodate() check instead of checking for both flags, and found that it also fixed this bug and passed all the tests. I also attempted to devise a few testcases that might trip either variant of my fix and was unable to find any problems. It may be that just checking CE_SKIP_WORKTREE is a better fix, but I'm not sure. I thought it was a bit safer to strictly reduce the number of cases where we skip the up-to-date check rather than just toggling which kind of cases skip it, and thus went with the current variant of the fix.

Note 2: I also wondered if verify_absent() might have a similar bug, but despite my attempts to try to devise a testcase that would trigger such a thing, I couldn't find any problematic testcases. Thus, this patch makes no attempt to apply similar changes to verify_absent() and verify_absent_if_directory().

Signed-off-by: Elijah Newren <newren@gmail.com>
---
 t/t1011-read-tree-sparse-checkout.sh | 2 +-
 unpack-trees.c                       | 4 +++-
 2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh
index 1b2395b8a8..4ed0885bf2 100755
--- a/t/t1011-read-tree-sparse-checkout.sh
+++ b/t/t1011-read-tree-sparse-checkout.sh
@@ -197,7 +197,7 @@ test_expect_success 'read-tree will not throw away dirty changes, non-sparse' '
 	grep -q dirty init.t
 '
 
-test_expect_failure 'read-tree will not throw away dirty changes, sparse' '
+test_expect_success 'read-tree will not throw away dirty changes, sparse' '
 	echo "/*" >.git/info/sparse-checkout &&
 	read_tree_u_must_succeed -m -u HEAD &&
 
diff --git a/unpack-trees.c b/unpack-trees.c
index 98e2f2e0e6..6d9d89c662 100644
--- a/unpack-trees.c
+++ b/unpack-trees.c
@@ -2059,7 +2059,9 @@ static int verify_uptodate_1(const struct cache_entry *ce,
 int verify_uptodate(const struct cache_entry *ce,
 		    struct unpack_trees_options *o)
 {
-	if (!o->skip_sparse_checkout && (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
+	if (!o->skip_sparse_checkout &&
+	    (ce->ce_flags & CE_SKIP_WORKTREE) &&
+	    (ce->ce_flags & CE_NEW_SKIP_WORKTREE))
 		return 0;
 	return verify_uptodate_1(ce, o, ERROR_NOT_UPTODATE_FILE);
 }
-- 
2.34.1.442.ge63c19bdd2.dirty
Previous: Elijah NewrenNext: Elijah Newren
Message 3 of 11 in “Remove the present-despite-SKIP_WORKTREE class of bugs”
  1. 0/5 Remove the present-despite-SKIP_WORKTREE class of bugsElijah Newren, Jan 9, 2022
  2. 1/5 t1011: add testcase demonstrating accidental loss of user modificationsElijah Newren, Jan 9, 2022
  3. 2/5 unpack-trees: fix accidental loss of user changesElijah Newren, Jan 9, 2022
  4. 3/5 repo_read_index: ensure SKIP_WORKTREE means skip worktreeElijah Newren, Jan 9, 2022
  5. Victoria DyeJan 10, 2022
  6. Elijah NewrenJan 11, 2022
  7. Victoria DyeJan 11, 2022
  8. 4/5 Update documentation related to sparsity and the skip-worktree bitElijah Newren, Jan 9, 2022
  9. 5/5 Accelerate ensure_skip_worktree_means_skip_worktree by cachingElijah Newren, Jan 9, 2022
  10. Victoria DyeJan 11, 2022
  11. Elijah NewrenJan 11, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.