git/builtin
Junio C Hamano 9d158601b3 apply: do not patch lines that were already patched
When looking for a place to apply a hunk, we used to check lines that
match the preimage of it, starting from the line that the patch wants to
apply the hunk at, looking forward and backward with increasing offsets
until we find a match.

Colin Guthrie found an interesting case where this misapplied a patch that
wanted to touch a preimage that consists of

                        }
                }

                return 0;
        }

which is a rather unfortunately common pattern.

The target version of the file originally had only one such location, but
the hunk immediately before that created another instance of such block of
lines, and find_pos() happily reported that the preimage of the hunk
matched what it wanted to modify.

Oops.

By marking the lines application of earlier hunks touched and preventing
match_fragment() from considering them as a match with preimage of other
hunks, we can reduce such an accident.

I also considered to teach apply_one_fragment() to take the offset we have
found while applying the previous hunk into account when looking for a
match with find_pos(), but dismissed that approach, because it would
sometimes work better but sometimes worse, depending on the difference
between the version the patch was created against and the version the
patch is being applied.

This does _not_ prevent misapplication of patches to a file that has many
similar looking blocks of lines and a preimage cannot identify which one
of them should be applied.  For that, we would need to scan beyond the
first match in find_pos(), and issue a warning (or error out).  That will
be a separate topic.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
2011-03-04 14:47:18 -08:00
..
add.c add: describe --patch like checkout, reset 2011-02-15 10:51:08 -08:00
annotate.c
apply.c apply: do not patch lines that were already patched 2011-03-04 14:47:18 -08:00
archive.c
bisect--helper.c
blame.c Merge branch 'jn/parse-options-extra' 2010-12-12 21:49:53 -08:00
branch.c branch_merged: fix grammar in warning 2011-02-27 00:29:58 -08:00
bundle.c Use angles for placeholders consistently 2010-10-08 12:29:52 -07:00
cat-file.c blame,cat-file --textconv: Don't assume mode is ``S_IFREF | 0664'' 2010-09-29 16:53:25 -07:00
check-attr.c
check-ref-format.c Allow "check-ref-format --branch" from subdirectory 2010-08-06 10:01:45 -07:00
checkout-index.c Merge branch 'jn/git-cmd-h-bypass-setup' 2010-12-12 21:49:50 -08:00
checkout.c correct type of EMPTY_TREE_SHA1_BIN 2011-02-14 10:48:06 -08:00
clean.c Merge branch 'rs/opt-help-text' 2010-11-24 15:55:19 -08:00
clone.c clone,init: describe --template using the same wording 2011-02-15 10:51:08 -08:00
commit-tree.c Sync with 1.7.3.2 2010-10-21 17:16:10 -07:00
commit.c commit,status: describe -u likewise 2011-02-15 10:51:08 -08:00
config.c Merge branch 'jn/paginate-fix' 2010-08-31 16:23:31 -07:00
count-objects.c add description parameter to OPT__VERBOSE 2010-11-15 09:56:51 -08:00
describe.c Merge branch 'tf/commit-list-prefix' 2010-12-22 14:40:17 -08:00
diff-files.c Submodules: Use "ignore" settings from .gitmodules too for diff and status 2010-08-09 09:11:44 -07:00
diff-index.c Submodules: Use "ignore" settings from .gitmodules too for diff and status 2010-08-09 09:11:44 -07:00
diff-tree.c Submodules: Use "ignore" settings from .gitmodules too for diff and status 2010-08-09 09:11:44 -07:00
diff.c diff: support --cached on unborn branches 2011-02-07 15:04:30 -08:00
fast-export.c Merge branch 'en/d-f-conflict-fix' 2010-09-08 08:54:01 -07:00
fetch-pack.c commit: Add commit_list prefix in two function names. 2010-11-29 14:01:52 -08:00
fetch.c Merge branch 'jl/fetch-submodule-recursive' 2010-12-16 12:57:15 -08:00
fmt-merge-msg.c Change incorrect "remote branch" to "remote tracking branch" in C code 2010-11-03 09:20:47 -07:00
for-each-ref.c for-each-ref: fix objectname:short bug 2010-08-26 16:42:25 -07:00
fsck.c fsck: do not give up too early in fsck_dir() 2011-01-27 12:58:15 -08:00
gc.c Merge branch 'jn/git-cmd-h-bypass-setup' 2010-12-12 21:49:50 -08:00
grep.c thread-utils.h: simplify the inclusion 2010-12-10 12:58:06 -08:00
hash-object.c
help.c Cast execl*() NULL sentinels to (char *) 2010-07-25 23:14:18 -07:00
index-pack.c Use parentheses and `...' where appropriate 2010-10-08 12:31:07 -07:00
init-db.c init: remove unnecessary check 2011-03-03 15:45:10 -08:00
log.c Merge branch 'tc/format-patch-p' 2010-12-12 21:49:52 -08:00
ls-files.c Merge branch 'jn/git-cmd-h-bypass-setup' 2010-12-12 21:49:50 -08:00
ls-remote.c ls-remote: run setup_git_directory_gently() sooner 2010-08-15 20:00:02 -07:00
ls-tree.c Use angles for placeholders consistently 2010-10-08 12:29:52 -07:00
mailinfo.c commit: helper methods to reduce redundant blocks of code 2010-11-04 13:53:34 -07:00
mailsplit.c Use parentheses and `...' where appropriate 2010-10-08 12:31:07 -07:00
merge-base.c merge-base --independent to print reduced parent list in a merge 2010-08-18 14:02:03 -07:00
merge-file.c Merge branch 'rs/opt-help-text' 2010-11-24 15:55:19 -08:00
merge-index.c
merge-ours.c
merge-recursive.c Merge branch 'jf/merge-ignore-ws' 2010-10-26 21:40:54 -07:00
merge-tree.c merge-tree: fix where two branches share no changes 2010-07-14 12:56:49 -07:00
merge.c commit,merge,tag: describe -m likewise 2011-02-15 10:51:08 -08:00
mktag.c
mktree.c
mv.c add OPT__FORCE 2010-11-15 10:04:43 -08:00
name-rev.c object.h: Add OBJECT_ARRAY_INIT macro and make use of it. 2010-08-29 22:42:49 -07:00
notes.c Merge branch 'jh/notes-merge' 2010-12-08 11:24:12 -08:00
pack-objects.c thread-utils.h: simplify the inclusion 2010-12-10 12:58:06 -08:00
pack-redundant.c
pack-refs.c
patch-id.c
prune-packed.c
prune.c add description parameter to OPT__DRY_RUN 2010-11-15 09:57:37 -08:00
push.c Merge branch 'maint' 2010-08-12 18:07:09 -07:00
read-tree.c add description parameter to OPT__VERBOSE 2010-11-15 09:56:51 -08:00
receive-pack.c Merge branch 'tr/receive-pack-aliased-update-fix' into maint 2010-07-07 10:25:15 -07:00
reflog.c
remote-ext.c remote-ext: do not segfault for blank lines 2011-01-18 10:18:25 -08:00
remote-fd.c remote-fd/ext: finishing touches after code review 2010-11-19 11:04:20 -08:00
remote.c Merge branch 'rs/opt-help-text' 2010-11-24 15:55:19 -08:00
replace.c
rerere.c Merge branch 'jn/merge-renormalize' 2010-09-03 09:43:41 -07:00
reset.c Describe various forms of "be quiet" using OPT__QUIET 2010-11-15 10:04:56 -08:00
rev-list.c Merge branch 'jk/maint-rev-list-nul' into maint 2010-11-24 12:46:32 -08:00
rev-parse.c Merge branch 'maint' 2010-07-07 11:18:26 -07:00
revert.c Merge branch 'jn/cherry-pick-refresh-index' into maint 2010-12-09 10:36:51 -08:00
rm.c builtin/rm.c: Use ALLOC_GROW instead of alloc_nr and xrealloc. 2010-12-19 10:44:06 -08:00
send-pack.c Merge branch 'jk/push-progress' 2010-11-17 15:01:00 -08:00
shortlog.c parse-options: Don't call parse_options_check() so much 2010-12-06 16:51:36 -08:00
show-branch.c commit: Add commit_list prefix in two function names. 2010-11-29 14:01:52 -08:00
show-ref.c Describe various forms of "be quiet" using OPT__QUIET 2010-11-15 10:04:56 -08:00
stripspace.c
symbolic-ref.c Describe various forms of "be quiet" using OPT__QUIET 2010-11-15 10:04:56 -08:00
tag.c commit,merge,tag: describe -m likewise 2011-02-15 10:51:08 -08:00
tar-tree.c
unpack-file.c
unpack-objects.c do not depend on signed integer overflow 2010-10-06 11:10:07 -07:00
update-index.c Merge branch 'jn/parse-options-extra' 2010-12-12 21:49:53 -08:00
update-ref.c
update-server-info.c add OPT__FORCE 2010-11-15 10:04:43 -08:00
upload-archive.c
var.c var: run setup_git_directory_gently() sooner 2010-08-15 20:00:02 -07:00
verify-pack.c
verify-tag.c Merge branch 'mg/maint-tag-rfc1991' 2010-12-08 11:24:13 -08:00
write-tree.c