From: Stephan Beyer <s-beyer@gmx.net>
To: git@vger.kernel.org
Cc: Paolo Bonzini <bonzini@gnu.org>,
Junio C Hamano <gitster@pobox.com>,
Stephan Beyer <s-beyer@gmx.net>
Subject: [RFC/PATCH] Add git-squash tool and tests
Date: Mon, 9 Jun 2008 22:29:58 +0200 [thread overview]
Message-ID: <1213043398-30524-1-git-send-email-s-beyer@gmx.net> (raw)
In-Reply-To: <484D47C9.9050509@gnu.org>
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:
> This could be done by providing a stand-alone git-squash command;
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
next prev parent reply other threads:[~2008-06-09 20:31 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-06-07 22:01 [RFC] git-sequencer.txt Stephan Beyer
2008-06-09 11:45 ` squashing patches (was: Re: [RFC] git-sequencer.txt) Stephan Beyer
2008-06-09 14:04 ` Johannes Schindelin
2008-06-09 15:10 ` squashing patches Paolo Bonzini
2008-06-09 15:43 ` Paolo Bonzini
2008-06-09 16:29 ` Stephan Beyer
2008-06-09 16:37 ` Paolo Bonzini
2008-06-09 20:29 ` Stephan Beyer [this message]
2008-06-09 20:34 ` [RFC/PATCH] Add git-squash tool and tests Johannes Schindelin
2008-06-09 20:53 ` Paolo Bonzini
2008-06-09 21:34 ` Johannes Schindelin
2008-06-09 23:42 ` Stephan Beyer
2008-06-10 0:26 ` Johannes Schindelin
2008-06-09 23:46 ` Stephan Beyer
2008-06-09 19:34 ` squashing patches Junio C Hamano
2008-06-09 20:43 ` Stephan Beyer
2008-06-09 20:53 ` Jeff King
2008-06-09 23:57 ` Stephan Beyer
2008-06-10 1:00 ` Jeff King
2008-06-09 21:02 ` Junio C Hamano
2008-06-10 0:38 ` Stephan Beyer
2008-06-09 16:49 ` [RFC] git-sequencer.txt Jakub Narebski
2008-06-10 1:21 ` Stephan Beyer
2008-06-10 4:46 ` Christian Couder
2008-06-10 8:59 ` Stephan Beyer
2008-06-11 4:10 ` Christian Couder
2008-06-11 17:07 ` Daniel Barkalow
2008-06-10 6:17 ` Jakub Narebski
2008-06-12 0:22 ` [RFCv2/FYI] git-sequencer.txt Stephan Beyer
2008-06-12 1:31 ` Paolo Bonzini
2008-06-12 15:29 ` Stephan Beyer
2008-06-12 15:38 ` [RFC/PATCH] git-commit: Change --reuse-message to --reuse-commit Stephan Beyer
2008-06-12 15:56 ` [RFCv2/FYI] git-sequencer.txt Paolo Bonzini
2008-06-12 5:16 ` Junio C Hamano
2008-06-12 17:07 ` Stephan Beyer
2008-06-13 5:04 ` Paolo Bonzini
2008-06-13 12:16 ` Stephan Beyer
2008-06-13 14:42 ` Paolo Bonzini
2008-06-13 19:24 ` Olivier Marin
2008-06-12 14:10 ` Jakub Narebski
2008-06-12 17:20 ` Stephan Beyer
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1213043398-30524-1-git-send-email-s-beyer@gmx.net \
--to=s-beyer@gmx.net \
--cc=bonzini@gnu.org \
--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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).