git rebase and merge commits
- From
Dominique Quatravaux <domq@google.com>
- Date
- Oct 20, 2010, 16:45 UTC
- Message-ID
- <AANLkTikroNPehcyBsueCnJ5hR0idd3cBP4m1KNccdRqL@mail.gmail.com>
Hi all, I'm trying to write "git shove", a wrapper around git rebase --interactive that would turn this
# A---B---C---K targetbranch # / \ # D---E---F---G---H---I--J srcbranch
into this:
# A---B---C---I'---K' targetbranch # / \ # D---E---F---G---H'---J' srcbranch #
(ie I has been shoved into targetbranch).
It seemed to me that the first step should be to simply rebase I, H, and J (in this order) onto C. Unfortunately git rebase --interactive -p C proposes a git-rebase-todo that contains only "noop"; if I forcefully put this instead,
edit iiii I edit hhhh H edit jjjj J
it seems to me that the HEAD jumps backward to the original H on the second rebase step, instead of daisy-chaining H behind I. This is with git 1.7.3.1.
Here are the outputs of git log --graph --pretty=oneline --abbrev-commit at each rebase step:
1/3
* a810395 I * 1cfccc7 H |\ | * c477d4e C | * 7002290 B | * aa9f1d0 A * | b614d31 G * | 2ad4496 F |/ * 0d512e9 E * b6cbc2b D
2/3
* 1cfccc7 H |\ | * c477d4e C | * 7002290 B | * aa9f1d0 A * | b614d31 G * | 2ad4496 F |/ * 0d512e9 E * b6cbc2b D
3/3
* 3a41a45 J * a810395 I * 1cfccc7 H |\ | * c477d4e C | * 7002290 B | * aa9f1d0 A * | b614d31 G * | 2ad4496 F |/ * 0d512e9 E * b6cbc2b D
Is there a way to do a real rebase of a merge commit?
FWIW, here is the script I use to create my toy environment in the current directory:
function _make_commit() {
echo "$1" > "$1"
git add "$1"
git commit -a -m "$1"
git tag "$1" HEAD
}function _prepare_merged_history() {
git init
_make_commit "D"
git checkout -b targetbranch
_make_commit "E"
_make_commit "A"
_make_commit "B"
_make_commit "C"
_make_commit "K"
git checkout E
git checkout -b srcbranch
_make_commit "F"
_make_commit "G"
git merge -m "H" C
git tag H HEAD
_make_commit "I"
_make_commit "J"
}function _git_rebase_todo_line() {
echo -n "pick "
git rev-list -n 1 --pretty=oneline --abbrev-commit --abbrev=7 "$1"
}function _make_git_rebase_todo() {
{
_git_rebase_todo_line refs/tags/I
_git_rebase_todo_line refs/tags/H
_git_rebase_todo_line refs/tags/J
} > git-rebase-todo
}[ -d ".git" ] && exit _prepare_merged_history _make_git_rebase_todo
Thanks in advance,
-- Dominique Quatravaux +41 79 609 40 72