diff options
-rw-r--r-- | Documentation/merge-options.txt | 8 | ||||
-rwxr-xr-x | git-commit.sh | 7 | ||||
-rwxr-xr-x | git-merge.sh | 72 | ||||
-rwxr-xr-x | git-pull.sh | 7 | ||||
-rwxr-xr-x | git-reset.sh | 2 |
5 files changed, 72 insertions, 24 deletions
diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 53cc35590d..182cef54be 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -6,6 +6,14 @@ 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 diff --git a/git-commit.sh b/git-commit.sh index 128db6c52a..d7f3ade493 100755 --- a/git-commit.sh +++ b/git-commit.sh @@ -566,6 +566,9 @@ then 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 @@ -663,7 +666,7 @@ else 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 @@ -734,7 +737,7 @@ else 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 diff --git a/git-merge.sh b/git-merge.sh index da5657eb40..fc25f8dda0 100755 --- a/git-merge.sh +++ b/git-merge.sh @@ -3,8 +3,7 @@ # 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=' @@ -42,20 +41,49 @@ restorestate() { 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 } @@ -66,6 +94,8 @@ do -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=*|\ @@ -152,8 +182,7 @@ f,*) ?,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",*) @@ -205,8 +234,7 @@ f,*) 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 ;; @@ -310,11 +338,17 @@ case "$best_strategy" in 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 diff --git a/git-pull.sh b/git-pull.sh index bdd3939923..aa8c208092 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -8,7 +8,7 @@ USAGE='[-n | --no-summary] [--no-commit] [-s strategy]... [<fetch-options>] <rep 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 @@ -17,6 +17,8 @@ do 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) @@ -100,4 +102,5 @@ case "$strategy_args" in 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 diff --git a/git-reset.sh b/git-reset.sh index 296f3b779b..46451d0d64 100755 --- a/git-reset.sh +++ b/git-reset.sh @@ -61,4 +61,4 @@ case "$reset_type" in ;; 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" |