[RFC/PATCH] Add git-squash tool and tests

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Stephan Beyer
Date: Monday, June 9, 2008 - 1:29 pm

git-squash is a simple command that, given the parent commit of X,
squashes the commits X..HEAD into one.

Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
---
Hi,

perhaps this is a little surprising, but because of:
I thought it could be right to quickly write this as a script.

Here it is as RFC, yet without documentation.

Junio, this could be a backend for the zucchini instruction, by just
 zucchini <n>  =>  git-squash "HEAD~$(expr $n + 1)"   ;-)

 Makefile          |    1 +
 command-list.txt  |    1 +
 git-squash.sh     |   77 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 t/t3150-squash.sh |   66 +++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 145 insertions(+), 0 deletions(-)
 create mode 100755 git-squash.sh
 create mode 100755 t/t3150-squash.sh

diff --git a/Makefile b/Makefile
index 1937507..863004b 100644
--- a/Makefile
+++ b/Makefile
@@ -251,6 +251,7 @@ SCRIPT_SH += git-rebase.sh
 SCRIPT_SH += git-repack.sh
 SCRIPT_SH += git-request-pull.sh
 SCRIPT_SH += git-sh-setup.sh
+SCRIPT_SH += git-squash.sh
 SCRIPT_SH += git-stash.sh
 SCRIPT_SH += git-submodule.sh
 SCRIPT_SH += git-web--browse.sh
diff --git a/command-list.txt b/command-list.txt
index 3583a33..e342da3 100644
--- a/command-list.txt
+++ b/command-list.txt
@@ -108,6 +108,7 @@ git-show-branch                         ancillaryinterrogators
 git-show-index                          plumbinginterrogators
 git-show-ref                            plumbinginterrogators
 git-sh-setup                            purehelpers
+git-squash                              mainporcelain
 git-stash                               mainporcelain
 git-status                              mainporcelain common
 git-stripspace                          purehelpers
