8

We have a standard web project and maintain 3 core branches for this project: Master, Beta, and Develop. Here is a summary of the process/workflow that we use:

(1) A new feature/update is requested so we create a new Feature branch.

(2) A commit is made for the new Feature branch and the Feature branch is merged into the 'Develop' branch; the 'Develop' branch is then published to a testing environment to be tested.

(3) Once the new feature is tested/approved, a new pull request is made in the same Feature branch; this new pull request is meant to be merged into the 'Beta' branch.

The 'Beta' branch has all of our "ready-to-go-live" features: in fact, we publish the 'Beta' branch directly to the production environment and when that is ready we immediately merge the 'Beta' branch to the 'Master' branch....by doing this, the 'Master' branch is always a copy of the code that is on the production environment.

The problem: in step 3 above, when we try to merge the new Feature branch into the 'Beta' branch, the pull request includes ALL new commits that have been merged into the 'Develop' branch.

Example: 5 feature branches are individually merged to the 'Develop' branch (branches are labeled 1, 2, 3, 4, and 5). All 5 are tested, but there are bugs with the first 4. So branch "5" is approved and we try to create a pull request for that Feature branch and merge it to 'Beta'....but when we do that, the pull request includes all 5 feature branches....not just the commit for branch "5".

We MUST be doing something wrong! What can we do to fix our process/workflow?

