views:

78

answers:

1

The following is a scenario I commonly face:

You have a set of commits on master or design, that I want to put on top of production branch.

I tend to create a new branch with the base as production cherry-pick these commits on it and merge it to production

Then when I merge master to production, I face merge conflicts because even tho the changes are same, but are registered as a different commit because of cherry-pick.

I have found some workarounds to deal with this, all of which are laborious and can be termed "hacks".

Altho' I haven't done too much rebasing, I believe that too creates a new commit hash.

Should I be using rebasing where I am cherrypicking. What other advantages does that have over this.

+1  A: 

You should make a rebase --interactive your design branch on top of production, where:

  • you can reorder your commits, starting with the ones you need in production
  • you can then merge production to the last commit of design you want to incorporate (fast forward)
    -x--x--x1--x--x2 (design)
      \
       p--p (production)

With x1 and x2 needing to be included in production:

git checkout design
git rebase --interactive production

-x
  \
   p--p (production)
       \ 
        x1'-x2'--x'--x' (design)

Then:

git checkout production
git merge x2'
-x
  \
   p--p--x1'--x2' (production)
                \
                 x'--x' (design)

That allows you:

  • to validate current design commits against the production commits (durung the rebase)
  • reorder the design commits
  • include the first ones in production
  • allows subsequent merges from design to production to be a fast-forward one.

Lakshman Prasad adds:

I push the changes at the end of the day most of the time. So doesn't really help that much. How would your answer change for the pushed master branch

I would do the same, but with a private branch created just for the operation:

git checkout master
git checkout -b master-private
    -x--x--x1--x--x2 (master, master-private)
      \
       p--p (production)

, then the rebase, this time with the private branch (i.e. a branch you won't ever push).

git rebase --interactive production

-x--x--x1--x--x2 (master)
  \
   p--p (production)
       \ 
        x1'-x2'--x'--x' (master-private)

Then:

git checkout production
git merge x2'

-x--x--x1--x--x2 (master)
  \
   p--p--x1'--x2' (production)
                \
                 x'--x' (master-private)

master won't benefit from the commit reordering (with a more logical order), but at least you can push master whenever you want.

And production can still include exactly what it needs.
If subsequent commits to master have the same issue (some need to be included to production, other will later), I would:

  • delete master-private (we don't really care about those x', copy of x commits from master)
  • make a master-private branch on top of master
  • re-do the rebase --interactive, with a crude conflict resolution tactic (except for the first commits of that master-private branch, since those ones need to be integrated in the production branch)
    -x--x--x1--x--x2--x--x3--x (master)
      \
       p--p--x1'--x2'--x3' (production)
                   |     \
                   |      x''--x'' (master-private)
                    \
                     x'..x' (old x' from the first master-private)
VonC
VonC, I push the changes at the end of the day most of the time. So doesn't really help that much. How would your answer change for the pushed master branch.
Lakshman Prasad
@Lakshman: if you push but nobody pull, then it works. But if not, you need to have a special private branch you create on top of master, before "rebasing interactive" that same (private, i.e. not pushed) private branch on top of production.
VonC
@Lakshman: off course, that means you never merge master or design to production (since it will trigger lots of conflicts). You always rebase --interactive a private branch you make whenever you need one on top of master or design.
VonC