diff --git a/git-squash.sh b/git-squash.sh
new file mode 100755
index 0000000..64b5949
--- /dev/null
+++ b/git-squash.sh
@@ -0,0 +1,77 @@
+#!/bin/sh
+#
+# Squash commits from HEAD up to ... into one commit.
+
+SUBDIRECTORY_OK=Yes
+OPTIONS_KEEPDASHDASH=
+OPTIONS_SPEC="\
+git-squash [options] <commit-ish>
+--
+author=           use author <author>
+C,reuse-message=  use commit data from <commit-ish>
+F,file=           use commit message in <file>
+m,message=        use commit message <msg>
+e,edit            force edit of commit message
+s,signoff         add Signed-off-by:
+include-merges    don't fail if merge is in between
+"
+
+. git-sh-setup
+require_work_tree
+
+# test if working tree is clean
+git rev-parse --verify HEAD >/dev/null &&
+git update-index --refresh &&
+git diff-files --quiet &&
+git diff-index --cached --quiet HEAD -- ||
+	die "Working tree is dirty"
+
+git var GIT_COMMITTER_IDENT >/dev/null ||
+	die "You need to set your committer info first"
+
+HEAD=$(git rev-parse --verify HEAD) ||
+	die "No HEAD?"
+
+commitstr="git commit "
+merges=
+while test $# -gt 1
+do
+	case "$1" in
+	-m|-F|-C|--author)
+		commitstr="$commitstr $1 '$2'"
+		shift
+		;;
+	-e|-s)
+		commitstr="$commitstr $1"
+		;;
+	--include-merges)
+		merges=y
+		;;
+	--)
+		break
+		;;
+	esac
+	shift
+done
+
+test $# -gt 2 &&
+	die "Wrong number of arguments."
+test $# -lt 2 &&
+	die "No commit given."
+shift
+
+commit="$1"
+git rev-parse --verify "$commit" >/dev/null ||
+	die "$commit is no valid commit."
+
+# check for merges if no --include-merges given
+test -z "$merges" &&
+git log "$commit.." | grep -q "^Merge:" &&
+	die "$commit..HEAD contains a merge commit. You may try --include-merges."
+
+# reset and commit
+git reset --soft "$commit"
+eval "$commitstr" || {
+	git reset --hard $HEAD
+	die "Commit failed"
+}
diff --git a/t/t3150-squash.sh b/t/t3150-squash.sh
new file mode 100755
index 0000000..9f18995
--- /dev/null
+++ b/t/t3150-squash.sh
@@ -0,0 +1,66 @@
+#!/bin/sh
+
+test_description='git-squash'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+	: >file1 &&
+	: >file2 &&
+	: >file3 &&
+	: >file4 &&
+	: >file5 &&
+	: >file6 &&
+	git add file1 &&
+	git commit -m file1 &&
+	git add file2 &&
+	git commit -m file2 &&
+	git checkout -b master2 HEAD^ &&
+	git add file3 &&
+	git commit -m file3 &&
+	git checkout master &&
+	git merge master2 &&
+	git add file4 &&
+	git commit -m file4 &&
+	git add file5 &&
+	git commit -m file5 &&
+	git add file6 &&
+	git commit -m file6
+'
+
+test_expect_success 'git-squash HEAD^ is a nop and fails' '
+	git checkout -b first master &&
+	! git squash HEAD^ &&
+	test "$(git rev-parse HEAD)" = "$(git rev-parse first)" &&
+	test "$(git rev-parse master)" = "$(git rev-parse first)"
+'
+
+test_expect_success 'git-squash works' '
+	git checkout -b second master &&
+	git squash -m "file5 and file6" --signoff HEAD^^ &&
+	test "$(git rev-parse HEAD)" = "$(git rev-parse second)" &&
+	test -f file1 -a -f file2 -a -f file3 -a \
+	     -f file4 -a -f file5 -a -f file6
+'
+
+test_expect_success 'git-squash fails if merge in between' '
+	git checkout -b third master &&
+	! git squash -C master master2^ &&
+	test "$(git rev-parse HEAD)" = "$(git rev-parse third)" &&
+	test "$(git rev-parse master)" = "$(git rev-parse third)"
+'
+
+test_expect_success 'git-squash works with --include-merges if merge in between' '
+	git checkout -b fourth master &&
+	git squash -C master --include-merges master2^ &&
+	test "$(git rev-parse HEAD)" = "$(git rev-parse fourth)"
+'
+
+test_expect_success 'git-squash aborts correctly if no commit message given' '
+	git checkout -b fifth master &&
+	! git squash HEAD~2 &&
+	test "$(git rev-parse HEAD)" = "$(git rev-parse fifth)" &&
+	test "$(git rev-parse master)" = "$(git rev-parse fifth)"
+'
+
+test_done
-- 
1.5.5.3

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[RFC] git-sequencer.txt, Stephan Beyer, (Sat Jun 7, 3:01 pm)
squashing patches (was: Re: [RFC] git-sequencer.txt), Stephan Beyer, (Mon Jun 9, 4:45 am)
Re: squashing patches (was: Re: [RFC] git-sequencer.txt), Johannes Schindelin, (Mon Jun 9, 7:04 am)
Re: squashing patches, Paolo Bonzini, (Mon Jun 9, 8:10 am)
Re: squashing patches, Paolo Bonzini, (Mon Jun 9, 8:43 am)
Re: squashing patches, Stephan Beyer, (Mon Jun 9, 9:29 am)
Re: squashing patches, Paolo Bonzini, (Mon Jun 9, 9:37 am)
Re: [RFC] git-sequencer.txt, Jakub Narebski, (Mon Jun 9, 9:49 am)
Re: squashing patches, Junio C Hamano, (Mon Jun 9, 12:34 pm)
[RFC/PATCH] Add git-squash tool and tests, Stephan Beyer, (Mon Jun 9, 1:29 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Johannes Schindelin, (Mon Jun 9, 1:34 pm)
Re: squashing patches, Stephan Beyer, (Mon Jun 9, 1:43 pm)
Re: squashing patches, Jeff King, (Mon Jun 9, 1:53 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Paolo Bonzini, (Mon Jun 9, 1:53 pm)
Re: squashing patches, Junio C Hamano, (Mon Jun 9, 2:02 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Johannes Schindelin, (Mon Jun 9, 2:34 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Stephan Beyer, (Mon Jun 9, 4:42 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Stephan Beyer, (Mon Jun 9, 4:46 pm)
Re: squashing patches, Stephan Beyer, (Mon Jun 9, 4:57 pm)
Re: [RFC/PATCH] Add git-squash tool and tests, Johannes Schindelin, (Mon Jun 9, 5:26 pm)
Re: squashing patches, Stephan Beyer, (Mon Jun 9, 5:38 pm)
Re: squashing patches, Jeff King, (Mon Jun 9, 6:00 pm)
Re: [RFC] git-sequencer.txt, Stephan Beyer, (Mon Jun 9, 6:21 pm)
Re: [RFC] git-sequencer.txt, Christian Couder, (Mon Jun 9, 9:46 pm)
Re: [RFC] git-sequencer.txt, Jakub Narebski, (Mon Jun 9, 11:17 pm)
Re: [RFC] git-sequencer.txt, Stephan Beyer, (Tue Jun 10, 1:59 am)
Re: [RFC] git-sequencer.txt, Christian Couder, (Tue Jun 10, 9:10 pm)
Re: [RFC] git-sequencer.txt, Daniel Barkalow, (Wed Jun 11, 10:07 am)
[RFCv2/FYI] git-sequencer.txt, Stephan Beyer, (Wed Jun 11, 5:22 pm)
Re: [RFCv2/FYI] git-sequencer.txt, Paolo Bonzini, (Wed Jun 11, 6:31 pm)
Re: [RFCv2/FYI] git-sequencer.txt, Junio C Hamano, (Wed Jun 11, 10:16 pm)
Re: [RFCv2/FYI] git-sequencer.txt, Jakub Narebski, (Thu Jun 12, 7:10 am)
Re: [RFCv2/FYI] git-sequencer.txt, Stephan Beyer, (Thu Jun 12, 8:29 am)
Re: [RFCv2/FYI] git-sequencer.txt, Paolo Bonzini, (Thu Jun 12, 8:56 am)
Re: [RFCv2/FYI] git-sequencer.txt, Stephan Beyer, (Thu Jun 12, 10:07 am)
Re: [RFCv2/FYI] git-sequencer.txt, Stephan Beyer, (Thu Jun 12, 10:20 am)
Re: [RFCv2/FYI] git-sequencer.txt, Paolo Bonzini, (Thu Jun 12, 10:04 pm)
Re: [RFCv2/FYI] git-sequencer.txt, Stephan Beyer, (Fri Jun 13, 5:16 am)
Re: [RFCv2/FYI] git-sequencer.txt, Paolo Bonzini, (Fri Jun 13, 7:42 am)
Re: [RFCv2/FYI] git-sequencer.txt, Olivier Marin, (Fri Jun 13, 12:24 pm)