0

We have are a small team of 6 people working with Scrum and Git.

We are developing a quite complex webapplication with the ZK Framework. It uses Java and a MySQL database.

We have adapted the "Git workflow" by Vincent Driessen from:

https://nvie.com/posts/a-successful-git-branching-model/

This results in the following diagram, showing our model:

Git workflow

When we develop a new feature, we branch off of the "develop"-branch.

After a feature has been completed, we do 2 stages of testing - internally (the developers) and externally (the customers that suggested the feature).

For the customer-test, we have a "sandbox", which is more or less a 1:1 copy of our live-system. It has it's own database and branch.

It has it's own branch "sandbox" and is sort of a "pre-release".

Our problem:

We have 1 person doing the merges from the feature-branch into the sandbox-branch, including solving all merge-conflicts.

(We know this is not scalable and soon every developer might need to merge + conflict-solve their own feature-branches. We are still learning and adapting)

Then the customer goes into the sandbox, tests the feature and says either "fail" or "success".

1) Fail - we fix the feature.

2) Success - we close the feature and merge it into develop.

And this is where we are not sure if this process is optimal - you basically need to merge + conflict-solve at least twice, because while testing on the sandbox, the develop-branch keeps getting new commits, which often can result in the feature-/sandbox-version being different from the develop-verson -> merge-conflicts.

Is there a way to solve this more elegantly?

And / Or is there a way to reduce the merge-conflicts?

No data flows back from sandbox into the feature. The arrows labeled "Test: Fail / Success" are merely used to show that the customer tested it and gave his "okay".

We also do not develop on the sandbox.

6
  • 1
    Only demonstrably 'sucessful' branching strategy is trunk-based development with continuous integration. amazon.com/… – Euphoric Jun 10 '20 at 13:03
  • Just to be sure. "Sandbox" only hold one feature at a time? Or all ready features? – JayZ Jun 10 '20 at 13:26
  • @JayZ: All features, including features that are not ready. Think of it as a testing-ground. – hamena314 Jun 10 '20 at 13:32
  • what are the back arrows from sandbox back to the feature branch? DELETE THIS BRANCH – Ewan Jun 10 '20 at 18:03
  • @Ewan: The arrow from sandbox back into develop labeled "Test: fail / success" are simply information-flow. When the test has been completed, the customers click on a "tested"-checkbox in our ticket-system, so then we can merge the feature from the feature-branch into develop. No data flows back from sandbox to develop. And we also do not develop on the sandbox. – hamena314 Jun 10 '20 at 21:14
4

As your image shows, the Sandbox branch can contain commits from (multiple) unfinished features. This means that in practice, what gets tested is never the same as what gets merged into develop nor the result of merging a feature into develop.

Your features may have been independent enough that this didn't bite you, but someday it will. And the fact that you encounter merge conflicts on both merges suggests that one of two things is happening and neither is desirable

  • features get a failed test result due to an earlier failure on a related (unfinished) feature
  • code from an unfinished feature gets merged into develop together with another feature

As a way forward, I would recommend that you abandon the Sandbox branch. Instead, you configure the sandbox environment such that code from any branch can be installed on it. And next to that, you implement a reservation mechanism, so that people know when the customer is testing a feature and they shouldn't change what software is running in the sandbox environment.

3
  • I am not sure if I get "code from an unfinished feature gets merged into develop together with another feature" correctly. Please bear with me: Do you mean, that the whole sandbox gets merged back into develop? Because this is not the case. The arrows labeled "Test Success / Fail" are merely the information, that the test failed / succeded. No commit goes from sandbox into develop. Did I understand this correctly? – hamena314 Jun 11 '20 at 13:11
  • @hamena314, what I expect is that you would get changes from unfinished features into your feature branch during the conflict resolution of merging your branch to the sandbox branch. My expectation might be off. – Bart van Ingen Schenau Jun 11 '20 at 13:15
  • "code from an unfinished feature gets merged into develop together with another feature" you probably mean "merged into sandbox" – max630 Jun 11 '20 at 14:39
4

I don't have access to the image but from your explanation I understand that "sandbox" is a fork of "master" where features are merged to be tested.

There are multiple ways to solve this depending on your system and process

  1. Scrap "sandbox", customer test on "develop". You still branch from develop for fixes in case of customer feedback. Stop merge into "develop" when approaching a release and focus on fixing feature. When all features on "develop" are green merge "develop" in a release branch. Reopen merge on develop.
  2. Have customer tests on feature branches. You need to be able to deploy differently per customer. Easy for standalone software (like a game), harder for complex systems.
  3. Have "sandbox" forked from develop. Only merge "ready" features in sandbox. When all features are OK, you can merge on develop. Problem is you risk to continually have untested feature (by customer) that prevent merging.

IMO the best solution is 2. but is not always an option. 1. is using develop as a beta branch but may force some developer to keep some feature branch branch open if they miss the window to merge before a release.

