From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Subject: [PATCH 0/8] "git apply --threeway"
Date: Wed, 9 May 2012 23:02:17 -0700 [thread overview]
Message-ID: <1336629745-22436-1-git-send-email-gitster@pobox.com> (raw)
This series teaches "git apply" the same "three-way merge fallback" logic
that makes "am -3" so useful when flipping patches around. For people who
do not know how "am -3" magic works, the basic idea goes like this:
0) Suppose you have this history leading to commit E:
O---A---B---...---E
1) Also suppose you have a patch that is based on an older version; it no
longer applies to the version of the file you have. The patch would
apply cleanly to the file in an older version, say A, and would result
in file in a fictitious version X:
X
/
O---A---B---...---E
You can think of X as a commit where this patch was taken from, but
there may not be any such commit in your object database.
2) A useful observation to make here is that the result of applying such
a patch to your current version should look similar to the result of
merging X and E:
X-------------M merge!
/ /
O---A---B---...---E
And this feature works exactly like that.
- After trying and failing to apply the patch text, we inspect our object
database and see if there is a blob object that matches what is
recorded on the "index" line of the patch as its preimage. We may not
have such a blob object, and we give up in such a case.
- And then we try to apply the patch text to that blob. This also could
fail, as the patch author could have tweaked the patch text after
producing the patch with "git diff" without adjusting the "index" line.
Again we simply give up in such a case.
- When we successfully apply the patch to the older blob, the result
would be what would appear in the fictitious commit X in the above
picture. We then try the usual file-level three-way merge between X
and E using A as the base version. This could cleanly merge, in which
case we successfully applied the patch. Or this could conflict, in
which case we record the conflicted stages in the index, just like a
conflicted "merge" or an "am -3" does, and leave the conflict markers
in the result.
I've wanted to see this for the past few years, and even suggested that
this is a good bite-sized GSoC project, but unfortunately nobody bit it;
you have to do it yourself if you really want it, I guess.
Note that this iteration still does not do a few things:
- We probably should call into the rerere machinery to have it help the
user deal with the conflicts.
- The "--threeway" option probably should be made explicitly incompatible
with the "--reject" option (implement it when the command line is
parsed).
- It might make sense to make "--threeway" imply "--index", but it is not
strictly necessary (see the second test case in t4108).
- Documentation updates are missing.
- "am -3" should be rewritten by using this. That in turn means that the
"--build-fake-ancestor" option of "git apply" will lose the only and
the last in-tree user, but we may not be able to drop it immediately as
there may be out-of-tree users. On the other hand, any out-of-tree
user that uses the "--build-fake-ancestor" option is reimplementing the
three-way fallback on their own, and they can be updated to use the new
"--threeway" option of "git apply".
- Once this proves useful, it may deserve to use short-and-sweet "-3"
option.
Junio C Hamano (8):
apply: reformat comment
apply: accept --threeway command line option
apply: split load_preimage() helper function out
apply: clear_image() clears things a bit more
apply: refactor read_file_or_gitlink()
apply: fall back on three-way merge
apply: plug the three-way merge logic in
apply: register conflicted stages to the index
builtin/apply.c | 198 +++++++++++++++++++++++++++++++++++++++++-----
t/t4108-apply-threeway.sh | 78 ++++++++++++++++++
2 files changed, 257 insertions(+), 19 deletions(-)
create mode 100755 t/t4108-apply-threeway.sh
--
1.7.10.1.562.gfc79b1c
next reply other threads:[~2012-05-10 6:02 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-05-10 6:02 Junio C Hamano [this message]
2012-05-10 6:02 ` [PATCH 1/8] apply: reformat comment Junio C Hamano
2012-05-10 6:02 ` [PATCH 2/8] apply: accept --threeway command line option Junio C Hamano
2012-05-10 12:40 ` Nguyen Thai Ngoc Duy
2012-05-10 15:31 ` Junio C Hamano
2012-05-10 6:02 ` [PATCH 3/8] apply: split load_preimage() helper function out Junio C Hamano
2012-05-10 6:02 ` [PATCH 4/8] apply: clear_image() clears things a bit more Junio C Hamano
2012-05-10 6:02 ` [PATCH 5/8] apply: refactor read_file_or_gitlink() Junio C Hamano
2012-05-10 6:02 ` [PATCH 6/8] apply: fall back on three-way merge Junio C Hamano
2012-05-10 7:26 ` Matthieu Moy
2012-05-10 15:10 ` Junio C Hamano
2012-05-10 15:41 ` Matthieu Moy
2012-05-10 20:31 ` Jeff King
2012-05-10 21:06 ` Junio C Hamano
2012-05-10 22:24 ` Jeff King
2012-05-10 6:02 ` [PATCH 7/8] apply: plug the three-way merge logic in Junio C Hamano
2012-05-10 6:02 ` [PATCH 8/8] apply: register conflicted stages to the index Junio C Hamano
2012-05-10 7:31 ` [PATCH 0/8] "git apply --threeway" Matthieu Moy
2012-05-10 15:26 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1336629745-22436-1-git-send-email-gitster@pobox.com \
--to=gitster@pobox.com \
--cc=git@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).