Skip to content

Commit c28eaa6

Browse files
committed
Merge branch 'rp/apply-cached-with-i-t-a' into next
Recent versions of "git diff-files" shows a diff between the index and the working tree for "intent-to-add" paths as a "new file" patch; "git apply --cached" should be able to take "git diff-files" and should act as an equivalent to "git add" for the path, but the command failed to do so for such a path. * rp/apply-cached-with-i-t-a: t4140: test apply with i-t-a paths apply: make i-t-a entries never match worktree apply: allow "new file" patches on i-t-a entries
2 parents b232f7c + 4c025c6 commit c28eaa6

File tree

2 files changed

+77
-4
lines changed

2 files changed

+77
-4
lines changed

apply.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3740,17 +3740,31 @@ static int check_preimage(struct apply_state *state,
37403740

37413741
#define EXISTS_IN_INDEX 1
37423742
#define EXISTS_IN_WORKTREE 2
3743+
#define EXISTS_IN_INDEX_AS_ITA 3
37433744

37443745
static int check_to_create(struct apply_state *state,
37453746
const char *new_name,
37463747
int ok_if_exists)
37473748
{
37483749
struct stat nst;
37493750

3750-
if (state->check_index &&
3751-
index_name_pos(state->repo->index, new_name, strlen(new_name)) >= 0 &&
3752-
!ok_if_exists)
3753-
return EXISTS_IN_INDEX;
3751+
if (state->check_index && (!ok_if_exists || !state->cached)) {
3752+
int pos;
3753+
3754+
pos = index_name_pos(state->repo->index, new_name, strlen(new_name));
3755+
if (pos >= 0) {
3756+
struct cache_entry *ce = state->repo->index->cache[pos];
3757+
3758+
/* allow ITA, as they do not yet exist in the index */
3759+
if (!ok_if_exists && !(ce->ce_flags & CE_INTENT_TO_ADD))
3760+
return EXISTS_IN_INDEX;
3761+
3762+
/* ITA entries can never match working tree files */
3763+
if (!state->cached && (ce->ce_flags & CE_INTENT_TO_ADD))
3764+
return EXISTS_IN_INDEX_AS_ITA;
3765+
}
3766+
}
3767+
37543768
if (state->cached)
37553769
return 0;
37563770

@@ -3935,6 +3949,9 @@ static int check_patch(struct apply_state *state, struct patch *patch)
39353949
case EXISTS_IN_INDEX:
39363950
return error(_("%s: already exists in index"), new_name);
39373951
break;
3952+
case EXISTS_IN_INDEX_AS_ITA:
3953+
return error(_("%s: does not match index"), new_name);
3954+
break;
39383955
case EXISTS_IN_WORKTREE:
39393956
return error(_("%s: already exists in working directory"),
39403957
new_name);

t/t4140-apply-ita.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/sh
2+
3+
test_description='git apply of i-t-a file'
4+
5+
. ./test-lib.sh
6+
7+
test_expect_success setup '
8+
test_write_lines 1 2 3 4 5 >blueprint &&
9+
10+
cat blueprint >test-file &&
11+
git add -N test-file &&
12+
git diff >creation-patch &&
13+
grep "new file mode 100644" creation-patch &&
14+
15+
rm -f test-file &&
16+
git diff >deletion-patch &&
17+
grep "deleted file mode 100644" deletion-patch
18+
'
19+
20+
test_expect_success 'apply creation patch to ita path (--cached)' '
21+
git rm -f test-file &&
22+
cat blueprint >test-file &&
23+
git add -N test-file &&
24+
25+
git apply --cached creation-patch &&
26+
git cat-file blob :test-file >actual &&
27+
test_cmp blueprint actual
28+
'
29+
30+
test_expect_success 'apply creation patch to ita path (--index)' '
31+
git rm -f test-file &&
32+
cat blueprint >test-file &&
33+
git add -N test-file &&
34+
rm -f test-file &&
35+
36+
test_must_fail git apply --index creation-patch
37+
'
38+
39+
test_expect_success 'apply deletion patch to ita path (--cached)' '
40+
git rm -f test-file &&
41+
cat blueprint >test-file &&
42+
git add -N test-file &&
43+
44+
git apply --cached deletion-patch &&
45+
test_must_fail git ls-files --stage --error-unmatch test-file
46+
'
47+
48+
test_expect_success 'apply deletion patch to ita path (--index)' '
49+
cat blueprint >test-file &&
50+
git add -N test-file &&
51+
52+
test_must_fail git apply --index deletion-patch &&
53+
git ls-files --stage --error-unmatch test-file
54+
'
55+
56+
test_done

0 commit comments

Comments
 (0)