Using Git to merge all changes from a feature branch during development into a release branch
We use GitFlow to manage our software repositories: http://nvie.com/posts/a-successful-git-branching-model/
I have a situation where I'm not sure how to handle this branching model.
Within a couple of weeks, I made about a dozen commits per branch feature
(forked develop
). To reduce the load on check-in develop
, I merged the changes from develop
into my branch feature
3 times during those two weeks. The fork is feature
complete and its changes are merged into the develop
.
However, as it turns out, this feature is also required on a branch release
that was forked from develop
about a month ago. Is there a way to only merge the changes from this old branch, but omit the changes to develop
which I pushed into it 3 times?
source to share
According to the Git Flow model, you missed the train
Your repo should look something like this:
o - o - o - o - o - o [master]
\
\ o - o - o - o - o [release]
\ /
o - o - o - o - o - o - o - o - o - o - o [develop]
\ \ \ /
o - o - o - o - o - o - o [feature]
However, if you and your team are really following the Git Flow model, I have bad news for you: the ship sailed. In particular, it is too late for you to include features from your branch feature
(now also in develop
) into the branch release
. It just isn't allowed by Git Flow.
If you look at the next part of the main nvie.com , you can see that after the release branch is created, it is not allowed to receive anything from develop
, let alone any feature branch. The sole purpose of the release branch is to stabilize / consolidate towards the actual release, i.e. Merging into master
.
If you really stick with the Git flow model, you should
- either abandon the current branch
release
and create a new one outgoing from the tipdevelop
, - or freeze all work on
release
and then reinstall it ondevelop
before resuming work on it, - or wait for the next version to include your new features in release.
If you are ok not sticking with Git Flow ...
If you're willing to go against the Git stream on this, you can always use your functions in release
without polluting it out of the latest stuff develop
. The downside to this approach is that your history will be a little messy and will contain "duplicate commits"; but I don't think you have much choice if you really insist on including your features from branch feature
to the current / active version.
For convenience, let's say your repo looks like this (I've labeled multiple commits with letters):
o - o - o - o - o - o [master]
\
\ o - o - o - o - o [release]
\ /
o - A - B - C - o - o - o - o - o - o - o [develop]
\ \ \ /
D - E - F - G - H - I - J [feature]
What can you do is
-
Departure
release
git checkout release
-
Get a list of all revisions that were not a merge, between commit A and the end
feature
; in this case it would be bit B, C, D, E, G, I and J. Commandgit rev-list --no-merges A..feature
should do it for you.
-
Pass this changelog in
cherry-pick
to apply the changes made by those commits on toprelease
:git cherry-pick `git rev-list --no-merges A..feature`
You end up with something like this:
o - o - o - o - o - o [master] \ \ o - o - o - o - o - B'- C'- D'- E'- G'- I'- J' [HEAD=release] \ / \ / o - A - B - C - o - o - o - o - o - o - o [develop] \ \ \ / D - E - F - G - H - I - J [feature]
-
Stabilize the branch
release
. - After
release
clickmaster
, you also have to merge it indevelop
, and you have to get back on your feet.
source to share