# Copyright (c) 2005 Junio C Hamano
#
-USAGE='[-n] [--summary] [--no-commit] [--squash] [-s <strategy>] [-m=<merge-message>] <commit>+'
+USAGE='[-n] [--summary] [--[no-]commit] [--[no-]squash] [--[no-]ff] [-s <strategy>] [-m=<merge-message>] <commit>+'
SUBDIRECTORY_OK=Yes
. git-sh-setup
all_strategies='recur recursive octopus resolve stupid ours subtree'
default_twohead_strategies='recursive'
default_octopus_strategies='octopus'
-no_trivial_merge_strategies='ours subtree'
+no_fast_forward_strategies='subtree ours'
+no_trivial_strategies='recursive recur subtree ours'
use_strategies=
-index_merge=t
+allow_fast_forward=t
+allow_trivial_merge=t
dropsave() {
rm -f -- "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/MERGE_MSG" \
squash_message () {
echo Squashed commit of the following:
echo
- git log --no-merges ^"$head" $remote
+ git log --no-merges ^"$head" $remoteheads
}
finish () {
;;
*)
git update-ref -m "$rlogm" HEAD "$1" "$head" || exit 1
+ git gc --auto
;;
esac
;;
fi
;;
esac
+
+ # Run a post-merge hook
+ if test -x "$GIT_DIR"/hooks/post-merge
+ then
+ case "$squash" in
+ t)
+ "$GIT_DIR"/hooks/post-merge 1
+ ;;
+ '')
+ "$GIT_DIR"/hooks/post-merge 0
+ ;;
+ esac
+ fi
}
merge_name () {
fi
}
-case "$#" in 0) usage ;; esac
-
-have_message=
-while case "$#" in 0) break ;; esac
-do
+parse_option () {
case "$1" in
-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
--no-summa|--no-summar|--no-summary)
--summary)
show_diffstat=t ;;
--sq|--squ|--squa|--squas|--squash)
- squash=t no_commit=t ;;
+ allow_fast_forward=t squash=t no_commit=t ;;
+ --no-sq|--no-squ|--no-squa|--no-squas|--no-squash)
+ allow_fast_forward=t squash= no_commit= ;;
+ --c|--co|--com|--comm|--commi|--commit)
+ allow_fast_forward=t squash= no_commit= ;;
--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
- no_commit=t ;;
+ allow_fast_forward=t squash= no_commit=t ;;
+ --ff)
+ allow_fast_forward=t squash= no_commit= ;;
+ --no-ff)
+ allow_fast_forward=false squash= no_commit= ;;
-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
--strateg=*|--strategy=*|\
-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
have_message=t
;;
-*) usage ;;
- *) break ;;
+ *) return 1 ;;
esac
shift
+ args_left=$#
+}
+
+parse_config () {
+ while test $# -gt 0
+ do
+ parse_option "$@" || usage
+ while test $args_left -lt $#
+ do
+ shift
+ done
+ done
+}
+
+test $# != 0 || usage
+
+have_message=
+
+if branch=$(git-symbolic-ref -q HEAD)
+then
+ mergeopts=$(git config "branch.${branch#refs/heads/}.mergeoptions")
+ if test -n "$mergeopts"
+ then
+ parse_config $mergeopts
+ fi
+fi
+
+while parse_option "$@"
+do
+ while test $args_left -lt $#
+ do
+ shift
+ done
done
if test -z "$show_diffstat"; then
for s in $use_strategies
do
- for nt in $no_trivial_merge_strategies
+ for ss in $no_fast_forward_strategies
+ do
+ case " $s " in
+ *" $ss "*)
+ allow_fast_forward=f
+ break
+ ;;
+ esac
+ done
+ for ss in $no_trivial_strategies
do
case " $s " in
- *" $nt "*)
- index_merge=f
+ *" $ss "*)
+ allow_trivial_merge=f
break
;;
esac
esac
echo "$head" >"$GIT_DIR/ORIG_HEAD"
-case "$index_merge,$#,$common,$no_commit" in
-f,*)
- # We've been told not to try anything clever. Skip to real merge.
- ;;
+case "$allow_fast_forward,$#,$common,$no_commit" in
?,*,'',*)
# No common ancestors found. We need a real merge.
;;
finish_up_to_date "Already up-to-date."
exit 0
;;
-?,1,"$head",*)
+t,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
# We are not doing octopus, not fast forward, and have only
# one common.
git update-index --refresh 2>/dev/null
- case " $use_strategies " in
- *' recursive '*|*' recur '*)
- : run merge later
- ;;
- *)
+ 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..."
# auto resolved the merge cleanly.
if test '' != "$result_tree"
then
- parents=$(git show-branch --independent "$head" "$@" | sed -e 's/^/-p /')
+ if test "$allow_fast_forward" = "t"
+ 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