5

So I am figuring out the simplest branching/deployment strategy from Github that at least has a dev and a release(master) branch. After seing this answer I think this is really close to what we need. Except the one big problem of being able to deploy only some features. Not everything.

The 2 options presented here are just not good enough. This is a common scenario and reverting everytime is plain nasty. Also, I have read that cherry picking has other issues as well specially because the cherry picked commits are actually copies (is this true?)

Now, I am thinking that if for new features that we start working on we create a branch, and we merge them to our chosen dev branch, we can merge those branches to the release branch (instead of merging from dev to the release branch, we merge from feature branch to both dev and release so we can chose what to release) so we would only have the desired changes ready for release. I can think of at least two possible issues with this:

  • The feature branch has been merged to both dev and release, will this get me in trouble later?
  • Will it work? since my feature branches could be based off changes made in other feature branches (they would be based off dev) when I merge the feature to dev I would have to pull first, thus adding the other features in.

So, in summary, how can i keep a dev branch, put some changes there, and later only move some stuff to another branch?.

Thanks a lot.

Community
  • 1
  • 1
Ernesto
  • 1,523
  • 1
  • 14
  • 32

1 Answers1

6

You can definitely do this. Here's what I'd recommend:

  • Base all of your branches off master. This accomplishes two things:
    • Your branch is based off of production, so it's ready to go out
    • You don't have things in your branch from dev that aren't ready for release yet
  • When you want to release a branch:
    • Merge branch into master
    • Deploy
    • Merge master into dev to keep it up to date. Otherwise people in dev get farther and farther away from what's in production.
  • When your branch is finished, but you don't want to release, merge into dev
  • When everything waiting in dev is ready to go out
    • Merge dev into master
    • Deploy

Something you'll run into is you're working on cool_feature and your coworker has branched fix_terrible_bug that you realize cool_feature needs. In that case, merge fix_terrible_bug directly into cool_feature and continue. When fix_terrible_bug is finished, it can merge into master or dev even if you're not done with cool_feature yet, and similarly you can merge cool_feature into either even if your coworker is continuing work on fix_terrible_bug. When the other branch merges, Git will do just fine (though when you're merging a lot like this, avoid rebases, they'll end up confusing things).


As a side note, don't worry about cherry-picks "copying" things. Every commit in Git is a bundle built from its contents, its parent commit, the current time, etc. When you cherry-pick, you're putting the same contents onto a new parent commit, so the commit hash necessarily changes and it's effectively a new commit independent of the original. That's just fine - Git is good at its job. Unless you're committing gigabytes of high def video, you're not going to notice any extra space used, and when the "original" commit joins paths with your cherry-pick, it will effectively be a no-op and eventually get garbage collected.

Kristján
  • 18,165
  • 5
  • 50
  • 62
  • 1
    Thanks. Branching from master seems reasonable. But you mention: "When everything waiting in dev is ready to go out", doesn't this leave me with the same problem I started with? Many many times this isn't the case. Many times we have several features in dev, only a few can go out. Maybe that's my answer, maybe cherry picking IS the only way. – Ernesto May 13 '15 at 16:01
  • Ah, so is it not the case that you can decide if a branch should deploy or not right as you're finishing it up? That's fine. Merge them into dev so everyone can use them, but keep the branch around so you can also merge it into master when it's ready to go. You can merge multiple branches into master if they need to deploy together, and it's no problem if they also merge to dev. For huge things, make a release branch for everyone to work from, then merge that into master/dev/anywhere. Remember branches are cheap, master/dev are not special, and you can sculpt your Git tree any way you like. – Kristján May 13 '15 at 16:11
  • I will give it a try. Will git "know" that the branch changes were already merged when I merge dev into master? – Ernesto May 13 '15 at 16:18
  • I believe branching from the "release ready" branch is almost the solution. The only pending issue is, anything I merge to development requires me to pull, thus adding changes from other features that are in dev. So, by just putting it in dev I am forced to change the feature branch. – Ernesto May 13 '15 at 16:27
  • Not quite. When you pull, dev updates, but a branch you've already created stays as it is. To get changes on dev into your branch, you'd have to explicitly merge dev into the branch. – Kristján May 13 '15 at 17:05
  • Yes, maybe i didn't explain myself clearly, here is the issue: if I want my cool-feature in dev, I have to merge dev latest changes into cool-feature, therefore changing cool-feature (merging it with anything anyone has added in dev since I started working in cool-feature). So if at some point I want only cool-feature into master, I can't. – Ernesto May 13 '15 at 17:28
  • I'm not sure I understand you correctly. You don't have to merge `dev` into `cool-feature` in order to merge `cool-feature` into `dev`. – Kristján May 13 '15 at 17:52
  • You are absolutely right. It was a missanderstanding from my side. I am confusing the process here with fast-forward errors you get when pushing changes to a remote (https://help.github.com/articles/dealing-with-non-fast-forward-errors/). I really appreciate your help. I think I have a much better idea of the process now. Thanks! – Ernesto May 13 '15 at 20:54
  • Two questions/additions to the already well-thought solution. 1. To a continuous flow I would add nightly merging of master to dev. In order to support spontaneous hotfixes on master being synced to dev. What do you think of that? 2. Why would I actually need to merge dev to master ever? I would prefer to revert features merged to dev from dev again, if it is decided that they should never go to master. – yau Jan 13 '18 at 13:58
  • One more subtlety. 3. What if you can't merge your feature branch easily into dev because of conflicts? Of course, you could just solve the conflicts within dev and continue your feature branch without those adaptions or fix them selectively. But this is not always possible/feasible, then you want to merge dev into your feature first and get an unwanted mix and can't blindly merge that to master. (By the way, conflicts merging into _master_ aren't a problem, as you can always easily merge from there into your feature since master is in the most tidy state.) – yau Jan 13 '18 at 20:53
  • For 1. I would say if the fix is ready and merged into master, then merge master to dev inmediately in case someone needs it. Not sure if I understand 2 completely, but in my case, dev is my constant dev branch so eventually changes merged there need to go to master. So you might want two or tree features that you merged into dev because you wanted to test together, then when you are sure, put them in master. – Ernesto Jan 15 '18 at 20:22
  • 3. I see the problem, but since you always branch from master and constantly merge master into dev to keep it updated, you reduce chances of a monstruous merge. If two features are so closely related that they cause a huge conflict and only one will go to master I would first evaluate if the features are correctly separated. If it does happen, i guess dev is the best place to fix those conflicts. – Ernesto Jan 15 '18 at 20:27