rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Copyright (c) 2018 Johannes E. Schindelin
|
|
|
|
#
|
|
|
|
|
|
|
|
test_description='git rebase -i --rebase-merges
|
|
|
|
|
|
|
|
This test runs git rebase "interactively", retaining the branch structure by
|
|
|
|
recreating merge commits.
|
|
|
|
|
|
|
|
Initial setup:
|
|
|
|
|
|
|
|
-- B -- (first)
|
|
|
|
/ \
|
2020-11-18 23:44:25 +00:00
|
|
|
A - C - D - E - H (main)
|
2018-08-15 09:39:34 +00:00
|
|
|
\ \ /
|
|
|
|
\ F - G (second)
|
|
|
|
\
|
|
|
|
Conflicting-G
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
'
|
2020-11-18 23:44:25 +00:00
|
|
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
tests: mark tests relying on the current default for `init.defaultBranch`
In addition to the manual adjustment to let the `linux-gcc` CI job run
the test suite with `master` and then with `main`, this patch makes sure
that GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME is set in all test scripts
that currently rely on the initial branch name being `master by default.
To determine which test scripts to mark up, the first step was to
force-set the default branch name to `master` in
- all test scripts that contain the keyword `master`,
- t4211, which expects `t/t4211/history.export` with a hard-coded ref to
initialize the default branch,
- t5560 because it sources `t/t556x_common` which uses `master`,
- t8002 and t8012 because both source `t/annotate-tests.sh` which also
uses `master`)
This trick was performed by this command:
$ sed -i '/^ *\. \.\/\(test-lib\|lib-\(bash\|cvs\|git-svn\)\|gitweb-lib\)\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' $(git grep -l master t/t[0-9]*.sh) \
t/t4211*.sh t/t5560*.sh t/t8002*.sh t/t8012*.sh
After that, careful, manual inspection revealed that some of the test
scripts containing the needle `master` do not actually rely on a
specific default branch name: either they mention `master` only in a
comment, or they initialize that branch specificially, or they do not
actually refer to the current default branch. Therefore, the
aforementioned modification was undone in those test scripts thusly:
$ git checkout HEAD -- \
t/t0027-auto-crlf.sh t/t0060-path-utils.sh \
t/t1011-read-tree-sparse-checkout.sh \
t/t1305-config-include.sh t/t1309-early-config.sh \
t/t1402-check-ref-format.sh t/t1450-fsck.sh \
t/t2024-checkout-dwim.sh \
t/t2106-update-index-assume-unchanged.sh \
t/t3040-subprojects-basic.sh t/t3301-notes.sh \
t/t3308-notes-merge.sh t/t3423-rebase-reword.sh \
t/t3436-rebase-more-options.sh \
t/t4015-diff-whitespace.sh t/t4257-am-interactive.sh \
t/t5323-pack-redundant.sh t/t5401-update-hooks.sh \
t/t5511-refspec.sh t/t5526-fetch-submodules.sh \
t/t5529-push-errors.sh t/t5530-upload-pack-error.sh \
t/t5548-push-porcelain.sh \
t/t5552-skipping-fetch-negotiator.sh \
t/t5572-pull-submodule.sh t/t5608-clone-2gb.sh \
t/t5614-clone-submodules-shallow.sh \
t/t7508-status.sh t/t7606-merge-custom.sh \
t/t9302-fast-import-unpack-limit.sh
We excluded one set of test scripts in these commands, though: the range
of `git p4` tests. The reason? `git p4` stores the (foreign) remote
branch in the branch called `p4/master`, which is obviously not the
default branch. Manual analysis revealed that only five of these tests
actually require a specific default branch name to pass; They were
modified thusly:
$ sed -i '/^ *\. \.\/lib-git-p4\.sh$/i\
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=master\
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME\
' t/t980[0167]*.sh t/t9811*.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2020-11-18 23:44:19 +00:00
|
|
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
|
|
|
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
. ./test-lib.sh
|
|
|
|
. "$TEST_DIRECTORY"/lib-rebase.sh
|
2020-02-24 13:38:13 +00:00
|
|
|
. "$TEST_DIRECTORY"/lib-log-graph.sh
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
|
|
|
|
test_cmp_graph () {
|
|
|
|
cat >expect &&
|
2020-02-24 13:38:13 +00:00
|
|
|
lib_test_cmp_graph --boundary --format=%s "$@"
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
test_expect_success 'setup' '
|
|
|
|
write_script replace-editor.sh <<-\EOF &&
|
|
|
|
mv "$1" "$(git rev-parse --git-path ORIGINAL-TODO)"
|
|
|
|
cp script-from-scratch "$1"
|
|
|
|
EOF
|
|
|
|
|
|
|
|
test_commit A &&
|
|
|
|
git checkout -b first &&
|
|
|
|
test_commit B &&
|
2019-08-18 19:16:39 +00:00
|
|
|
b=$(git rev-parse --short HEAD) &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_commit C &&
|
2019-08-18 19:16:39 +00:00
|
|
|
c=$(git rev-parse --short HEAD) &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_commit D &&
|
2019-08-18 19:16:39 +00:00
|
|
|
d=$(git rev-parse --short HEAD) &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
git merge --no-commit B &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m E &&
|
|
|
|
git tag -m E E &&
|
2019-08-18 19:16:39 +00:00
|
|
|
e=$(git rev-parse --short HEAD) &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
git checkout -b second C &&
|
|
|
|
test_commit F &&
|
2019-08-18 19:16:39 +00:00
|
|
|
f=$(git rev-parse --short HEAD) &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_commit G &&
|
2019-08-18 19:16:39 +00:00
|
|
|
g=$(git rev-parse --short HEAD) &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout main &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
git merge --no-commit G &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m H &&
|
2019-08-18 19:16:39 +00:00
|
|
|
h=$(git rev-parse --short HEAD) &&
|
2018-08-15 09:39:34 +00:00
|
|
|
git tag -m H H &&
|
|
|
|
git checkout A &&
|
|
|
|
test_commit conflicting-G G.t
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'create completely different structure' '
|
|
|
|
cat >script-from-scratch <<-\EOF &&
|
|
|
|
label onto
|
|
|
|
|
|
|
|
# onebranch
|
|
|
|
pick G
|
|
|
|
pick D
|
|
|
|
label onebranch
|
|
|
|
|
|
|
|
# second
|
|
|
|
reset onto
|
|
|
|
pick B
|
|
|
|
label second
|
|
|
|
|
|
|
|
reset onto
|
|
|
|
merge -C H second
|
|
|
|
merge onebranch # Merge the topic branch '\''onebranch'\''
|
|
|
|
EOF
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git rebase -i -r A main &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_cmp_graph <<-\EOF
|
|
|
|
* Merge the topic branch '\''onebranch'\''
|
|
|
|
|\
|
|
|
|
| * D
|
|
|
|
| * G
|
|
|
|
* | H
|
|
|
|
|\ \
|
|
|
|
| |/
|
|
|
|
|/|
|
|
|
|
| * B
|
|
|
|
|/
|
|
|
|
* A
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success 'generate correct todo list' '
|
2019-08-18 19:16:39 +00:00
|
|
|
cat >expect <<-EOF &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
label onto
|
|
|
|
|
|
|
|
reset onto
|
2019-08-18 19:16:39 +00:00
|
|
|
pick $b B
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
label E
|
|
|
|
|
|
|
|
reset onto
|
2019-08-18 19:16:39 +00:00
|
|
|
pick $c C
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
label branch-point
|
2019-08-18 19:16:39 +00:00
|
|
|
pick $f F
|
|
|
|
pick $g G
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
label H
|
|
|
|
|
|
|
|
reset branch-point # C
|
2019-08-18 19:16:39 +00:00
|
|
|
pick $d D
|
|
|
|
merge -C $e E # E
|
|
|
|
merge -C $h H # H
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
|
|
|
|
EOF
|
|
|
|
|
|
|
|
grep -v "^#" <.git/ORIGINAL-TODO >output &&
|
|
|
|
test_cmp expect output
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '`reset` refuses to overwrite untracked files' '
|
|
|
|
git checkout -b refuse-to-reset &&
|
|
|
|
test_commit dont-overwrite-untracked &&
|
|
|
|
git checkout @{-1} &&
|
|
|
|
: >dont-overwrite-untracked.t &&
|
|
|
|
echo "reset refs/tags/dont-overwrite-untracked" >script-from-scratch &&
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
2019-01-28 10:27:56 +00:00
|
|
|
test_must_fail git rebase -ir HEAD &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
git rebase --abort
|
|
|
|
'
|
|
|
|
|
2022-11-10 16:43:40 +00:00
|
|
|
test_expect_success '`reset` rejects trees' '
|
|
|
|
test_when_finished "test_might_fail git rebase --abort" &&
|
|
|
|
test_must_fail env GIT_SEQUENCE_EDITOR="echo reset A^{tree} >" \
|
|
|
|
git rebase -i B C >out 2>err &&
|
|
|
|
grep "object .* is a tree" err &&
|
|
|
|
test_must_be_empty out
|
|
|
|
'
|
|
|
|
|
2022-11-10 16:43:41 +00:00
|
|
|
test_expect_success '`reset` only looks for labels under refs/rewritten/' '
|
|
|
|
test_when_finished "test_might_fail git rebase --abort" &&
|
|
|
|
git branch refs/rewritten/my-label A &&
|
|
|
|
test_must_fail env GIT_SEQUENCE_EDITOR="echo reset my-label >" \
|
|
|
|
git rebase -i B C >out 2>err &&
|
|
|
|
grep "could not resolve ${SQ}my-label${SQ}" err &&
|
|
|
|
test_must_be_empty out
|
|
|
|
'
|
|
|
|
|
2018-08-15 09:39:35 +00:00
|
|
|
test_expect_success 'failed `merge -C` writes patch (may be rescheduled, too)' '
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_when_finished "test_might_fail git rebase --abort" &&
|
|
|
|
git checkout -b conflicting-merge A &&
|
|
|
|
|
|
|
|
: fail because of conflicting untracked file &&
|
|
|
|
>G.t &&
|
|
|
|
echo "merge -C H G" >script-from-scratch &&
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
|
|
|
test_must_fail git rebase -ir HEAD &&
|
|
|
|
grep "^merge -C .* G$" .git/rebase-merge/done &&
|
|
|
|
grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo &&
|
|
|
|
test_path_is_file .git/rebase-merge/patch &&
|
|
|
|
|
|
|
|
: fail because of merge conflict &&
|
|
|
|
rm G.t .git/rebase-merge/patch &&
|
2018-08-15 09:39:34 +00:00
|
|
|
git reset --hard conflicting-G &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_must_fail git rebase --continue &&
|
|
|
|
! grep "^merge -C .* G$" .git/rebase-merge/git-rebase-todo &&
|
|
|
|
test_path_is_file .git/rebase-merge/patch
|
|
|
|
'
|
|
|
|
|
2018-08-15 09:39:35 +00:00
|
|
|
test_expect_success 'failed `merge <branch>` does not crash' '
|
|
|
|
test_when_finished "test_might_fail git rebase --abort" &&
|
|
|
|
git checkout conflicting-G &&
|
|
|
|
|
|
|
|
echo "merge G" >script-from-scratch &&
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
|
|
|
test_must_fail git rebase -ir HEAD &&
|
|
|
|
! grep "^merge G$" .git/rebase-merge/git-rebase-todo &&
|
|
|
|
grep "^Merge branch ${SQ}G${SQ}$" .git/rebase-merge/message
|
|
|
|
'
|
|
|
|
|
2021-08-20 15:40:35 +00:00
|
|
|
test_expect_success 'merge -c commits before rewording and reloads todo-list' '
|
|
|
|
cat >script-from-scratch <<-\EOF &&
|
|
|
|
merge -c E B
|
|
|
|
merge -c H G
|
|
|
|
EOF
|
|
|
|
|
|
|
|
git checkout -b merge-c H &&
|
2019-05-02 10:22:49 +00:00
|
|
|
(
|
2021-08-20 15:40:35 +00:00
|
|
|
set_reword_editor &&
|
|
|
|
GIT_SEQUENCE_EDITOR="\"$PWD/replace-editor.sh\"" \
|
|
|
|
git rebase -i -r D
|
2019-05-02 10:22:49 +00:00
|
|
|
) &&
|
2021-08-20 15:40:35 +00:00
|
|
|
check_reworded_commits E H
|
2019-05-02 10:22:49 +00:00
|
|
|
'
|
|
|
|
|
2021-08-20 15:40:38 +00:00
|
|
|
test_expect_success 'merge -c rewords when a strategy is given' '
|
|
|
|
git checkout -b merge-c-with-strategy H &&
|
|
|
|
write_script git-merge-override <<-\EOF &&
|
|
|
|
echo overridden$1 >G.t
|
|
|
|
git add G.t
|
|
|
|
EOF
|
|
|
|
|
|
|
|
PATH="$PWD:$PATH" \
|
|
|
|
GIT_SEQUENCE_EDITOR="echo merge -c H G >" \
|
|
|
|
GIT_EDITOR="echo edited >>" \
|
|
|
|
git rebase --no-ff -ir -s override -Xxopt E &&
|
|
|
|
test_write_lines overridden--xopt >expect &&
|
|
|
|
test_cmp expect G.t &&
|
|
|
|
test_write_lines H "" edited "" >expect &&
|
|
|
|
git log --format=%B -1 >actual &&
|
|
|
|
test_cmp expect actual
|
|
|
|
|
|
|
|
'
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_expect_success 'with a branch tip that was cherry-picked already' '
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout -b already-upstream main &&
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
base="$(git rev-parse --verify HEAD)" &&
|
|
|
|
|
|
|
|
test_commit A1 &&
|
|
|
|
test_commit A2 &&
|
|
|
|
git reset --hard $base &&
|
|
|
|
test_commit B1 &&
|
|
|
|
test_tick &&
|
|
|
|
git merge -m "Merge branch A" A2 &&
|
|
|
|
|
|
|
|
git checkout -b upstream-with-a2 $base &&
|
|
|
|
test_tick &&
|
|
|
|
git cherry-pick A2 &&
|
|
|
|
|
|
|
|
git checkout already-upstream &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i -r upstream-with-a2 &&
|
|
|
|
test_cmp_graph upstream-with-a2.. <<-\EOF
|
|
|
|
* Merge branch A
|
|
|
|
|\
|
|
|
|
| * A1
|
|
|
|
* | B1
|
|
|
|
|/
|
|
|
|
o A2
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2023-03-26 03:06:34 +00:00
|
|
|
test_expect_success '--no-rebase-merges countermands --rebase-merges' '
|
|
|
|
git checkout -b no-rebase-merges E &&
|
|
|
|
git rebase --rebase-merges --no-rebase-merges C &&
|
|
|
|
test_cmp_graph C.. <<-\EOF
|
|
|
|
* B
|
|
|
|
* D
|
|
|
|
o C
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
rebase -i: introduce --rebase-merges=[no-]rebase-cousins
When running `git rebase --rebase-merges` non-interactively with an
ancestor of HEAD as <upstream> (or leaving the todo list unmodified),
we would ideally recreate the exact same commits as before the rebase.
However, if there are commits in the commit range <upstream>.. that do not
have <upstream> as direct ancestor (i.e. if `git log <upstream>..` would
show commits that are omitted by `git log --ancestry-path <upstream>..`),
this is currently not the case: we would turn them into commits that have
<upstream> as direct ancestor.
Let's illustrate that with a diagram:
C
/ \
A - B - E - F
\ /
D
Currently, after running `git rebase -i --rebase-merges B`, the new branch
structure would be (pay particular attention to the commit `D`):
--- C' --
/ \
A - B ------ E' - F'
\ /
D'
This is not really preserving the branch topology from before! The
reason is that the commit `D` does not have `B` as ancestor, and
therefore it gets rebased onto `B`.
This is unintuitive behavior. Even worse, when recreating branch
structure, most use cases would appear to want cousins *not* to be
rebased onto the new base commit. For example, Git for Windows (the
heaviest user of the Git garden shears, which served as the blueprint
for --rebase-merges) frequently merges branches from `next` early, and
these branches certainly do *not* want to be rebased. In the example
above, the desired outcome would look like this:
--- C' --
/ \
A - B ------ E' - F'
\ /
-- D' --
Let's introduce the term "cousins" for such commits ("D" in the
example), and let's not rebase them by default. For hypothetical
use cases where cousins *do* need to be rebased, `git rebase
--rebase=merges=rebase-cousins` needs to be used.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:40 +00:00
|
|
|
test_expect_success 'do not rebase cousins unless asked for' '
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout -b cousins main &&
|
rebase -i: introduce --rebase-merges=[no-]rebase-cousins
When running `git rebase --rebase-merges` non-interactively with an
ancestor of HEAD as <upstream> (or leaving the todo list unmodified),
we would ideally recreate the exact same commits as before the rebase.
However, if there are commits in the commit range <upstream>.. that do not
have <upstream> as direct ancestor (i.e. if `git log <upstream>..` would
show commits that are omitted by `git log --ancestry-path <upstream>..`),
this is currently not the case: we would turn them into commits that have
<upstream> as direct ancestor.
Let's illustrate that with a diagram:
C
/ \
A - B - E - F
\ /
D
Currently, after running `git rebase -i --rebase-merges B`, the new branch
structure would be (pay particular attention to the commit `D`):
--- C' --
/ \
A - B ------ E' - F'
\ /
D'
This is not really preserving the branch topology from before! The
reason is that the commit `D` does not have `B` as ancestor, and
therefore it gets rebased onto `B`.
This is unintuitive behavior. Even worse, when recreating branch
structure, most use cases would appear to want cousins *not* to be
rebased onto the new base commit. For example, Git for Windows (the
heaviest user of the Git garden shears, which served as the blueprint
for --rebase-merges) frequently merges branches from `next` early, and
these branches certainly do *not* want to be rebased. In the example
above, the desired outcome would look like this:
--- C' --
/ \
A - B ------ E' - F'
\ /
-- D' --
Let's introduce the term "cousins" for such commits ("D" in the
example), and let's not rebase them by default. For hypothetical
use cases where cousins *do* need to be rebased, `git rebase
--rebase=merges=rebase-cousins` needs to be used.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:40 +00:00
|
|
|
before="$(git rev-parse --verify HEAD)" &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -r HEAD^ &&
|
|
|
|
test_cmp_rev HEAD $before &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase --rebase-merges=rebase-cousins HEAD^ &&
|
|
|
|
test_cmp_graph HEAD^.. <<-\EOF
|
|
|
|
* Merge the topic branch '\''onebranch'\''
|
|
|
|
|\
|
|
|
|
| * D
|
|
|
|
| * G
|
|
|
|
|/
|
|
|
|
o H
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
2023-03-26 03:06:36 +00:00
|
|
|
test_expect_success 'rebase.rebaseMerges=rebase-cousins is equivalent to --rebase-merges=rebase-cousins' '
|
|
|
|
test_config rebase.rebaseMerges rebase-cousins &&
|
|
|
|
git checkout -b config-rebase-cousins main &&
|
|
|
|
git rebase HEAD^ &&
|
|
|
|
test_cmp_graph HEAD^.. <<-\EOF
|
|
|
|
* Merge the topic branch '\''onebranch'\''
|
|
|
|
|\
|
|
|
|
| * D
|
|
|
|
| * G
|
|
|
|
|/
|
|
|
|
o H
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--no-rebase-merges overrides rebase.rebaseMerges=no-rebase-cousins' '
|
|
|
|
test_config rebase.rebaseMerges no-rebase-cousins &&
|
|
|
|
git checkout -b override-config-no-rebase-cousins E &&
|
|
|
|
git rebase --no-rebase-merges C &&
|
|
|
|
test_cmp_graph C.. <<-\EOF
|
|
|
|
* B
|
|
|
|
* D
|
|
|
|
o C
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--rebase-merges overrides rebase.rebaseMerges=rebase-cousins' '
|
|
|
|
test_config rebase.rebaseMerges rebase-cousins &&
|
|
|
|
git checkout -b override-config-rebase-cousins E &&
|
|
|
|
before="$(git rev-parse --verify HEAD)" &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase --rebase-merges C &&
|
|
|
|
test_cmp_rev HEAD $before
|
|
|
|
'
|
|
|
|
|
2018-04-25 12:29:16 +00:00
|
|
|
test_expect_success 'refs/rewritten/* is worktree-local' '
|
|
|
|
git worktree add wt &&
|
|
|
|
cat >wt/script-from-scratch <<-\EOF &&
|
|
|
|
label xyz
|
|
|
|
exec GIT_DIR=../.git git rev-parse --verify refs/rewritten/xyz >a || :
|
|
|
|
exec git rev-parse --verify refs/rewritten/xyz >b
|
|
|
|
EOF
|
|
|
|
|
|
|
|
test_config -C wt sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
git -C wt rebase -i HEAD &&
|
|
|
|
test_must_be_empty wt/a &&
|
|
|
|
test_cmp_rev HEAD "$(cat wt/b)"
|
|
|
|
'
|
|
|
|
|
2019-05-14 18:03:49 +00:00
|
|
|
test_expect_success '--abort cleans up refs/rewritten' '
|
|
|
|
git checkout -b abort-cleans-refs-rewritten H &&
|
|
|
|
GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
|
|
|
|
git rev-parse --verify refs/rewritten/onto &&
|
|
|
|
git rebase --abort &&
|
|
|
|
test_must_fail git rev-parse --verify refs/rewritten/onto
|
|
|
|
'
|
|
|
|
|
|
|
|
test_expect_success '--quit cleans up refs/rewritten' '
|
|
|
|
git checkout -b quit-cleans-refs-rewritten H &&
|
|
|
|
GIT_SEQUENCE_EDITOR="echo break >>" git rebase -ir @^ &&
|
|
|
|
git rev-parse --verify refs/rewritten/onto &&
|
|
|
|
git rebase --quit &&
|
|
|
|
test_must_fail git rev-parse --verify refs/rewritten/onto
|
|
|
|
'
|
|
|
|
|
2018-04-25 12:29:29 +00:00
|
|
|
test_expect_success 'post-rewrite hook and fixups work for merges' '
|
2019-05-14 18:03:49 +00:00
|
|
|
git checkout -b post-rewrite H &&
|
2018-04-25 12:29:29 +00:00
|
|
|
test_commit same1 &&
|
|
|
|
git reset --hard HEAD^ &&
|
|
|
|
test_commit same2 &&
|
|
|
|
git merge -m "to fix up" same1 &&
|
|
|
|
echo same old same old >same2.t &&
|
|
|
|
test_tick &&
|
|
|
|
git commit --fixup HEAD same2.t &&
|
|
|
|
fixup="$(git rev-parse HEAD)" &&
|
|
|
|
|
2022-03-17 10:13:14 +00:00
|
|
|
test_hook post-rewrite <<-\EOF &&
|
|
|
|
cat >actual
|
|
|
|
EOF
|
2018-04-25 12:29:29 +00:00
|
|
|
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i --autosquash -r HEAD^^^ &&
|
|
|
|
printf "%s %s\n%s %s\n%s %s\n%s %s\n" >expect $(git rev-parse \
|
|
|
|
$fixup^^2 HEAD^2 \
|
|
|
|
$fixup^^ HEAD^ \
|
|
|
|
$fixup^ HEAD \
|
|
|
|
$fixup HEAD) &&
|
|
|
|
test_cmp expect actual
|
|
|
|
'
|
|
|
|
|
2018-04-25 12:29:31 +00:00
|
|
|
test_expect_success 'refuse to merge ancestors of HEAD' '
|
|
|
|
echo "merge HEAD^" >script-from-scratch &&
|
|
|
|
test_config -C wt sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
before="$(git rev-parse HEAD)" &&
|
|
|
|
git rebase -i HEAD &&
|
|
|
|
test_cmp_rev HEAD $before
|
|
|
|
'
|
|
|
|
|
2018-05-03 23:01:23 +00:00
|
|
|
test_expect_success 'root commits' '
|
|
|
|
git checkout --orphan unrelated &&
|
|
|
|
(GIT_AUTHOR_NAME="Parsnip" GIT_AUTHOR_EMAIL="root@example.com" \
|
|
|
|
test_commit second-root) &&
|
|
|
|
test_commit third-root &&
|
|
|
|
cat >script-from-scratch <<-\EOF &&
|
|
|
|
pick third-root
|
|
|
|
label first-branch
|
|
|
|
reset [new root]
|
|
|
|
pick second-root
|
|
|
|
merge first-branch # Merge the 3rd root
|
|
|
|
EOF
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
2019-03-25 18:14:19 +00:00
|
|
|
git rebase -i --force-rebase --root -r &&
|
2018-05-03 23:01:23 +00:00
|
|
|
test "Parsnip" = "$(git show -s --format=%an HEAD^)" &&
|
|
|
|
test $(git rev-parse second-root^0) != $(git rev-parse HEAD^) &&
|
|
|
|
test $(git rev-parse second-root:second-root.t) = \
|
|
|
|
$(git rev-parse HEAD^:second-root.t) &&
|
|
|
|
test_cmp_graph HEAD <<-\EOF &&
|
|
|
|
* Merge the 3rd root
|
|
|
|
|\
|
|
|
|
| * third-root
|
|
|
|
* second-root
|
|
|
|
EOF
|
|
|
|
|
|
|
|
: fast forward if possible &&
|
|
|
|
before="$(git rev-parse --verify HEAD)" &&
|
|
|
|
test_might_fail git config --unset sequence.editor &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i --root -r &&
|
|
|
|
test_cmp_rev HEAD $before
|
|
|
|
'
|
|
|
|
|
2018-05-03 23:01:28 +00:00
|
|
|
test_expect_success 'a "merge" into a root commit is a fast-forward' '
|
|
|
|
head=$(git rev-parse HEAD) &&
|
|
|
|
cat >script-from-scratch <<-EOF &&
|
|
|
|
reset [new root]
|
|
|
|
merge $head
|
|
|
|
EOF
|
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i -r HEAD^ &&
|
|
|
|
test_cmp_rev HEAD $head
|
|
|
|
'
|
|
|
|
|
2018-05-03 23:01:29 +00:00
|
|
|
test_expect_success 'A root commit can be a cousin, treat it that way' '
|
|
|
|
git checkout --orphan khnum &&
|
|
|
|
test_commit yama &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout -b asherah main &&
|
2018-05-03 23:01:29 +00:00
|
|
|
test_commit shamkat &&
|
|
|
|
git merge --allow-unrelated-histories khnum &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -f -r HEAD^ &&
|
2019-11-12 23:07:45 +00:00
|
|
|
test_cmp_rev ! HEAD^2 khnum &&
|
2018-05-03 23:01:29 +00:00
|
|
|
test_cmp_graph HEAD^.. <<-\EOF &&
|
|
|
|
* Merge branch '\''khnum'\'' into asherah
|
|
|
|
|\
|
|
|
|
| * yama
|
|
|
|
o shamkat
|
|
|
|
EOF
|
|
|
|
test_tick &&
|
|
|
|
git rebase --rebase-merges=rebase-cousins HEAD^ &&
|
|
|
|
test_cmp_graph HEAD^.. <<-\EOF
|
|
|
|
* Merge branch '\''khnum'\'' into asherah
|
|
|
|
|\
|
|
|
|
| * yama
|
|
|
|
|/
|
|
|
|
o shamkat
|
|
|
|
EOF
|
|
|
|
'
|
2018-05-03 23:01:28 +00:00
|
|
|
|
2018-05-29 16:32:36 +00:00
|
|
|
test_expect_success 'labels that are object IDs are rewritten' '
|
|
|
|
git checkout -b third B &&
|
|
|
|
test_commit I &&
|
|
|
|
third=$(git rev-parse HEAD) &&
|
2020-11-18 23:44:25 +00:00
|
|
|
git checkout -b labels main &&
|
2018-05-29 16:32:36 +00:00
|
|
|
git merge --no-commit third &&
|
|
|
|
test_tick &&
|
|
|
|
git commit -m "Merge commit '\''$third'\'' into labels" &&
|
2018-06-01 17:46:39 +00:00
|
|
|
echo noop >script-from-scratch &&
|
2018-05-29 16:32:36 +00:00
|
|
|
test_config sequence.editor \""$PWD"/replace-editor.sh\" &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i -r A &&
|
2018-06-01 17:46:39 +00:00
|
|
|
grep "^label $third-" .git/ORIGINAL-TODO &&
|
2018-05-29 16:32:36 +00:00
|
|
|
! grep "^label $third$" .git/ORIGINAL-TODO
|
|
|
|
'
|
|
|
|
|
2017-12-21 14:52:45 +00:00
|
|
|
test_expect_success 'octopus merges' '
|
|
|
|
git checkout -b three &&
|
|
|
|
test_commit before-octopus &&
|
|
|
|
test_commit three &&
|
|
|
|
git checkout -b two HEAD^ &&
|
|
|
|
test_commit two &&
|
|
|
|
git checkout -b one HEAD^ &&
|
|
|
|
test_commit one &&
|
|
|
|
test_tick &&
|
|
|
|
(GIT_AUTHOR_NAME="Hank" GIT_AUTHOR_EMAIL="hank@sea.world" \
|
|
|
|
git merge -m "Tüntenfüsch" two three) &&
|
|
|
|
|
|
|
|
: fast forward if possible &&
|
|
|
|
before="$(git rev-parse --verify HEAD)" &&
|
|
|
|
test_tick &&
|
|
|
|
git rebase -i -r HEAD^^ &&
|
|
|
|
test_cmp_rev HEAD $before &&
|
|
|
|
|
|
|
|
test_tick &&
|
2019-03-25 18:14:19 +00:00
|
|
|
git rebase -i --force-rebase -r HEAD^^ &&
|
2017-12-21 14:52:45 +00:00
|
|
|
test "Hank" = "$(git show -s --format=%an HEAD)" &&
|
|
|
|
test "$before" != $(git rev-parse HEAD) &&
|
|
|
|
test_cmp_graph HEAD^^.. <<-\EOF
|
|
|
|
*-. Tüntenfüsch
|
|
|
|
|\ \
|
|
|
|
| | * three
|
|
|
|
| * | two
|
|
|
|
| |/
|
2019-10-15 23:47:57 +00:00
|
|
|
* / one
|
2017-12-21 14:52:45 +00:00
|
|
|
|/
|
|
|
|
o before-octopus
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
rebase --exec: make it work with --rebase-merges
The idea of `--exec` is to append an `exec` call after each `pick`.
Since the introduction of fixup!/squash! commits, this idea was extended
to apply to "pick, possibly followed by a fixup/squash chain", i.e. an
exec would not be inserted between a `pick` and any of its corresponding
`fixup` or `squash` lines.
The current implementation uses a dirty trick to achieve that: it
assumes that there are only pick/fixup/squash commands, and then
*inserts* the `exec` lines before any `pick` but the first, and appends
a final one.
With the todo lists generated by `git rebase --rebase-merges`, this
simple implementation shows its problems: it produces the exact wrong
thing when there are `label`, `reset` and `merge` commands.
Let's change the implementation to do exactly what we want: look for
`pick` lines, skip any fixup/squash chains, and then insert the `exec`
line. Lather, rinse, repeat.
Note: we take pains to insert *before* comment lines whenever possible,
as empty commits are represented by commented-out pick lines (and we
want to insert a preceding pick's exec line *before* such a line, not
afterward).
While at it, also add `exec` lines after `merge` commands, because they
are similar in spirit to `pick` commands: they add new commits.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-08-09 09:41:11 +00:00
|
|
|
test_expect_success 'with --autosquash and --exec' '
|
2018-08-06 09:52:52 +00:00
|
|
|
git checkout -b with-exec H &&
|
|
|
|
echo Booh >B.t &&
|
|
|
|
test_tick &&
|
|
|
|
git commit --fixup B B.t &&
|
|
|
|
write_script show.sh <<-\EOF &&
|
|
|
|
subject="$(git show -s --format=%s HEAD)"
|
2020-06-09 19:00:21 +00:00
|
|
|
content="$(git diff HEAD^ HEAD | tail -n 1)"
|
2018-08-06 09:52:52 +00:00
|
|
|
echo "$subject: $content"
|
|
|
|
EOF
|
|
|
|
test_tick &&
|
|
|
|
git rebase -ir --autosquash --exec ./show.sh A >actual &&
|
|
|
|
grep "B: +Booh" actual &&
|
|
|
|
grep "E: +Booh" actual &&
|
|
|
|
grep "G: +G" actual
|
|
|
|
'
|
|
|
|
|
2018-11-12 23:25:58 +00:00
|
|
|
test_expect_success '--continue after resolving conflicts after a merge' '
|
2018-11-12 23:25:57 +00:00
|
|
|
git checkout -b already-has-g E &&
|
|
|
|
git cherry-pick E..G &&
|
|
|
|
test_commit H2 &&
|
|
|
|
|
|
|
|
git checkout -b conflicts-in-merge H &&
|
|
|
|
test_commit H2 H2.t conflicts H2-conflict &&
|
|
|
|
test_must_fail git rebase -r already-has-g &&
|
|
|
|
grep conflicts H2.t &&
|
|
|
|
echo resolved >H2.t &&
|
|
|
|
git add -u &&
|
|
|
|
git rebase --continue &&
|
|
|
|
test_must_fail git rev-parse --verify HEAD^2 &&
|
|
|
|
test_path_is_missing .git/MERGE_HEAD
|
|
|
|
'
|
|
|
|
|
2019-07-31 15:18:47 +00:00
|
|
|
test_expect_success '--rebase-merges with strategies' '
|
|
|
|
git checkout -b with-a-strategy F &&
|
|
|
|
test_tick &&
|
|
|
|
git merge -m "Merge conflicting-G" conflicting-G &&
|
|
|
|
|
|
|
|
: first, test with a merge strategy option &&
|
|
|
|
git rebase -ir -Xtheirs G &&
|
|
|
|
echo conflicting-G >expect &&
|
|
|
|
test_cmp expect G.t &&
|
|
|
|
|
|
|
|
: now, try with a merge strategy other than recursive &&
|
|
|
|
git reset --hard @{1} &&
|
|
|
|
write_script git-merge-override <<-\EOF &&
|
|
|
|
echo overridden$1 >>G.t
|
|
|
|
git add G.t
|
|
|
|
EOF
|
|
|
|
PATH="$PWD:$PATH" git rebase -ir -s override -Xxopt G &&
|
|
|
|
test_write_lines G overridden--xopt >expect &&
|
|
|
|
test_cmp expect G.t
|
|
|
|
'
|
|
|
|
|
2019-11-17 23:16:10 +00:00
|
|
|
test_expect_success '--rebase-merges with commit that can generate bad characters for filename' '
|
|
|
|
git checkout -b colon-in-label E &&
|
|
|
|
git merge -m "colon: this should work" G &&
|
|
|
|
git rebase --rebase-merges --force-rebase E
|
|
|
|
'
|
|
|
|
|
2019-11-18 11:57:47 +00:00
|
|
|
test_expect_success '--rebase-merges with message matched with onto label' '
|
|
|
|
git checkout -b onto-label E &&
|
|
|
|
git merge -m onto G &&
|
|
|
|
git rebase --rebase-merges --force-rebase E &&
|
|
|
|
test_cmp_graph <<-\EOF
|
|
|
|
* onto
|
|
|
|
|\
|
|
|
|
| * G
|
|
|
|
| * F
|
|
|
|
* | E
|
|
|
|
|\ \
|
|
|
|
| * | B
|
|
|
|
* | | D
|
|
|
|
| |/
|
|
|
|
|/|
|
|
|
|
* | C
|
|
|
|
|/
|
|
|
|
* A
|
|
|
|
EOF
|
|
|
|
'
|
|
|
|
|
rebase: introduce the --rebase-merges option
Once upon a time, this here developer thought: wouldn't it be nice if,
say, Git for Windows' patches on top of core Git could be represented as
a thicket of branches, and be rebased on top of core Git in order to
maintain a cherry-pick'able set of patch series?
The original attempt to answer this was: git rebase --preserve-merges.
However, that experiment was never intended as an interactive option,
and it only piggy-backed on git rebase --interactive because that
command's implementation looked already very, very familiar: it was
designed by the same person who designed --preserve-merges: yours truly.
Some time later, some other developer (I am looking at you, Andreas!
;-)) decided that it would be a good idea to allow --preserve-merges to
be combined with --interactive (with caveats!) and the Git maintainer
(well, the interim Git maintainer during Junio's absence, that is)
agreed, and that is when the glamor of the --preserve-merges design
started to fall apart rather quickly and unglamorously.
The reason? In --preserve-merges mode, the parents of a merge commit (or
for that matter, of *any* commit) were not stated explicitly, but were
*implied* by the commit name passed to the `pick` command.
This made it impossible, for example, to reorder commits. Not to mention
to move commits between branches or, deity forbid, to split topic branches
into two.
Alas, these shortcomings also prevented that mode (whose original
purpose was to serve Git for Windows' needs, with the additional hope
that it may be useful to others, too) from serving Git for Windows'
needs.
Five years later, when it became really untenable to have one unwieldy,
big hodge-podge patch series of partly related, partly unrelated patches
in Git for Windows that was rebased onto core Git's tags from time to
time (earning the undeserved wrath of the developer of the ill-fated
git-remote-hg series that first obsoleted Git for Windows' competing
approach, only to be abandoned without maintainer later) was really
untenable, the "Git garden shears" were born [*1*/*2*]: a script,
piggy-backing on top of the interactive rebase, that would first
determine the branch topology of the patches to be rebased, create a
pseudo todo list for further editing, transform the result into a real
todo list (making heavy use of the `exec` command to "implement" the
missing todo list commands) and finally recreate the patch series on
top of the new base commit.
That was in 2013. And it took about three weeks to come up with the
design and implement it as an out-of-tree script. Needless to say, the
implementation needed quite a few years to stabilize, all the while the
design itself proved itself sound.
With this patch, the goodness of the Git garden shears comes to `git
rebase -i` itself. Passing the `--rebase-merges` option will generate
a todo list that can be understood readily, and where it is obvious
how to reorder commits. New branches can be introduced by inserting
`label` commands and calling `merge <label>`. And once this mode will
have become stable and universally accepted, we can deprecate the design
mistake that was `--preserve-merges`.
Link *1*:
https://github.com/msysgit/msysgit/blob/master/share/msysGit/shears.sh
Link *2*:
https://github.com/git-for-windows/build-extra/blob/master/shears.sh
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2018-04-25 12:29:04 +00:00
|
|
|
test_done
|