[PATCH v2 0/4] fix apply --intent-to-add
From: Raymond E. Pasco <hidden>
Date: 2025-07-02 21:28:36
I've rerolled this taking comments into consideration; I've removed the
first patch, because I'm convinced not erroring out is fine here, and
expanded on the log messages somewhat. I've also fixed an issue where I
was outsmarted by a text editor when writing the test patch.
Raymond E. Pasco (4):
apply: read in the index in --intent-to-add mode
apply: only write intents to add for new files
t4140: test apply --intent-to-add interactions
apply docs: clarify wording for --intent-to-add
Documentation/git-apply.adoc | 9 +++++----
apply.c | 4 ++--
t/t4140-apply-ita.sh | 31 ++++++++++++++++++++++++++++++-
3 files changed, 37 insertions(+), 7 deletions(-)
Range-diff against v1:
1: b1c9ea7cac < -: ---------- apply: error on --intent-to-add outside gitdir
2: 3a422c8124 ! 1: 71ec291fba apply: read in the index in --intent-to-add mode
@@ Commit message
cases, because the index was never read in (in apply, this is done
in read_apply_cache()) before writing to it.
- If we merely gate read_apply_cache() behind update_index, then it will
- not be read when state->apply is false, even if it must be checked.
- Therefore, we instead read the index if it will be either checked or
- updated, because reading the index is a prerequisite to either.
+ This causes the operation to clobber the old, correct index with a
+ new empty-tree index before writing intent-to-add entries to this
+ empty index; the final result is that the index now records every
+ existing file in the repository as deleted, which is incorrect.
+
+ This error can be corrected by first reading the index. The
+ update_index flag is correctly set if ita_only is true, because
+ this mode updates the index. However, if we merely gate the call
+ to read_apply_cache() behind update_index, then it will not be read
+ when state->apply is false, even if it must be checked. Therefore,
+ we instead read the index if it will be either checked or updated,
+ because reading the index is a prerequisite to either.
Reported-by: Ryan Hodges [off-list ref]
Original-patch-by: Johannes Altmanninger [off-list ref]
3: df28144f82 ! 2: 5f49ff9035 apply: only write intents to add for new files
@@ Commit message
touching the index, we can't rely only on that flag to decide whether to
write an index entry.
- Instead, we must test whether we are in a mode which updates the
- index, or else are in worktree-only mode with --intent-to-add on and
- the current file being an addition. We do not need to check
- state->apply, because we only enter write_out_results() if state->apply
- is already set.
+ Because we have already entered write_out_results() and are performing
+ writes, we know that state->apply is true. If state->check_index is
+ additionally true, we are in a mode which updates the index and should
+ always write, whereas if we are merely in ita_only mode we must only
+ write if the patch is a new file creation patch.
Signed-off-by: Raymond E. Pasco [off-list ref]
4: 0bbae13b63 ! 3: f8a6d8032f t4140: test apply --intent-to-add interactions
@@ t/t4140-apply-ita.sh: test_description='git apply of i-t-a file'
test_expect_success setup '
test_write_lines 1 2 3 4 5 >blueprint &&
-+ cat blueprint >committed-file &&
-+ git add committed-file &&
-+ git commit -m "commit" &&
++ cat blueprint >committed-file &&
++ git add committed-file &&
++ git commit -m "commit" &&
+
cat blueprint >test-file &&
git add -N test-file &&
@@ t/t4140-apply-ita.sh: test_expect_success 'apply deletion patch to ita path (--i
'
+test_expect_success 'apply creation patch to existing index with -N' '
-+ git rm -f test-file &&
-+ cat blueprint >index-file &&
-+ git add index-file &&
-+ git apply -N creation-patch &&
++ git rm -f test-file &&
++ cat blueprint >index-file &&
++ git add index-file &&
++ git apply -N creation-patch &&
+
-+ git ls-files --stage --error-unmatch index-file &&
-+ git ls-files --stage --error-unmatch test-file
++ git ls-files --stage --error-unmatch index-file &&
++ git ls-files --stage --error-unmatch test-file
+'
+
+test_expect_success 'apply complex patch with -N' '
-+ git rm -f test-file index-file &&
-+ git apply -N complex-patch &&
++ git rm -f test-file index-file &&
++ git apply -N complex-patch &&
+
-+ git ls-files --stage --error-unmatch test-file &&
-+ git diff | grep "a/committed-file"
++ git ls-files --stage --error-unmatch test-file &&
++ git diff | grep "a/committed-file"
+'
+
test_done
5: 970c739ca9 ! 4: ad42992d03 apply docs: clarify wording for --intent-to-add
@@ Documentation/git-apply.adoc: OPTIONS
- Note that `--index` could be implied by other options such
- as `--cached` or `--3way`.
+ option in linkgit:git-add[1]). This option is ignored if
-+ `--index` or `--cached` are used. Note that `--index` could
-+ be implied by other options such as `--3way`.
++ `--index` or `--cached` are used, and has no effect outside a Git
++ repository. Note that `--index` could be implied by other options
++ such as `--3way`.
-3::
--3way::
--
2.50.0.201.gfeb04032fb