0

I want to take over changes from a range of commits.

The situation is the following. I have the master and my feature branch. I fixed a bug (with commits a to e) and bring this fix to the master. But there exists a release branch which should also become this bug fix. This release branch branched from the master several months ago and only gets new content for major bugs.

Usually, I take over the changes by hand into the release branch.
Is there a technique to get merge the changes from the feature branch with the bug fix into the release branch without m1?

From my point of view, a merge will not be possible because of the commits between the commit r1 and m1. But has anybody an idea how to handle this situation?

Branch Diagramm

phd
  • 82,685
  • 13
  • 120
  • 165
Korbi
  • 1
  • 1

3 Answers3

0

Depending on the changes introduced by the commits r1 to m1 and if they interfere with the feature branch, you can try to rebase the feature branch onto the release branch:

git rebase --onto release-branch m1 feature-branch

If they do not interfere, the rebase should by trivial and you can simply merge the rebased feature branch into the release branch. For more information: https://git-scm.com/docs/git-rebase

Sagre
  • 462
  • 3
  • 12
0

You can cherry-pick a range. The start index is the parent of the commit you want.

git checkout release
git cherry-pick a^..e
EncryptedWatermelon
  • 4,788
  • 1
  • 12
  • 28
0

There are (at least) two ways to do this.

The way I think most people will recommend is git cherry-pick; you can list the specific commits whose changes you want to apply to the release branch[1]. You can find documentation here: https://git-scm.com/docs/git-cherry-pick

The way I recommend is to use rebase. You can do an interactive rebase, perhaps as simple as

git checkout --detach master
git rebase -i <release_branch>
git branch -f <release_branch>

This will pull up a "to-do list', which you can edit to suit your needs. In this case, you can locate the lines representing the commits whose changes you want, and then delete everything else from the todo list.

Docs: https://git-scm.com/docs/git-rebase

IMPORTANT - note that the rebase is done in detached head state, to avoid moving any refs as part of the rebase; and when it's done you have to update the release branch so it includes the newly copied commits. These are the 'cost' of using rebase for this operation - though depending on preferences there are various ways to address it. But I still personally find it more user-friendly to do this (so git gives the TODO list I can search through and edit) vs. cherry-pick (which requires me to figure out expressions to identify the commits up front).

These methods are in most ways equivalent. A couple things to note:

These commands "copy" the original commit to the new location. The word "copy' is a little misleading here - a patch is calculated for each commit, representing the changes introduced by that commit; and those patches are applied to the new base to create new commits.

In some ways this is like manually applying the changes. In particular, git won't "remember" that the new commits are related to the original commits, so if for some reason you later wanted to merge between master and the release branch there would be potential conflicts - just as your previous manually-applied changes would likely result in conflicts.

But in other ways, this is like doing a weird sort of merge, and that means the cherry-pick or rebase operation itself could generate conflicts (and these aren't always the most intuitive, though most often they're not too bad as long as you think about what the command is trying to accomplish).


[1] - You can identify individual commits by their SHA ID, or by expressions relative to some ref (such as master~2 to mean "the 1st parent of masters 1st parent"). You can specify ranges of commits, like master~6..~master~2, though cherry-pick is a little funny about ranges. IF you follow the docs, they'll take you through many different variations

Mark Adelsberger
  • 42,148
  • 4
  • 35
  • 52