4
  • 1) would mean, that feature-branches only exist to help the development, we would not test on them, yes? In order to test develop, we would have to close the feature-branch and test on develop, meaning we would need to open a new feature-branch if the test fails and we fix it? – hamena314 Jun 11 '20 at 13:08
  • 2) I have added information about our systems. We develop a complex webapplication with Java, ZK framework and a database. Each of our developers runs a local Tomcat with our version of develop + feature. When we add a new column in a database-table, this change is only in the local db. So the customer would have to test locally on the developer-machine. Else we would need to monitor, which column is new and remove it after every test. – hamena314 Jun 11 '20 at 13:08
  • 3) What do you mean by "ready features"? – hamena314 Jun 11 '20 at 13:08
  • Just a suggestion, either in feature or develop branch, you could tag the branch as RC (release candidate) and deploy the tag, not the branch so others can keep working with these branches without compromising the tests – Laiv Jun 11 '20 at 13:12
2

Others have pointed out that your sandbox branch is flawed, your diagram even shows code being merged into and passing its test when the code is in a failed state from the previous feature.

However, I think you have bigger problems

[feature is merged into sandbox] Then the customer goes into the sandbox, tests the feature and says either "fail" or "success".

Having customer acceptance per feature, regardless of branching strategy, is going to be super hard and cause lots of merge problems.

The reason is that features are not developed one at a time, or in isolation from each other.

If you test feature A and it fails, and test feature B and merge it in. Now feature A has to be retested with the B changes and then with C, D etc if they don't complete fast enough. Before you know it you have a super long lived feature branch which is always having to merge and test

Unless you work on a single feature at a time You have to have some grouping of features into releases and test the release rather than individual features.

Pulling a feature from a release is a big decision, because of the knock on consequences on the other features. You can't let the customer decide at the last minute. Get them to agree the features they want in the next release.

1
  • We explicitly wanted to have a system with "cross-testing", meaning we put all features into it and test it. Because if we test feature A independently from feature B, we put both features into develop - and dont test it further because it is hidden somewhere in our large program. Then when we release the new version, it crashes, since A + B interfere with each other, which we did not notice due to the independent testing. But I like the idea with grouping features, have to draw around a bit in my diagrams to understand the consequences. – hamena314 Jun 11 '20 at 13:14
1

Merge into develop and use feature flags to hide the feature. Deploy develop to the sandbox environment and enable those feature flags there. Develop can still be deployed to live with other changes as necessary, just don't enable the new feature. This means you are only merging once.

5
  • 1
    Interesting idea, but wouldnt this mean that feature A and B could still interfere with each other if they change overlapping parts in the code? – hamena314 Jun 11 '20 at 13:16
  • 1
    @hamena314 Yes, and isn't it good that you found that out early rather than when both were "done done"? – Jacob Raihle Jun 12 '20 at 7:07
  • Fair point, but it would require that at one point ALL features are activated and tested simultanously. If I have A, B, C, ... Z in develop, but only A is "activated", I wouldn't notice the interference of A with B, C, ...Z, would I? – hamena314 Jun 12 '20 at 9:07
  • I think it would usually be clear when designing or implementing the features, but that could happen, yeah. You would need to test the reasonable permutations of feature flags, if they are somehow related. – Jacob Raihle Jun 12 '20 at 10:00
  • 1
    @hamena314 Also, don't you at least smoke-test everything anyway when you release a new version? I mean, depending on architecture, any new feature could at any time break any old feature from a QA-perspective. Sure sometimes architecture design prevents that, but you would need to account that in general not only for new features, no? – Frank Hopkins Jun 13 '20 at 0:46
1

As some have said this way of working is problematic but threre are a few things that you can do to minimize the problem:

  1. Keep branches as short as posible. Long-lived branches will be problematic. It is better to have more small merges that will result in less conflicts. You can split your changes in smaller tasks but this will require a customer who is fast to approve.

  2. Reduce Work in Progress to prevent openning a new branch until the last one is finished. This is good thing in itself as work in progress is a kind of waste.

  3. Work on the same branch. 6 people in 6 different branches means a lot of conflicts. Pair programing means only 3 branches with shorter duration. Nothing prevents the 6 of you to work on the same branch.

  4. Merge changes from develop frequently into every branch.

  5. Use feature flags.

  6. Add a third criteria: "Fail" and "Success" are not enough. You can include a new decission "Needs changes" that would allow the merge but will requiere you to fix the bugs or make the appropiate improvements. Incremental improvement will go in the spirit of Agile.

  7. Use automatic build and tests. This should detect a lot of the problems caused by new commits. That way the client won't need a long testing process. Less errors will also reduce the "Fails" assesments and that means shorter branches. And hopefully the client will start to trust you so their evaluation will only focus on their business preferences.

  8. Choose to work on features that would minimize code conflicts. Surely you will have an idea about what modules would be changed so you can select be strategic to minimize merge.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.