Merge branch 'cw/rebase-i-root'
"git rebase [-i] --root $tip" can now be used to rewrite all the history down to the root. * cw/rebase-i-root: t3404: make test 57 work with dash and others Add tests for rebase -i --root without --onto rebase -i: support --root without --onto
This commit is contained in:
commit
0cd993a778
@ -10,7 +10,7 @@ SYNOPSIS
|
||||
[verse]
|
||||
'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
|
||||
[<upstream>] [<branch>]
|
||||
'git rebase' [-i | --interactive] [options] [--exec <cmd>] --onto <newbase>
|
||||
'git rebase' [-i | --interactive] [options] [--exec <cmd>] [--onto <newbase>]
|
||||
--root [<branch>]
|
||||
'git rebase' --continue | --skip | --abort
|
||||
|
||||
@ -369,10 +369,11 @@ squash/fixup series.
|
||||
--root::
|
||||
Rebase all commits reachable from <branch>, instead of
|
||||
limiting them with an <upstream>. This allows you to rebase
|
||||
the root commit(s) on a branch. Must be used with --onto, and
|
||||
the root commit(s) on a branch. When used with --onto, it
|
||||
will skip changes already contained in <newbase> (instead of
|
||||
<upstream>). When used together with --preserve-merges, 'all'
|
||||
root commits will be rewritten to have <newbase> as parent
|
||||
<upstream>) whereas without --onto it will operate on every change.
|
||||
When used together with both --onto and --preserve-merges,
|
||||
'all' root commits will be rewritten to have <newbase> as parent
|
||||
instead.
|
||||
|
||||
--autosquash::
|
||||
|
@ -415,6 +415,29 @@ record_in_rewritten() {
|
||||
esac
|
||||
}
|
||||
|
||||
do_pick () {
|
||||
if test "$(git rev-parse HEAD)" = "$squash_onto"
|
||||
then
|
||||
# Set the correct commit message and author info on the
|
||||
# sentinel root before cherry-picking the original changes
|
||||
# without committing (-n). Finally, update the sentinel again
|
||||
# to include these changes. If the cherry-pick results in a
|
||||
# conflict, this means our behaviour is similar to a standard
|
||||
# failed cherry-pick during rebase, with a dirty index to
|
||||
# resolve before manually running git commit --amend then git
|
||||
# rebase --continue.
|
||||
git commit --allow-empty --allow-empty-message --amend \
|
||||
--no-post-rewrite -n -q -C $1 &&
|
||||
pick_one -n $1 &&
|
||||
git commit --allow-empty --allow-empty-message \
|
||||
--amend --no-post-rewrite -n -q -C $1 ||
|
||||
die_with_patch $1 "Could not apply $1... $2"
|
||||
else
|
||||
pick_one $1 ||
|
||||
die_with_patch $1 "Could not apply $1... $2"
|
||||
fi
|
||||
}
|
||||
|
||||
do_next () {
|
||||
rm -f "$msg" "$author_script" "$amend" || exit
|
||||
read -r command sha1 rest < "$todo"
|
||||
@ -426,16 +449,14 @@ do_next () {
|
||||
comment_for_reflog pick
|
||||
|
||||
mark_action_done
|
||||
pick_one $sha1 ||
|
||||
die_with_patch $sha1 "Could not apply $sha1... $rest"
|
||||
do_pick $sha1 "$rest"
|
||||
record_in_rewritten $sha1
|
||||
;;
|
||||
reword|r)
|
||||
comment_for_reflog reword
|
||||
|
||||
mark_action_done
|
||||
pick_one $sha1 ||
|
||||
die_with_patch $sha1 "Could not apply $sha1... $rest"
|
||||
do_pick $sha1 "$rest"
|
||||
git commit --amend --no-post-rewrite || {
|
||||
warn "Could not amend commit after successfully picking $sha1... $rest"
|
||||
warn "This is most likely due to an empty commit message, or the pre-commit hook"
|
||||
@ -449,8 +470,7 @@ do_next () {
|
||||
comment_for_reflog edit
|
||||
|
||||
mark_action_done
|
||||
pick_one $sha1 ||
|
||||
die_with_patch $sha1 "Could not apply $sha1... $rest"
|
||||
do_pick $sha1 "$rest"
|
||||
warn "Stopped at $sha1... $rest"
|
||||
exit_with_patch $sha1 0
|
||||
;;
|
||||
|
@ -32,7 +32,7 @@ SUBDIRECTORY_OK=Yes
|
||||
OPTIONS_KEEPDASHDASH=
|
||||
OPTIONS_SPEC="\
|
||||
git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] [<branch>]
|
||||
git rebase [-i] [options] [--exec <cmd>] --onto <newbase> --root [<branch>]
|
||||
git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]
|
||||
git-rebase [-i] --continue | --abort | --skip
|
||||
--
|
||||
Available options are
|
||||
@ -378,6 +378,11 @@ and run me again. I am stopping in case you still have something
|
||||
valuable there.'
|
||||
fi
|
||||
|
||||
if test -n "$rebase_root" && test -z "$onto"
|
||||
then
|
||||
test -z "$interactive_rebase" && interactive_rebase=implied
|
||||
fi
|
||||
|
||||
if test -n "$interactive_rebase"
|
||||
then
|
||||
type=interactive
|
||||
@ -411,7 +416,12 @@ then
|
||||
die "invalid upstream $upstream_name"
|
||||
upstream_arg="$upstream_name"
|
||||
else
|
||||
test -z "$onto" && die "You must specify --onto when using --root"
|
||||
if test -z "$onto"
|
||||
then
|
||||
empty_tree=`git hash-object -t tree /dev/null`
|
||||
onto=`git commit-tree $empty_tree </dev/null`
|
||||
squash_onto="$onto"
|
||||
fi
|
||||
unset upstream_name
|
||||
unset upstream
|
||||
test $# -gt 1 && usage
|
||||
|
@ -872,4 +872,35 @@ test_expect_success 'rebase -i --exec without <CMD>' '
|
||||
git checkout master
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -i --root re-order and drop commits' '
|
||||
git checkout E &&
|
||||
FAKE_LINES="3 1 2 5" git rebase -i --root &&
|
||||
test E = $(git cat-file commit HEAD | sed -ne \$p) &&
|
||||
test B = $(git cat-file commit HEAD^ | sed -ne \$p) &&
|
||||
test A = $(git cat-file commit HEAD^^ | sed -ne \$p) &&
|
||||
test C = $(git cat-file commit HEAD^^^ | sed -ne \$p) &&
|
||||
test 0 = $(git cat-file commit HEAD^^^ | grep -c ^parent\ )
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -i --root retain root commit author and message' '
|
||||
git checkout A &&
|
||||
echo B >file7 &&
|
||||
git add file7 &&
|
||||
GIT_AUTHOR_NAME="Twerp Snog" git commit -m "different author" &&
|
||||
FAKE_LINES="2" git rebase -i --root &&
|
||||
git cat-file commit HEAD | grep -q "^author Twerp Snog" &&
|
||||
git cat-file commit HEAD | grep -q "^different author$"
|
||||
'
|
||||
|
||||
test_expect_success 'rebase -i --root temporary sentinel commit' '
|
||||
git checkout B &&
|
||||
(
|
||||
FAKE_LINES="2" &&
|
||||
export FAKE_LINES &&
|
||||
test_must_fail git rebase -i --root
|
||||
) &&
|
||||
git cat-file commit HEAD | grep "^tree 4b825dc642cb" &&
|
||||
git rebase --abort
|
||||
'
|
||||
|
||||
test_done
|
||||
|
@ -22,11 +22,6 @@ test_expect_success 'prepare repository' '
|
||||
test_commit 4 B
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --root expects --onto' '
|
||||
git checkout -B fail other &&
|
||||
test_must_fail git rebase --root
|
||||
'
|
||||
|
||||
test_expect_success 'rebase --root fails with too many args' '
|
||||
git checkout -B fail other &&
|
||||
test_must_fail git rebase --onto master --root fail fail
|
||||
|
Loading…
Reference in New Issue
Block a user