git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Junio C Hamano <junkio@cox.net>
To: Linus Torvalds <torvalds@osdl.org>
Cc: git@vger.kernel.org
Subject: [PATCH] Fall back to three-way merge when applying a patch.
Date: Tue, 04 Oct 2005 17:46:05 -0700	[thread overview]
Message-ID: <7vd5mk7pv6.fsf@assigned-by-dhcp.cox.net> (raw)

After git-apply fails, attempt to find a base tree that the patch
cleanly applies to, and do a three-way merge using that base tree into
the current index.

When the fall-back merge fails, the working tree can be resolved the
same way as you would normally hand resolve a conflicting merge.
When making commit, use .dotest/final-commit as the log message
template.  Or you could just choose to 'git-checkout-index -f -a'
to revert the failed merge.

Signed-off-by: Junio C Hamano <junkio@cox.net>

---

 * I will be placing this in the proposed updates branch.
   Hopefully this would alleviate the complaints from people who
   find the "no fuzz" policy of git-apply is too strict.

   The change is helped if the patch sender uses the updated
   git-format-patch that records which tree the patch is
   supposed to cleanly apply to, but that is not strictly
   necessary; it tries to find a tree that patch applies to from
   the recent commits itself.

 git-applypatch.sh |   62 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 1 deletions(-)

applies-to: 9eec9ff9326032bca405a12a265918725edf4ac7
fb533c6562481dfbc4719f740aa0d85e2a45700c
diff --git a/git-applypatch.sh b/git-applypatch.sh
--- a/git-applypatch.sh
+++ b/git-applypatch.sh
@@ -105,7 +105,67 @@ git-apply --index "$PATCHFILE" || {
 	# Here if we know which revision the patch applies to,
 	# we create a temporary working tree and index, apply the
 	# patch, and attempt 3-way merge with the resulting tree.
-	exit 1
+
+	O_OBJECT=`cd "$GIT_OBJECT_DIRECTORY" && pwd`
+	rm -fr .patch-merge-*
+
+	(
+		N=10
+
+		# if the patch records the base tree...
+		sed -ne '
+			/^diff /q
+			/^applies-to: \([0-9a-f]*\)$/{
+				s//\1/p
+				q
+			}
+		' "$PATCHFILE"
+
+		# or hoping the patch is against our recent commits...
+		git-rev-list --max-count=$N HEAD
+
+		# or hoping the patch is against known tags...
+		git-ls-remote --tags .
+	) |
+	while read base junk
+	do
+		# Try it if we have it as a tree.
+		git-cat-file tree "$base" >/dev/null 2>&1 || continue
+
+		rm -fr .patch-merge-tmp-* &&
+		mkdir .patch-merge-tmp-dir || break
+		(
+			cd .patch-merge-tmp-dir &&
+			GIT_INDEX_FILE=../.patch-merge-tmp-index &&
+			GIT_OBJECT_DIRECTORY="$O_OBJECT" &&
+			export GIT_INDEX_FILE GIT_OBJECT_DIRECTORY &&
+			git-read-tree "$base" &&
+			git-apply --index &&
+			mv ../.patch-merge-tmp-index ../.patch-merge-index &&
+			echo "$base" >../.patch-merge-base
+		) <"$PATCHFILE"  2>/dev/null && break
+	done
+
+	test -f .patch-merge-index &&
+	his_tree=$(GIT_INDEX_FILE=.patch-merge-index git-write-tree) &&
+	orig_tree=$(cat .patch-merge-base) &&
+	rm -fr .patch-merge-* || exit 1
+
+	echo Falling back to patching base and 3-way merge using $orig_tree...
+
+	# This is not so wrong.  Depending on which base we picked,
+	# orig_tree may be wildly different from ours, but his_tree
+	# has the same set of wildly different changes in parts the
+	# patch did not touch, so resolve ends up cancelling them,
+	# saying that we reverted all those changes.
+
+	if git-merge-resolve $orig_tree -- HEAD $his_tree
+	then
+		echo Done.
+	else
+		echo Failed to merge in the changes.
+		exit 1
+	fi
 }
 
 if test -x "$GIT_DIR"/hooks/pre-applypatch
---
0.99.8.GIT

             reply	other threads:[~2005-10-05  0:46 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2005-10-05  0:46 Junio C Hamano [this message]
2005-10-05  4:56 ` [PATCH] Fall back to three-way merge when applying a patch Linus Torvalds
2005-10-05  6:58   ` Junio C Hamano
2005-10-05 14:30     ` Linus Torvalds
2005-10-06  0:03       ` Junio C Hamano
2005-10-06  1:59         ` Eric W. Biederman
2005-10-06  2:18           ` Linus Torvalds
2005-10-06  4:17             ` Junio C Hamano
2005-10-06  5:25             ` Eric W. Biederman
2005-10-06 14:35               ` Linus Torvalds
2005-10-06 14:52                 ` Eric W. Biederman
2005-10-06 14:59                   ` Linus Torvalds
2005-10-06 17:07                     ` Eric W. Biederman
2005-10-07  2:33                     ` [PATCH] Show original and resulting blob object info in diff output Junio C Hamano
2005-10-07  4:47                       ` Linus Torvalds
2005-10-07  5:16                         ` Junio C Hamano
2005-10-06  7:33             ` [PATCH] Fall back to three-way merge when applying a patch 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

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=7vd5mk7pv6.fsf@assigned-by-dhcp.cox.net \
    --to=junkio@cox.net \
    --cc=git@vger.kernel.org \
    --cc=torvalds@osdl.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.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

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 read-only IMAP folder(s) and NNTP newsgroup(s).