1. mirror
  2. git

Commits

Junio C Hamano  committed 1ef9e05 Merge

Merge branch 'jc/squash'

* jc/squash:
git-merge --squash

  • Participants
  • Parent commits 6a0dbb8, 7d0c688
  • Branches master

Comments (0)

Files changed (5)

File Documentation/merge-options.txt

View file
 	not autocommit, to give the user a chance to inspect and
 	further tweak the merge result before committing.
 
+--squash::
+	Produce the working tree and index state as if a real
+	merge happened, but do not actually make a commit or
+	move the `HEAD`, nor record `$GIT_DIR/MERGE_HEAD` to
+	cause the next `git commit` command to create a merge
+	commit.  This allows you to create a single commit on
+	top of the current branch whose effect is the same as
+	merging another branch (or more in case of an octopus).
 
 -s <strategy>, \--strategy=<strategy>::
 	Use the given merge strategy; can be supplied more than

File git-commit.sh

View file
 elif test -f "$GIT_DIR/MERGE_HEAD" && test -f "$GIT_DIR/MERGE_MSG"
 then
 	cat "$GIT_DIR/MERGE_MSG"
+elif test -f "$GIT_DIR/SQUASH_MSG"
+then
+	cat "$GIT_DIR/SQUASH_MSG"
 fi | git-stripspace >"$GIT_DIR"/COMMIT_EDITMSG
 
 case "$signoff" in
 fi
 if [ "$?" != "0" -a ! -f "$GIT_DIR/MERGE_HEAD" -a -z "$amend" ]
 then
-	rm -f "$GIT_DIR/COMMIT_EDITMSG"
+	rm -f "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
 	run_status
 	exit 1
 fi
 	false
 fi
 ret="$?"
-rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG"
+rm -f "$GIT_DIR/COMMIT_MSG" "$GIT_DIR/COMMIT_EDITMSG" "$GIT_DIR/SQUASH_MSG"
 if test -d "$GIT_DIR/rr-cache"
 then
 	git-rerere

File git-merge.sh

View file
 # Copyright (c) 2005 Junio C Hamano
 #
 
-
-USAGE='[-n] [--no-commit] [-s <strategy>]... <merge-message> <head> <remote>+'
+USAGE='[-n] [--no-commit] [--squash] [-s <strategy>]... <merge-message> <head> <remote>+'
 . git-sh-setup
 
 LF='
 	fi
 }
 
+finish_up_to_date () {
+	case "$squash" in
+	t)
+		echo "$1 (nothing to squash)" ;;
+	'')
+		echo "$1" ;;
+	esac
+	dropsave
+}
+
+squash_message () {
+	echo Squashed commit of the following:
+	echo
+	git-log --no-merges ^"$head" $remote
+}
+
 finish () {
 	test '' = "$2" || echo "$2"
-	case "$merge_msg" in
-	'')
-		echo "No merge message -- not updating HEAD"
+	case "$squash" in
+	t)
+		echo "Squash commit -- not updating HEAD"
+		squash_message >"$GIT_DIR/SQUASH_MSG"
 		;;
-	*)
-		git-update-ref HEAD "$1" "$head" || exit 1
+	'')
+		case "$merge_msg" in
+		'')
+			echo "No merge message -- not updating HEAD"
+			;;
+		*)
+			git-update-ref HEAD "$1" "$head" || exit 1
+			;;
+		esac
 		;;
 	esac
-
-	case "$no_summary" in
+	case "$1" in
 	'')
-		git-diff-tree --stat --summary -M "$head" "$1"
+		;;
+	?*)
+		case "$no_summary" in
+		'')
+			git-diff-tree --stat --summary -M "$head" "$1"
+			;;
+		esac
 		;;
 	esac
 }
 	-n|--n|--no|--no-|--no-s|--no-su|--no-sum|--no-summ|\
 		--no-summa|--no-summar|--no-summary)
 		no_summary=t ;;
+	--sq|--squ|--squa|--squas|--squash)
+		squash=t no_commit=t ;;
 	--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
 		no_commit=t ;;
 	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 ?,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.
-	echo "Already up-to-date."
-	dropsave
+	finish_up_to_date "Already up-to-date."
 	exit 0
 	;;
 ?,1,"$head",*)
 	done
 	if test "$up_to_date" = t
 	then
-		echo "Already up-to-date. Yeeah!"
-		dropsave
+		finish_up_to_date "Already up-to-date. Yeeah!"
 		exit 0
 	fi
 	;;
 	git-merge-$best_strategy $common -- "$head_arg" "$@"
 	;;
 esac
-for remote
-do
-	echo $remote
-done >"$GIT_DIR/MERGE_HEAD"
-echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
+
+if test "$squash" = t
+then
+	finish
+else
+	for remote
+	do
+		echo $remote
+	done >"$GIT_DIR/MERGE_HEAD"
+	echo "$merge_msg" >"$GIT_DIR/MERGE_MSG"
+fi
 
 if test "$merge_was_ok" = t
 then

File git-pull.sh

View file
 LONG_USAGE='Fetch one or more remote refs and merge it/them into the current HEAD.'
 . git-sh-setup
 
-strategy_args= no_summary= no_commit=
+strategy_args= no_summary= no_commit= squash=
 while case "$#,$1" in 0) break ;; *,-*) ;; *) break ;; esac
 do
 	case "$1" in
 		no_summary=-n ;;
 	--no-c|--no-co|--no-com|--no-comm|--no-commi|--no-commit)
 		no_commit=--no-commit ;;
+	--sq|--squ|--squa|--squas|--squash)
+		squash=--squash ;;
 	-s=*|--s=*|--st=*|--str=*|--stra=*|--strat=*|--strate=*|\
 		--strateg=*|--strategy=*|\
 	-s|--s|--st|--str|--stra|--strat|--strate|--strateg|--strategy)
 esac
 
 merge_name=$(git-fmt-merge-msg <"$GIT_DIR/FETCH_HEAD") || exit
-git-merge $no_summary $no_commit $strategy_args "$merge_name" HEAD $merge_head
+git-merge $no_summary $no_commit $squash $strategy_args \
+	"$merge_name" HEAD $merge_head

File git-reset.sh

View file
 	;;
 esac
 
-rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR"
+rm -f "$GIT_DIR/MERGE_HEAD" "$GIT_DIR/rr-cache/MERGE_RR" "$GIT_DIR/SQUASH_MSG"