From: "Sverre Hvammen Johansen" <hvammen@gmail.com>
To: "Junio C Hamano" <gitster@pobox.com>
Cc: git@vger.kernel.org
Subject: Re: [RFC/PATCH 3/5] Restructure git-merge.sh
Date: Sun, 30 Mar 2008 20:29:12 -0800 [thread overview]
Message-ID: <402c10cd0803302129o396e5d37u944f76cd345d672@mail.gmail.com> (raw)
Restructure git-merge.sh for preparation of new feature:
Head reduction before selecting merge strategy
Some aspects of this patch does not make much sense without
the next patch in this series.
Signed-off-by: Sverre Hvammen Johansen <hvammen@gmail.com>
---
git-merge.sh | 186 +++++++++++++++++++++++++++++++++-------------------------
1 files changed, 105 insertions(+), 81 deletions(-)
diff --git a/git-merge.sh b/git-merge.sh
index 17f40f2..7c34b6c 100755
--- a/git-merge.sh
+++ b/git-merge.sh
@@ -207,6 +207,47 @@ parse_config () {
args_left=$#
}
+# Find reduced parents
+# The following variables are set as follow:
+# reduced_parents: The reduced parents of those specified on the
command line.
+# However, the actual parents are included if we never ff.
+# common: All common ancestors or not_queried
+# ff_head: Head or an reduced parent that may be a
candidate for fast forward
+find_reduced_parents () {
+ if test $fast_forward = never
+ then
+ reduced_parents=$(git rev-parse "$@")
+ ff_head=$head
+ common=not_queried
+ else
+ if test $# = 1
+ then
+ common=$(git merge-base --all $head "$1")
+ if test "$common" = $head
+ then
+ reduced_parents=
+ ff_head=$1
+ elif test "$common" = "$1"
+ then
+ reduced_parents=
+ ff_head=$head
+ else
+ reduced_parents=$1
+ ff_head=$head
+
+ fi
+ else
+ reduced_parents=$(git show-branch
--independent $head "$@")
+ # Here we may actually lie about which bransh
is ff of head.
+ # This will preserve the order the user gave.
+ ff_head=${reduced_parents%%$LF*}
+ reduced_parents=${reduced_parents#$ff_head}
+ reduced_parents=${reduced_parents#$LF}
+ common=not_queried
+ fi
+ fi
+}
+
test $# != 0 || usage
have_message=
@@ -294,24 +335,28 @@ do
done
set x $remoteheads ; shift
+find_reduced_parents "$@"
+
+actual_parents=$(git rev-parse "$@")
+
case "$use_strategies" in
'')
- case "$#" in
- 1)
- var="`git config --get pull.twohead`"
+ case "$actual_parents" in
+ ?*"$LF"?*)
+ var="`git config --get pull.octopus`"
if test -n "$var"
then
use_strategies="$var"
else
- use_strategies="$default_twohead_strategies"
+ use_strategies="$default_octopus_strategies"
fi ;;
*)
- var="`git config --get pull.octopus`"
+ var="`git config --get pull.twohead`"
if test -n "$var"
then
use_strategies="$var"
else
- use_strategies="$default_octopus_strategies"
+ use_strategies="$default_twohead_strategies"
fi ;;
esac
;;
@@ -339,87 +384,66 @@ do
done
done
-case "$#" in
-1)
- common=$(git merge-base --all $head "$@")
- ;;
-*)
- common=$(git show-branch --merge-base $head "$@")
- ;;
-esac
echo "$head" >"$GIT_DIR/ORIG_HEAD"
-case "$fast_forward,$#,$common,$no_commit" in
-*,*,'',*)
- # No common ancestors found. We need a real merge.
- ;;
-*,1,"$1",*)
- # If head can reach all the merge then we are up to date.
- # but first the most common case of merging one remote.
- finish_up_to_date "Already up-to-date."
- exit 0
- ;;
-allow,1,"$head",*)
- # Again the most common case of merging one remote.
- echo "Updating $(git rev-parse --short $head)..$(git rev-parse
--short $1)"
- git update-index --refresh 2>/dev/null
- msg="Fast forward"
- if test -n "$have_message"
+if test -z "$reduced_parents"
+then
+ if test $head = $ff_head
then
- msg="$msg (no commit created; -m option ignored)"
- fi
- new_head=$(git rev-parse --verify "$1^0") &&
- git read-tree -v -m -u --exclude-per-directory=.gitignore
$head "$new_head" &&
- finish "$new_head" "$msg" || exit
- dropsave
- exit 0
- ;;
-*,1,?*"$LF"?*,*)
- # We are not doing octopus and not fast forward. Need a
- # real merge.
- ;;
-*,1,*,)
- # We are not doing octopus, not fast forward, and have only
- # one common.
- git update-index --refresh 2>/dev/null
- case "$allow_trivial_merge" in
- t)
- # 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 "$1" &&
- result_tree=$(git write-tree)
- then
- echo "Wonderful."
- result_commit=$(
- printf '%s\n' "$merge_msg" |
- git commit-tree $result_tree -p HEAD -p "$1"
- ) || exit
- finish "$result_commit" "In-index merge"
- dropsave
- exit 0
- fi
- echo "Nope."
- esac
- ;;
-*)
- # An octopus. If we can reach all the remote we are up to date.
- up_to_date=t
- for remote
- do
- common_one=$(git merge-base --all $head $remote)
- if test "$common_one" != "$remote"
+ finish_up_to_date "Already up-to-date."
+ exit 0
+ elif test $fast_forward != never
+ then
+ echo "Updating $(git rev-parse --short $head)..$(git
rev-parse --short $ff_head)"
+ git update-index --refresh 2>/dev/null
+ msg="Fast forward"
+ if test -n "$have_message"
then
- up_to_date=f
- break
+ msg="$msg (no commit created; -m option ignored)"
fi
- done
- if test "$up_to_date" = t
- then
- finish_up_to_date "Already up-to-date. Yeeah!"
+ new_head=$(git rev-parse --verify "$ff_head^0") &&
+ git read-tree -v -m -u
--exclude-per-directory=.gitignore $head "$new_head" &&
+ finish "$new_head" "$msg" || exit
+ dropsave
exit 0
fi
+fi
+
+case "$actual_parents" in
+?*"$LF"?*)
+ # We have more than one actual parent
+ common=$(git show-branch --merge-base $head $actual_parents)
;;
+*)
+ # We have exactly one actual parent
+ test "$common" != not_queried || common=$(git merge-base --all
$head $actual_parents)
+ case "$common" in
+ ?*"$LF"?*)
+ # We are not doing octopus and not fast forward. Need a
+ # real merge.
+ ;;
+ *)
+ git update-index --refresh 2>/dev/null
+ if test "$allow_trivial_merge" = t
+ then
+ # 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 &&
+ 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
+ ) || exit
+ finish "$result_commit" "In-index merge"
+ dropsave
+ exit 0
+ fi
+ echo "Nope."
+ fi ;;
+ esac ;;
esac
# We are going to make a new commit.
@@ -460,7 +484,7 @@ do
# Remember which strategy left the state in the working tree
wt_strategy=$strategy
- git-merge-$strategy $common -- "$head_arg" "$@"
+ git-merge-$strategy $common -- "$head_arg" $actual_parents
exit=$?
if test "$no_commit" = t && test "$exit" = 0
then
@@ -530,7 +554,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" "$@"
+ git-merge-$best_strategy $common -- "$head_arg" $actual_parents
;;
esac
--
Sverre Hvammen Johansen
reply other threads:[~2008-03-31 4:30 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
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=402c10cd0803302129o396e5d37u944f76cd345d672@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).