Kris
  • 101
  • 2
  • 2
    Possible duplicate of [Do Git merges affect the "merged" branch?](http://stackoverflow.com/questions/40466290/do-git-merges-affect-the-merged-branch) – David Lipnik Nov 17 '16 at 20:07
  • Which branches do you test on? How often do the different features interfere with each other? – oyvind Mar 03 '17 at 08:24
  • The reason I ask is because it looks like you are testing only on one branch (develop), but you are still able to test/approve changes independently. So I'm guessing the features don't often intersect. – oyvind Mar 03 '17 at 08:25

6 Answers6

6

(3) Once the new feature is tested/approved, a new pull request is made in the same Feature branch; this new pull request is meant to be merged into the 'Beta' branch.

The 'Beta' branch has all of our "ready-to-go-live" features: in fact, we publish the 'Beta' branch directly to the production environment and when that is ready we immediately merge the 'Beta' branch to the 'Master' branch....by doing this, the 'Master' branch is always a copy of the code that is on the production environment.

The problem: in step 3 above, when we try to merge the new Feature branch into the 'Beta' branch, the pull request includes ALL new commits that have been merged into the 'Develop' branch.

No, that does not make sense. If that happens you have omitted important information such as:

  • Each new feature branch is branched off of another branch. Which one, development? Then it is clear that whatever development commits are in the history of a newly created feature, will also be merged into the beta branch. Git history is a directed acyclic graph, each commit pointing to one (normal commit) or multiple (merge commit) parent commits.
  • In order to make features merge cleanly into develop, maybe the feature branches are rebased onto development regularly or maybe the feature branches get refreshed by merging in the latest develop, both of which makes much sense and I advocate it. But in this case also their history contains all the history of develop at the time of merging/rebasing.

In each of these cases your workflow is fundamentally broken and cannot work with regard to your idea of a beta branch. So if you want to avoid cherry-picking (bad! bad! bad!) how can you achieve what you want to do? There are some basic options:

  1. Feature toggles: ugly. I would stay away from it whenever possible. The best way to inactivate a feature in any branch is not having the corresponding commits on that branch in the first place.
  2. Work cleanly: good. Refrain from merging back untested/unaccepted features to develop. Only merge them when they are done (as in "definition of done") and accepted by the client. Make sure you set up an environment enabling your clients to directly test on feature branches instead of mashing it all up onto a beta branch. This way whatever gets on development is inherently ready for production and you do not need the beta branch anymore. Unfinished work is never to be merged into a higher-level branch. This is what GitFlow is all about and it works. Even if you do not use GitFlow in its full glory but just master, develop and feature branches, the validity of my statements holds. I have worked like this in many projects and it works beautifully. Besides, if you think you need another branch to integrate features onto for future releases, create a new "next_release" or "future" branch for them and merge them to that branch, not onto develop. Then regularly refresh future from develop because you also want your features from the current release in the future release, but not vice versa. I hardly believe that this additional step will be necessary though.
kriegaex
  • 63,017
  • 15
  • 111
  • 202
  • Keith Pickering's comment on a different answer indicates that feature branches are created from the `develop` branch. I think your first bullet point is spot-on. – mkasberg Feb 26 '17 at 23:22
1

That's the way git works. You'll need to create separate branches for each feature.

Giacomo
  • 156
  • 1
  • 16
  • Employee from the OP's company here: we do create separate branches for each feature, as this is the entire foundation of GitFlow. Features are created from the "develop" branch, from which they are merged back into "develop", and also into "beta" if we need these changes on the beta site. – Keith Pickering Nov 16 '16 at 14:51
  • Tradition would dictate merging feature branches to "develop" ONLY, and then merging "develop" into "beta" when ready, but this doesn't work for us. The client sometimes needs to test new features selectively without using the most cutting-edge version of the site, which is the point of the beta branch existing. It's basically a less up-to-date version of "develop", but it's the one that gets merged into master for official releases. – Keith Pickering Nov 16 '16 at 14:54
  • Our problem is that sometimes, attempting to merge features into "beta" after they've already been merged back into "develop" will include several unrelated commits that SHOULDN'T be included in the feature branch, as neither develop, beta, or master should ever be merged INTO a feature. We just need to figure out what went wrong so we can keep our team from making the same mistake in the future. – Keith Pickering Nov 16 '16 at 14:55
  • 1
    Sorry if I chime in, but - sorry - you are not using Git the right way. What you want to achieve can easily be achieved in other ways. This says someone who has coached many dev teams as both a Scrum and Git coach, and none of my teams ever used such a twisted branch/merge workflow. And believe me, you do not have the most complex requirements in the world. – kriegaex Feb 26 '17 at 22:51
1

Once you merge a branch with another, the merging branch commits get commited on the home branch.

What you probably want to be doing is not even work on the development branch for development, but rather branch out of it for each feature (serialize the features, of course) which are then separately checked for bugs before merging packages of many feature branches into the development branch.

To get rid of bugs that got into the development branch anyway you will need to get the code working on the feature branch and then merge that OR revert the changes by reverting the feature branch using git revert and then merging the branch again (effectively reverting only the commits that it introduced to the development branch.

Reverting on the development branch (or any of the bigger branches in your hierarchy) is generally ill advised in the industry, except when you merge just a single feature... as different commits can establish dependencies between themselves and reverting can cause more harm than it solves.

To get a better hang on reverting read this guide by atlassian or the available documentation.

  • Hi, I'm on the same team as the OP - we are doing all work on individual feature branches, created from the "develop" branch, which are then merged back into "develop" when completed. These feature branches are also sometimes merged to a "beta" branch for periodic deployments to the beta server. Finally, "beta" is periodically merged to the master branch whenever it's ready to go live. – Keith Pickering Nov 15 '16 at 05:06
  • This workflow should work fine, but for some reason, whenever we try to merge our feature branches to "beta" (AFTER they've already been merged to "develop"), a bunch of unwanted/unrelated feature branch commits are merged into "beta" as well. We need to figure out what's going wrong so we can be able to merge feature branches to both "develop" and "beta" entirely independently from one another. – Keith Pickering Nov 15 '16 at 05:09
  • I'm not sure I understand ... You're merging the feature branches into the beta branch? After development branch is setup as it should be, you: `checkout beta`, `merge development`, and the branches are merged. And if you screwed up the development branch completely, with garbage commits that are buried beneath other commits ... what you want to do, unless you're ready to ['cherrypick'](https://git-scm.com/docs/git-cherry-pick), is delete the development branch, and branch out again from the working beta. I take it this is a school project of sorts? If so, don't cherry-pick – David Lipnik Nov 15 '16 at 21:18
  • You're correct, our workflow differs from the traditional GitFlow. Feature branches are merged into EITHER develop or beta, entirely independently. We never want to merge develop into beta or vice versa. The reason for this is that sometimes the client wants to test new features on a "beta" subdomain of their site, but the develop branch is too cutting-edge. – Keith Pickering Nov 16 '16 at 14:42
  • So the develop branch serves as the latest version of the code which we create all new feature branches from. These feature branches are always merged back into develop when completed, but we also merge them into the beta branch one by one when they are ready to be tested. If the client is happy with the updates, then beta is merged into master. – Keith Pickering Nov 16 '16 at 14:45
  • Our problem is that we have a hard time understanding git history (either visualized or not) so we can't figure out why merging certain features to beta—after they've already been merged back into develop—is sometimes including unwanted features which should NOT be on that particular feature branch. We need to know how such an error could potentially occur so we can know what to look for in the commit history. – Keith Pickering Nov 16 '16 at 14:47
  • If you run `git diff beta` while you are on your feature branch, you will get an output of every line which was removed or added to the code, with each snippet headed with information on the file paths. More on that [here](https://git-scm.com/docs/git-diff) – David Lipnik Nov 17 '16 at 19:08
1

You're correct, our workflow differs from the traditional GitFlow. Feature branches are merged into EITHER develop or beta, entirely independently.

Once the new feature is tested/approved, a new pull request is made in the same Feature branch

        f2--f2--f2   (f2)
       /          \
d--d--d--D1-------D2 (develop)
\       /
 f1---f1

a bunch of unwanted/unrelated feature branch commits are merged into "beta" as well

Strange: that would be as if f2 was on the D2 merge commit (which has f2 but also f1).

For testing, could you try in command-line to cherry-pick the exact commits you want, then merge them with --squash.

git checkout -b tmp develop
git cherry-pick  $(git merge-base develop f2) f2
git checkout beta
git merge --squash tmp

That way, you can validate you only get the exact f2 merged branch you want in beta, and not all the other features.
Once that is validated, we can work on doing the same from a GUI (like for instance SourceTree)

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
1

You say that merging feature 5 into beta will bring features 1-4 into beta as well. If so, the commits for features 1-4 are definitely in the feature 5 branch. There are 3 ways that could happen:

  1. Feature 5 was branched out from develop after features 1-4 were merged into develop.

  2. Develop was merged into feature 5 (upmerge) after features 1-4 were merged into develop.

  3. Features 1-4 were merged directly into feature 5.

Beware that a branch contains not just the commits made directly to the branch, but also all commits from the beginning of the repo up to the branching point, and any commits in branches merged into the branch.

BTW, the 3 points above hold even if you change 'merge' to 'rebase', or 'develop' to any other branch.

oyvind
  • 1,429
  • 3
  • 14
  • 24
1

I would be doing the follow steps.

  • Feature branches created from develop.
  • Once feature are done merge them to develop branch.
  • When time for testing comes I will create a test branch and do the tests there.I will fix any bug which comes in testing there itself.
  • Once my test are all successful I merge the branch to both master and develop.
  • I would then release my code from master to Beta environment.

I will keep in mind the following things .

  • If a feature is not needed for particular release I would not merge that feature to develo branch.
  • If I could not solve any bugs while testing I would not be releasing that code,hence as in the question I would have solved all the bugs and would be releasing the whole code.
jones j alapat
  • 931
  • 3
  • 13
  • 26