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 <rhodges@xxxxxxxxx> Original-patch-by: Johannes Altmanninger <aclopte@xxxxxxxxx> 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 <ray@xxxxxxxxxxxx> 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