git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: David Greene <greened@obbligato.org>
To: git@vger.kernel.org
Cc: john@keeping.me.uk, sandals@crustytoothpaste.net, peff@peff.net,
	gitster@pobox.com, "David A. Greene" <greened@obbligato.org>
Subject: [PATCH] Support rebase --keep-empty and --keep-redundant
Date: Tue, 15 Dec 2015 21:02:46 -0600	[thread overview]
Message-ID: <1450234966-28796-2-git-send-email-greened@obbligato.org> (raw)
In-Reply-To: <1450234966-28796-1-git-send-email-greened@obbligato.org>

From: "David A. Greene" <greened@obbligato.org>

Teach rebase how to invoke cherry-pick to keep empty commits.

Add a new option --keep-redundant equivalent to cherry-pick's
--keep-redundant-commits.  With this option, rebase will
preserve empty commits generated as a result of the merging
process.

Signed-off-by: David A. Greene <greened@obbligato.org>
---
 git-rebase--interactive.sh |  11 +++-
 git-rebase.sh              |   5 ++
 t/t3427-rebase-empty.sh    | 127 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100755 t/t3427-rebase-empty.sh

diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh
index b938a6d..8466cb9 100644
--- a/git-rebase--interactive.sh
+++ b/git-rebase--interactive.sh
@@ -393,7 +393,16 @@ pick_one_preserving_merges () {
 			echo "$sha1 $(git rev-parse HEAD^0)" >> "$rewritten_list"
 			;;
 		*)
-			output eval git cherry-pick \
+			cherry_keep_empty=
+			if test -n "$keep_empty"; then
+				cherry_keep_empty="--allow-empty"
+			fi
+			cherry_keep_redundant=
+			if test -n "$keep_redundant"; then
+				cherry_keep_redundant="--keep-redundant-commits"
+			fi
+			output eval git cherry-pick "$cherry_keep_empty" \
+				"$cherry_keep_redundant" \
 				${gpg_sign_opt:+$(git rev-parse --sq-quote "$gpg_sign_opt")} \
 				"$strategy_args" "$@" ||
 				die_with_patch $sha1 "Could not pick $sha1"
diff --git a/git-rebase.sh b/git-rebase.sh
index af7ba5f..1eae688 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -24,6 +24,7 @@ m,merge!           use merging strategies to rebase
 i,interactive!     let the user edit the list of commits to rebase
 x,exec=!           add exec lines after each commit of the editable list
 k,keep-empty	   preserve empty commits during rebase
+keep-redundant     preserve redundant commits during rebase
 f,force-rebase!    force rebase even if branch is up to date
 X,strategy-option=! pass the argument through to the merge strategy
 stat!              display a diffstat of what changed upstream
@@ -86,6 +87,7 @@ action=
 preserve_merges=
 autosquash=
 keep_empty=
+keep_redundant=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
 gpg_sign_opt=
 
@@ -255,6 +257,9 @@ do
 	--keep-empty)
 		keep_empty=yes
 		;;
+	--keep-redundant)
+		keep_redundant=yes
+		;;
 	--preserve-merges)
 		preserve_merges=t
 		test -z "$interactive_rebase" && interactive_rebase=implied
