2019-08-25 11:12:00 +02:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2019 Denton Liu
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='ensure rebase fast-forwards commits when possible'
|
|
|
|
|
|
|
|
. ./test-lib.sh
|
|
|
|
|
|
|
|
test_expect_success setup '
|
|
|
|
test_commit A &&
|
|
|
|
test_commit B &&
|
|
|
|
test_commit C &&
|
|
|
|
test_commit D &&
|
|
|
|
git checkout -t -b side
|
|
|
|
'
|
|
|
|
|
|
|
|
test_rebase_same_head () {
|
2019-08-27 07:37:53 +02:00
|
|
|
status_n="$1" &&
|
|
|
|
shift &&
|
|
|
|
what_n="$1" &&
|
|
|
|
shift &&
|
|
|
|
cmp_n="$1" &&
|
|
|
|
shift &&
|
|
|
|
status_f="$1" &&
|
|
|
|
shift &&
|
|
|
|
what_f="$1" &&
|
|
|
|
shift &&
|
|
|
|
cmp_f="$1" &&
|
|
|
|
shift &&
|
|
|
|
test_rebase_same_head_ $status_n $what_n $cmp_n "" "$*" &&
|
|
|
|
test_rebase_same_head_ $status_f $what_f $cmp_f " --no-ff" "$*"
|
|
|
|
}
|
|
|
|
|
|
|
|
test_rebase_same_head_ () {
|
2019-08-25 11:12:00 +02:00
|
|
|
status="$1" &&
|
|
|
|
shift &&
|
2019-08-25 11:12:02 +02:00
|
|
|
what="$1" &&
|
|
|
|
shift &&
|
|
|
|
cmp="$1" &&
|
|
|
|
shift &&
|
2019-08-27 07:37:53 +02:00
|
|
|
flag="$1"
|
|
|
|
shift &&
|
|
|
|
test_expect_$status "git rebase$flag $* with $changes is $what with $cmp HEAD" "
|
2019-08-25 11:12:00 +02:00
|
|
|
oldhead=\$(git rev-parse HEAD) &&
|
|
|
|
test_when_finished 'git reset --hard \$oldhead' &&
|
2019-08-27 07:37:53 +02:00
|
|
|
git rebase$flag $* >stdout &&
|
2019-08-25 11:12:02 +02:00
|
|
|
if test $what = work
|
|
|
|
then
|
2019-08-27 07:37:53 +02:00
|
|
|
# Must check this case first, for 'is up to
|
|
|
|
# date, rebase forced[...]rewinding head' cases
|
2019-08-25 11:12:02 +02:00
|
|
|
test_i18ngrep 'rewinding head' stdout
|
|
|
|
elif test $what = noop
|
|
|
|
then
|
2019-08-27 07:37:53 +02:00
|
|
|
test_i18ngrep 'is up to date' stdout &&
|
|
|
|
test_i18ngrep ! 'rebase forced' stdout
|
|
|
|
elif test $what = noop-force
|
|
|
|
then
|
|
|
|
test_i18ngrep 'is up to date, rebase forced' stdout
|
2019-08-25 11:12:02 +02:00
|
|
|
fi &&
|
2019-08-25 11:12:00 +02:00
|
|
|
newhead=\$(git rev-parse HEAD) &&
|
2019-08-25 11:12:02 +02:00
|
|
|
if test $cmp = same
|
|
|
|
then
|
|
|
|
test_cmp_rev \$oldhead \$newhead
|
|
|
|
elif test $cmp = diff
|
|
|
|
then
|
2019-11-13 00:07:45 +01:00
|
|
|
test_cmp_rev ! \$oldhead \$newhead
|
2019-08-25 11:12:02 +02:00
|
|
|
fi
|
2019-08-25 11:12:00 +02:00
|
|
|
"
|
|
|
|
}
|
|
|
|
|
|
|
|
changes='no changes'
|
2019-08-27 07:38:01 +02:00
|
|
|
test_rebase_same_head success noop same success work same
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same master
|
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B B
|
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B... B
|
|
|
|
test_rebase_same_head success noop same success noop-force same --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base master
|
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --no-fork-point
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
|
2019-08-27 07:38:01 +02:00
|
|
|
test_rebase_same_head success noop same success work same --fork-point master
|
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --onto B B
|
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --onto B... B
|
|
|
|
test_rebase_same_head success noop same success work same --fork-point --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success work same --keep-base --keep-base master
|
2019-08-25 11:12:00 +02:00
|
|
|
|
2019-08-25 11:12:02 +02:00
|
|
|
test_expect_success 'add work same to side' '
|
2019-08-25 11:12:00 +02:00
|
|
|
test_commit E
|
|
|
|
'
|
|
|
|
|
|
|
|
changes='our changes'
|
2019-08-27 07:38:01 +02:00
|
|
|
test_rebase_same_head success noop same success work same
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same master
|
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B B
|
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B... B
|
|
|
|
test_rebase_same_head success noop same success noop-force same --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base master
|
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --no-fork-point
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force same --keep-base --no-fork-point
|
2019-08-27 07:38:01 +02:00
|
|
|
test_rebase_same_head success noop same success work same --fork-point master
|
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --onto B B
|
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --onto B... B
|
|
|
|
test_rebase_same_head success noop same success work same --fork-point --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success work same --fork-point --keep-base master
|
2019-08-25 11:12:00 +02:00
|
|
|
|
2019-08-25 11:12:02 +02:00
|
|
|
test_expect_success 'add work same to upstream' '
|
2019-08-25 11:12:00 +02:00
|
|
|
git checkout master &&
|
|
|
|
test_commit F &&
|
|
|
|
git checkout side
|
|
|
|
'
|
|
|
|
|
|
|
|
changes='our and their changes'
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B B
|
|
|
|
test_rebase_same_head success noop same success noop-force diff --onto B... B
|
rebase: fast-forward --onto in more cases
Before, when we had the following graph,
A---B---C (master)
\
D (side)
running 'git rebase --onto master... master side' would result in D
being always rebased, no matter what. However, the desired behavior is
that rebase should notice that this is fast-forwardable and do that
instead.
Add detection to `can_fast_forward` so that this case can be detected
and a fast-forward will be performed. First of all, rewrite the function
to use gotos which simplifies the logic. Next, since the
options.upstream &&
!oidcmp(&options.upstream->object.oid, &options.onto->object.oid)
conditions were removed in `cmd_rebase`, we reintroduce a substitute in
`can_fast_forward`. In particular, checking the merge bases of
`upstream` and `head` fixes a failing case in t3416.
The abbreviated graph for t3416 is as follows:
F---G topic
/
A---B---C---D---E master
and the failing command was
git rebase --onto master...topic F topic
Before, Git would see that there was one merge base (C), and the merge
and onto were the same so it would incorrectly return 1, indicating that
we could fast-forward. This would cause the rebased graph to be 'ABCFG'
when we were expecting 'ABCG'.
With the additional logic, we detect that upstream and head's merge base
is F. Since onto isn't F, it means we're not rebasing the full set of
commits from master..topic. Since we're excluding some commits, a
fast-forward cannot be performed and so we correctly return 0.
Add '-f' to test cases that failed as a result of this change because
they were not expecting a fast-forward so that a rebase is forced.
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:37:59 +02:00
|
|
|
test_rebase_same_head success noop same success work diff --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success work diff --keep-base master
|
|
|
|
test_rebase_same_head success noop same success work diff --keep-base
|
2019-08-27 07:37:53 +02:00
|
|
|
test_rebase_same_head failure work same success work diff --fork-point --onto B B
|
|
|
|
test_rebase_same_head failure work same success work diff --fork-point --onto B... B
|
rebase: fast-forward --onto in more cases
Before, when we had the following graph,
A---B---C (master)
\
D (side)
running 'git rebase --onto master... master side' would result in D
being always rebased, no matter what. However, the desired behavior is
that rebase should notice that this is fast-forwardable and do that
instead.
Add detection to `can_fast_forward` so that this case can be detected
and a fast-forward will be performed. First of all, rewrite the function
to use gotos which simplifies the logic. Next, since the
options.upstream &&
!oidcmp(&options.upstream->object.oid, &options.onto->object.oid)
conditions were removed in `cmd_rebase`, we reintroduce a substitute in
`can_fast_forward`. In particular, checking the merge bases of
`upstream` and `head` fixes a failing case in t3416.
The abbreviated graph for t3416 is as follows:
F---G topic
/
A---B---C---D---E master
and the failing command was
git rebase --onto master...topic F topic
Before, Git would see that there was one merge base (C), and the merge
and onto were the same so it would incorrectly return 1, indicating that
we could fast-forward. This would cause the rebased graph to be 'ABCFG'
when we were expecting 'ABCG'.
With the additional logic, we detect that upstream and head's merge base
is F. Since onto isn't F, it means we're not rebasing the full set of
commits from master..topic. Since we're excluding some commits, a
fast-forward cannot be performed and so we correctly return 0.
Add '-f' to test cases that failed as a result of this change because
they were not expecting a fast-forward so that a rebase is forced.
Helped-by: Phillip Wood <phillip.wood@dunelm.org.uk>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:37:59 +02:00
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --onto master... master
|
rebase: teach rebase --keep-base
A common scenario is if a user is working on a topic branch and they
wish to make some changes to intermediate commits or autosquash, they
would run something such as
git rebase -i --onto master... master
in order to preserve the merge base. This is useful when contributing a
patch series to the Git mailing list, one often starts on top of the
current 'master'. While developing the patches, 'master' is also
developed further and it is sometimes not the best idea to keep rebasing
on top of 'master', but to keep the base commit as-is.
In addition to this, a user wishing to test individual commits in a
topic branch without changing anything may run
git rebase -x ./test.sh master... master
Since rebasing onto the merge base of the branch and the upstream is
such a common case, introduce the --keep-base option as a shortcut.
This allows us to rewrite the above as
git rebase -i --keep-base master
and
git rebase -x ./test.sh --keep-base master
respectively.
Add tests to ensure --keep-base works correctly in the normal case and
fails when there are multiple merge bases, both in regular and
interactive mode. Also, test to make sure conflicting options cause
rebase to fail. While we're adding test cases, add a missing
set_fake_editor call to 'rebase -i --onto master...side'.
While we're documenting the --keep-base option, change an instance of
"merge-base" to "merge base", which is the consistent spelling.
Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Helped-by: Junio C Hamano <gitster@pobox.com>
Helped-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Helped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>
Signed-off-by: Denton Liu <liu.denton@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2019-08-27 07:38:06 +02:00
|
|
|
test_rebase_same_head success noop same success work diff --fork-point --keep-base master
|
2019-08-25 11:12:00 +02:00
|
|
|
|
|
|
|
test_done
|