Using git v1.7.1 I'm trying to do a rebase with both the --preserve-merges
and --onto
features at the same time. The end results seems to be without the merge commits, and so appears linear. I'd rather preserve the merge commits, for the same reason that people would often use --preserve-merges
(easier to see the group of commits that was logically a separate feature and developed in its own branch).
My master branch (the destination for the rebase) is boring:
A-B-C
The feature branch I want to take from has a sub-feature branch that has been merged into it. Like:
X - Y
/ \
V-W ------ Z
Where Z is a merge commit that is the head of the feature branch to take from, and X and Y were on a sub-feature branch.
I'm using: git rebase --preserve-merges --onto C V Z
I'd like to end up with:
X - Y
/ \
A-B-C-W ------ Z
But instead I'm getting:
A-B-C-W-X-Y
Since Z was a conflict-free merge, the final state of the code is correct, but the history isn't as expressive as I would like.
Is there a way to get what I want?
edit to address @Bombe: I've written a bash script to construct my example. On my system (RHEL 6.2 with git 1.7.1) this demonstrates my problem.
#! /bin/bash
# start a new empty repo
git init
# make some commits on the master branch
git checkout master
touch A.txt; git add A.txt; git commit -m "add A.txt"; git tag Atag
touch B.txt; git add B.txt; git commit -m "add B.txt"; git tag Btag
touch C.txt; git add C.txt; git commit -m "add C.txt"; git tag Ctag
# now build the feature branch
# start at Btag (more or less arbitrary; point is it's before C)
git checkout Btag
git checkout -b feature
touch V.txt; git add V.txt; git commit -m "add V.txt"; git tag Vtag
touch W.txt; git add W.txt; git commit -m "add W.txt"; git tag Wtag
# now a subfeature
git checkout -b subfeature
touch X.txt; git add X.txt; git commit -m "add X.txt"; git tag Xtag
touch Y.txt; git add Y.txt; git commit -m "add Y.txt"; git tag Ytag
# merge the subfeature into the feature
# preserves branch history with --no-ff
git checkout feature
git merge --no-ff subfeature
# the merge commit is our Z
git tag Ztag
# one more commit so that merge isn't the tip (for better illustration of Z missing later)
touch postZ.txt; git add postZ.txt; git commit -m "add postZ.txt"; git tag postZtag
# now do the rebase
git rebase --preserve-merges --onto Ctag Vtag
# optionally move the master branch forward to the top of feature branch
git checkout master
git merge feature
Before the rebase I get:
X-Y
/ \
V-W-----Z-postZ
/
A-B-C
After the rebase I get:
X-Y
/ \
V-W-----Z-postZ
/
A-B-C-W'-X'-Y'-postZ'
Note the lack of Z' between Y' and postZ'.