# [PATCH] rebase: introduce "rebase.preserve" configuration option

2 messages from 2014-08-05 to 2014-08-05. Participants: Ralf Thielow, Junio C Hamano.
Thread: https://gitlist.dev/t/37293

## Ralf Thielow, 2014-08-05 20:48

Subject: [PATCH] rebase: introduce "rebase.preserve" configuration option
Message-ID: <1407271714-1624-1-git-send-email-ralf.thielow@gmail.com>
URL: https://gitlist.dev/e/1407271714-1624-1-git-send-email-ralf.thielow%40gmail.com

```
There are several ways to configure Git to preserve merges.
There is "pull.rebase=preserve" for all branches and
"branch.<name>.rebase=preserve" for individual branches.
However, there is no configuration option to preserve merges
for all branches when running git-rebase.

This patch introduces a new configuration variable
"rebase.preserve". If set to true, "--preserve-merges" option
will be enabled in git-rebase by default.

Signed-off-by: Ralf Thielow <ralf.thielow@gmail.com>
---
 Documentation/config.txt          |  3 +++
 git-rebase.sh                     |  1 +
 t/t3409-rebase-preserve-merges.sh | 20 ++++++++++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/Documentation/config.txt b/Documentation/config.txt
index c08286e..4166be0 100644
--- a/Documentation/config.txt
+++ b/Documentation/config.txt
@@ -2031,6 +2031,9 @@ rebase.autostash::
 	successful rebase might result in non-trivial conflicts.
 	Defaults to false.
 
+rebase.preserve::
+	If set to true enable '--preserve-merges' option by default.
+
 receive.autogc::
 	By default, git-receive-pack will run "git-gc --auto" after
 	receiving data from git-push and updating refs.  You can stop
diff --git a/git-rebase.sh b/git-rebase.sh
index 47ca3b9..e0b3e05 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -83,6 +83,7 @@ state_dir=
 # One of {'', continue, skip, abort}, as parsed from command line
 action=
 preserve_merges=
+test "$(git config --bool rebase.preserve)" = "true" && preserve_merges=t && interactive_rebase=implied
 autosquash=
 keep_empty=
 test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t
diff --git a/t/t3409-rebase-preserve-merges.sh b/t/t3409-rebase-preserve-merges.sh
index 8c251c5..3a02240 100755
--- a/t/t3409-rebase-preserve-merges.sh
+++ b/t/t3409-rebase-preserve-merges.sh
@@ -76,6 +76,16 @@ test_expect_success 'setup for merge-preserving rebase' \
 		git merge --no-ff topic2
 	) &&
 
+	git clone ./. clone5 &&
+	(
+		cd clone5 &&
+		git checkout -b topic2 origin/topic &&
+		echo Sixth > A &&
+		git commit -a -m "Modify A3" &&
+		git checkout -b topic origin/topic &&
+		git merge --no-ff topic2
+	) &&
+
 	git checkout topic &&
 	echo Fourth >> B &&
 	git commit -a -m "Modify B2"
@@ -119,4 +129,14 @@ test_expect_success 'rebase -p ignores merge.log config' '
 	)
 '
 
+test_expect_success 'config rebase.preserve preserves no-ff merges' '
+	(
+	cd clone5 &&
+	git fetch &&
+	git -c rebase.preserve=true rebase origin/topic &&
+	test 3 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
+	test 1 = $(git rev-list --all --pretty=oneline | grep "Merge branch" | wc -l)
+	)
+'
+
 test_done
-- 
2.1.0.rc1.205.gf9880d1

```

## Junio C Hamano, 2014-08-05 22:39

Subject: Re: [PATCH] rebase: introduce "rebase.preserve" configuration option
Message-ID: <xmqq61i6o92k.fsf@gitster.dls.corp.google.com>
URL: https://gitlist.dev/e/xmqq61i6o92k.fsf%40gitster.dls.corp.google.com
In-Reply-To: <1407271714-1624-1-git-send-email-ralf.thielow@gmail.com>

```
Ralf Thielow <ralf.thielow@gmail.com> writes:

> There are several ways to configure Git to preserve merges.
> There is "pull.rebase=preserve" for all branches and
> "branch.<name>.rebase=preserve" for individual branches.
> However, there is no configuration option to preserve merges
> for all branches when running git-rebase.

How should this interact with pull.rebase?  Specifically, what
should happen with these settings?

	[rebase] preserve = true
        [pull] rebase = true

Historically, the variable was a way to tell 'pull' to use 'rebase'
to integrate (if true) or use 'merge' to integrate (if false), and
then the third value that is clearly not 'false' was added to say
"How should the underlying 'rebase' integrate the local and the
remote histories?".

In that light, one can argue 'git pull' with the above two should
run 'rebase --preserve'.  In other words, rebase.preserve tells us
"When 'rebase' is told to run, it should do the 'preserving'
variant."

But then when somebody sets pull.rebase to true, expecting that
'true' does not just mean "Yup, please use rebase, I do not like
merges", but means "Use rebase without preserve", it would be hard
to debug if the behaviour of 'git pull' is affected by a separate
variable rebase.preserve that may be defined in a far-away place in
the configuration file.

I dunno.  This kind of complications is one reason why I wouldn't
encourage adding these configurations to affect the behaviours of
commands.

```
