1

Our team's branching strategy is a mix between git-flow and trunk-based. A feature is developed in a branch, then deployed to a staging environment for approval, then merged into master and deployed to production. Lately a problem has been brought up that i don't even know how to search for.

I'll set up the context and then the problem.

development cycle with four branches

At stage 1 we have a master branch deployed to prod, and two undeployed feature branches: green and orange. They may or may not be from the same dev team.

At stage 2, for testing and business purposes we need to have both unrelated features in a staging environment, so we create a staging/features as a staging branch from master, and merge green and orange into it.

At stage 3 more work is put into those features and they go to the staging branch. Each feature remains independent because they get approvals from different stakeholders, so one being approved doesn't mean the other one is also approved, and one being approved does not require to "wait" for the other. They are independent from each other. The staging branch cannot be merged into a feature for the same reason (it'll carry the opposite feature).

At stage 4 green feature is approved to master, so it merges and all other features have to pull from master. Shortly after, orange is approved so it merges to master and the dev cycle ends.

Now the problem.

development cycle with five branches

Stage 1 and 2 are similar but with 3 feature branches instead of 2.

At stage 3 development continues and the features are merged into the staging branch, all good.

At stage 4, blue wants to merge new code into staging but has conflicts with existing code.

If I solve the conflicts at the staging branch, that commit cannot be merged back into any feature, nor into master. I may even have conflicts with all the other features.

Today my solution is to remember which feature had conflicts and apply the fixes when both go into master, but it's extremely fragile. Keeping notes elsewhere is also prone to be forgotten when a merge is performed.

Is there a better way to keep solved conflicts in this branching strategy and not rely on a person's memory?

Rafael Moreira
  • 176
  • 1
  • 11
Elías D
  • 11
  • 4

1 Answers1

2

It turns out the name of the branching strategy you're using is Gitworkflow, and it is the strategy that the Git project uses, so you're in good company there. Here's a article with a diagram which looks just like yours. Note that your staging/features branch is called next in Gitworkflow, and I will refer to that branch as next in the rest of this answer. The key point here is that you should occasionally blow away next and reset it to master to clean up the cruft. This also helps reduce the chance of conflicts on next, so the more often you can do it the better. (In one of the repos I work in that uses this workflow we currently reset next every two weeks.)

As for conflicts, there are 2 main types:

  1. Conflicts that are on both next and master due to new stuff that appeared in both places.
  2. Conflicts that are on next because of another feature branch, or a previous version of your own feature branch that conflicts with the current version.

Type 1 conflicts are easy because you just do whatever you would do normally- perhaps rebase feature onto master, or merge master into feature if you prefer.

Type 2 conflicts, which are the type in you are inquiring about, are a little more complicated because oftentimes you only need to resolve them on next. Typically in this scenario I either make a temporary branch just for merging into next, or I start maintaining two branches for the feature- the regular one, my-feature which is always "perfect" and ready to be merged into master, and my-feature_next which is just for merging into next and resolving conflicts.

Tips for this workflow:

  1. When creating your feature branch, if you start from git merge-base next master you may be able to initially merge into both cleanly. The more often you reset next to master the more likely this is to work.
  2. If you have many merges into next with lots of fixups, sometimes it's easier to base your branch off of next and work solely there by only adding new commits to your branch. When you're completely ready you can squash those commits down to a small number of "good" commits and then use the rebase --onto option for prepping your branch for merging into master.
TTT
  • 22,611
  • 8
  • 63
  • 69