diff --git a/t/t3427-rebase-empty.sh b/t/t3427-rebase-empty.sh
new file mode 100755
index 0000000..9e67e00
--- /dev/null
+++ b/t/t3427-rebase-empty.sh
@@ -0,0 +1,127 @@
+#!/bin/sh
+
+test_description='git rebase tests for empty commits
+
+This test runs git rebase and tests handling of empty commits.
+'
+. ./test-lib.sh
+
+addfile() {
+    name=$1
+    echo $(basename ${name}) > ${name}
+    ${git} add ${name}
+    ${git} commit -m "Add $(basename ${name})"
+}
+
+check_equal()
+{
+	test_debug 'echo'
+	test_debug "echo \"check a:\" \"{$1}\""
+	test_debug "echo \"      b:\" \"{$2}\""
+	if [ "$1" = "$2" ]; then
+		return 0
+	else
+		return 1
+	fi
+}
+
+last_commit_message()
+{
+	git log --pretty=format:%s -1
+}
+
+test_expect_success 'setup' '
+	test_commit README &&
+	mkdir files &&
+	cd files &&
+	git init &&
+	test_commit master1 &&
+	test_commit master2 &&
+	test_commit master3 &&
+	cd .. &&
+	test_debug "echo Add project master to master" &&
+	git fetch files master &&
+	git branch files-master FETCH_HEAD &&
+	test_debug "echo Add subtree master to master via subtree" &&
+	git read-tree --prefix=files_subtree files-master &&
+	git checkout -- files_subtree &&
+	tree=$(git write-tree) &&
+	head=$(git rev-parse HEAD) &&
+	rev=$(git rev-parse --verify files-master^0) &&
+	commit=$(git commit-tree -p ${head} -p ${rev} -m "Add subproject master" ${tree}) &&
+	git reset ${commit} &&
+	cd files_subtree &&
+	test_commit master4 &&
+	cd .. &&
+	test_commit files_subtree/master5
+'
+
+# Does not preserve master4 and master5.
+#test_expect_success 'Rebase default' '
+#	git checkout -b rebase-default master &&
+#	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+#	git commit -m "Empty commit" --allow-empty &&
+#	git rebase -Xsubtree=files_subtree  --preserve-merges --onto files-master master &&
+#	check_equal "$(last_commit_message)" "files_subtree/master5"
+#'
+
+test_expect_success 'Rebase --root' '
+	git checkout -b rebase-default-root master &&
+	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+	git commit -m "Empty commit" --allow-empty &&
+	test_must_fail git rebase -Xsubtree=files_subtree  --preserve-merges --onto files-master --root &&
+	git rebase --abort
+'
+
+# Does not preserve master4, master5 and empty.
+#test_expect_success 'Rebase --keep-empty' '
+#	git checkout -b rebase-keep-empty master &&
+#	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+#	git commit -m "Empty commit" --allow-empty &&
+#	git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master master &&
+#	check_equal "$(last_commit_message)" "Empty commit"
+#'
+
+test_expect_success 'Rebase --keep-empty --root' '
+	git checkout -b rebase-keep-empty-root master &&
+	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+	git commit -m "Empty commit" --allow-empty &&
+	test_must_fail git rebase -Xsubtree=files_subtree --keep-empty --preserve-merges --onto files-master --root &&
+	git rebase --abort
+'
+
+# Does not preserve master4 and master5.
+#test_expect_success 'Rebase --keep-redundant' '
+#	git checkout -b rebase-keep-redundant master &&
+#	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+#	git commit -m "Empty commit" --allow-empty &&
+#	git rebase -Xsubtree=files_subtree --keep-redundant --preserve-merges --onto files-master master &&
+#	check_equal "$(last_commit_message)" "files_subtree/master5"
+#'
+
+test_expect_success 'Rebase --keep-redundant --root' '
+	git checkout -b rebase-keep-redundant-root master &&
+	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+	git commit -m "Empty commit" --allow-empty &&
+	git rebase -Xsubtree=files_subtree --keep-redundant --preserve-merges --onto files-master --root &&
+	check_equal "$(last_commit_message)" "files_subtree/master5"
+'
+
+# Does not preserve master4, master5 and empty.
+#test_expect_success 'Rebase --keep-empty --keep-redundant' '
+#	git checkout -b rebase-keep-empty-keep-redundant master &&
+#	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+#	git commit -m "Empty commit" --allow-empty &&
+#	git rebase -Xsubtree=files_subtree --keep-empty --keep-redundant --preserve-merges --onto files-master master &&
+#	check_equal "$(last_commit_message)" "Empty commit"
+#'
+
+test_expect_success 'Rebase --keep-empty --keep-redundant --root' '
+	git checkout -b rebase-keep-empty-keep-redundant-root master &&
+	git filter-branch --prune-empty -f --subdirectory-filter files_subtree &&
+	git commit -m "Empty commit" --allow-empty &&
+	git rebase -Xsubtree=files_subtree --keep-empty --keep-redundant --preserve-merges --onto files-master --root &&
+	check_equal "$(last_commit_message)" "Empty commit"
+'
+
+test_done
-- 
2.6.1

  reply	other threads:[~2015-12-16  3:03 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-12-16  3:02 (unknown), David Greene
2015-12-16  3:02 ` David Greene [this message]
2015-12-16  5:57 ` (unknown) Junio C Hamano
2015-12-16  8:44   ` (unknown) Patrick Steinhardt
2015-12-18 17:35     ` (unknown) David Greene

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=1450234966-28796-2-git-send-email-greened@obbligato.org \
    --to=greened@obbligato.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=john@keeping.me.uk \
    --cc=peff@peff.net \
    --cc=sandals@crustytoothpaste.net \
    /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).