Skip to content

Commit 5a7e52b

Browse files
committed
Merge branch 'jz/apply-3way-cached'
"git apply" now takes "--3way" and "--cached" at the same time, and work and record results only in the index. * jz/apply-3way-cached: git-apply: allow simultaneous --cached and --3way options
2 parents b98db1d + c0c2a37 commit 5a7e52b

File tree

3 files changed

+60
-5
lines changed

3 files changed

+60
-5
lines changed

Documentation/git-apply.txt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,10 @@ OPTIONS
8787
Attempt 3-way merge if the patch records the identity of blobs it is supposed
8888
to apply to and we have those blobs available locally, possibly leaving the
8989
conflict markers in the files in the working tree for the user to
90-
resolve. This option implies the `--index` option, and is incompatible
91-
with the `--reject` and the `--cached` options.
90+
resolve. This option implies the `--index` option unless the
91+
`--cached` option is used, and is incompatible with the `--reject` option.
92+
When used with the `--cached` option, any conflicts are left at higher stages
93+
in the cache.
9294

9395
--build-fake-ancestor=<file>::
9496
Newer 'git diff' output has embedded 'index information'

apply.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,6 @@ int check_apply_state(struct apply_state *state, int force_apply)
134134

135135
if (state->apply_with_reject && state->threeway)
136136
return error(_("--reject and --3way cannot be used together."));
137-
if (state->cached && state->threeway)
138-
return error(_("--cached and --3way cannot be used together."));
139137
if (state->threeway) {
140138
if (is_not_gitdir)
141139
return error(_("--3way outside a repository"));
@@ -4646,7 +4644,12 @@ static int write_out_results(struct apply_state *state, struct patch *list)
46464644
}
46474645
string_list_clear(&cpath, 0);
46484646

4649-
repo_rerere(state->repo, 0);
4647+
/*
4648+
* rerere relies on the partially merged result being in the working
4649+
* tree with conflict markers, but that isn't written with --cached.
4650+
*/
4651+
if (!state->cached)
4652+
repo_rerere(state->repo, 0);
46504653
}
46514654

46524655
return errs;

t/t4108-apply-threeway.sh

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,4 +180,54 @@ test_expect_success 'apply -3 with ambiguous repeating file' '
180180
test_cmp expect one_two_repeat
181181
'
182182

183+
test_expect_success 'apply with --3way --cached clean apply' '
184+
# Merging side should be similar to applying this patch
185+
git diff ...side >P.diff &&
186+
187+
# The corresponding cleanly applied merge
188+
git reset --hard &&
189+
git checkout main~ &&
190+
git merge --no-commit side &&
191+
git ls-files -s >expect.ls &&
192+
193+
# should succeed
194+
git reset --hard &&
195+
git checkout main~ &&
196+
git apply --cached --3way P.diff &&
197+
git ls-files -s >actual.ls &&
198+
print_sanitized_conflicted_diff >actual.diff &&
199+
200+
# The cache should resemble the corresponding merge
201+
# (both files at stage #0)
202+
test_cmp expect.ls actual.ls &&
203+
# However the working directory should not change
204+
>expect.diff &&
205+
test_cmp expect.diff actual.diff
206+
'
207+
208+
test_expect_success 'apply with --3way --cached and conflicts' '
209+
# Merging side should be similar to applying this patch
210+
git diff ...side >P.diff &&
211+
212+
# The corresponding conflicted merge
213+
git reset --hard &&
214+
git checkout main^0 &&
215+
test_must_fail git merge --no-commit side &&
216+
git ls-files -s >expect.ls &&
217+
218+
# should fail to apply
219+
git reset --hard &&
220+
git checkout main^0 &&
221+
test_must_fail git apply --cached --3way P.diff &&
222+
git ls-files -s >actual.ls &&
223+
print_sanitized_conflicted_diff >actual.diff &&
224+
225+
# The cache should resemble the corresponding merge
226+
# (one file at stage #0, one file at stages #1 #2 #3)
227+
test_cmp expect.ls actual.ls &&
228+
# However the working directory should not change
229+
>expect.diff &&
230+
test_cmp expect.diff actual.diff
231+
'
232+
183233
test_done

0 commit comments

Comments
 (0)