From: "Sverre Hvammen Johansen" <hvammen@gmail.com>
To: "Junio C Hamano" <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: [PATCH 4/5] Head reduction before selecting merge strategy
Date: Wed, 23 Apr 2008 22:52:07 -0700 [thread overview]
Message-ID: <402c10cd0804232252g43606767r10344ebbb2a44af9@mail.gmail.com> (raw)
See the documentation for an explanation of this feature.
Signed-off-by: Sverre Hvammen Johansen <hvammen@gmail.com>
---
Documentation/git-merge.txt | 43 ++++++++++++++++++++++++++++++++++++-
git-merge.sh | 50 ++++++++++++++++++++++++-------------------
2 files changed, 70 insertions(+), 23 deletions(-)
diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt
index 2af33d8..f6bc96f 100644
--- a/Documentation/git-merge.txt
+++ b/Documentation/git-merge.txt
@@ -36,7 +36,7 @@ include::merge-options.txt[]
<remote>::
Other branch head merged into our branch. You need at
least one <remote>. Specifying more than one <remote>
- obviously means you are trying an Octopus.
+ usually means you are trying an Octopus.
include::fast-forward-options.txt[]
@@ -133,6 +133,47 @@ merge (which is typically a fraction of the whole
tree), you can
have local modifications in your working tree as long as they do
not overlap with what the merge updates.
+If more than one commit are specified on the command line, git will
+try to reduce the number of commits used (reduced parents) by
+eliminating commits than can be reached from other commits. The
+commit message will reflect the commits specified on the command line
+but the merge strategy will be selected based on the reduced parents
+including `HEAD`. The reduced parents are the parents recorded in the
+merge commit object.
+
+The following shows master and three topic branches. topicB is based
+on topicA, topicA is previously branched off from master, and topicC
+is based on the tip of the master branch:
+
+------------
+ o---o---o topicB
+ /
+ o---o---o topicA
+ /
+ o---o---o---o---o---o master
+ \
+ o---o topicC
+------------
+
+Merging topicA, B and C to the master branch will select the merge
+strategy based on the three branches master, topicB, and topicC
+(topicA is eliminated since it can be reached from topicB). topicB
+and topicC are the reduced parents and are therefore the only
+parents recorded in the merge commit object:
+
+------------
+ $ git checkout master
+ $ git merge topicA topicB topicC
+
+ o---o---o topicB
+ / \
+ o---o---o topicA \
+ / \
+ o---o---o---o---o---o o master
+ \ /
+ o---o topicC
+------------
+
When there are conflicts, these things happen:
1. `HEAD` stays the same.
diff --git a/git-merge.sh b/git-merge.sh
index 7c34b6c..7c70c56 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -337,11 +337,16 @@ set x $remoteheads ; shift
find_reduced_parents "$@"
-actual_parents=$(git rev-parse "$@")
+# ff_head may be included here or later in actual parents
+if test -n "$reduced_parents"
+then
+ test $head = $ff_head ||
+ reduced_parents="$ff_head$LF$reduced_parents"
+fi
case "$use_strategies" in
'')
- case "$actual_parents" in
+ case "$reduced_parents" in
?*"$LF"?*)
var="`git config --get pull.octopus`"
if test -n "$var"
@@ -406,17 +411,23 @@ then
finish "$new_head" "$msg" || exit
dropsave
exit 0
+ else
+ reduced_parents="$ff_head"
+ ff_head=$head
fi
+else
+ test $head != $ff_head -a $fast_forward = never &&
+ reduced_parents="$ff_head$LF$reduced_parents"
fi
-case "$actual_parents" in
+case "$reduced_parents" in
?*"$LF"?*)
- # We have more than one actual parent
- common=$(git show-branch --merge-base $head $actual_parents)
+ # We have more than one reduced parent
+ common=$(git show-branch --merge-base $head $reduced_parents)
;;
*)
- # We have exactly one actual parent
- test "$common" != not_queried || common=$(git merge-base --all
$head $actual_parents)
+ # We have exactly one reduced parent
+ test "$common" != not_queried || common=$(git merge-base --all
$head $reduced_parents)
case "$common" in
?*"$LF"?*)
# We are not doing octopus and not fast forward. Need a
@@ -429,13 +440,13 @@ case "$actual_parents" in
# See if it is really trivial.
git var GIT_COMMITTER_IDENT >/dev/null || exit
echo "Trying really trivial in-index merge..."
- if git read-tree --trivial -m -u -v $common
$head $actual_parents &&
+ if git read-tree --trivial -m -u -v $common
$head $reduced_parents &&
result_tree=$(git write-tree)
then
echo "Wonderful."
result_commit=$(
printf '%s\n' "$merge_msg" |
- git commit-tree $result_tree
-p HEAD -p $actual_parents
+ git commit-tree $result_tree
-p HEAD -p $reduced_parents
) || exit
finish "$result_commit" "In-index merge"
dropsave
@@ -484,7 +495,7 @@ do
# Remember which strategy left the state in the working tree
wt_strategy=$strategy
- git-merge-$strategy $common -- "$head_arg" $actual_parents
+ git-merge-$strategy $common -- "$head_arg" $reduced_parents
exit=$?
if test "$no_commit" = t && test "$exit" = 0
then
@@ -520,17 +531,12 @@ done
# auto resolved the merge cleanly.
if test '' != "$result_tree"
then
- if test $fast_forward = allow
- then
- parents=$(git show-branch --independent "$head" "$@")
- else
- parents=$(git rev-parse "$head" "$@")
- fi
- parents=$(echo "$parents" | sed -e 's/^/-p /')
- result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree
$result_tree $parents) || exit
- finish "$result_commit" "Merge made by $wt_strategy."
- dropsave
- exit 0
+ test $head = $ff_head && reduced_parents="$head$LF$reduced_parents"
+ parents=$(echo "$reduced_parents" | sed -e 's/^/-p /')
+ result_commit=$(printf '%s\n' "$merge_msg" | git commit-tree
$result_tree $parents) || exit
+ finish "$result_commit" "Merge made by $wt_strategy."
+ dropsave
+ exit 0
fi
# Pick the result from the best strategy and have the user fix it up.
@@ -554,7 +560,7 @@ case "$best_strategy" in
echo "Rewinding the tree to pristine..."
restorestate
echo "Using the $best_strategy to prepare resolving by hand."
- git-merge-$best_strategy $common -- "$head_arg" $actual_parents
+ git-merge-$best_strategy $common -- "$head_arg" $reduced_parents
;;
esac
--
Sverre Hvammen Johansen
next reply other threads:[~2008-04-24 5:52 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-24 5:52 Sverre Hvammen Johansen [this message]
2008-04-25 10:31 ` [PATCH 4/5] Head reduction before selecting merge strategy Jakub Narebski
2008-05-04 4:52 ` Sverre Hvammen Johansen
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=402c10cd0804232252g43606767r10344ebbb2a44af9@mail.gmail.com \
--to=hvammen@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
/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).