All of lore.kernel.org
 help / color / mirror / 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

* 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.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.