I have seen a lot of similar questions here, but none answered our specific problem. My question is actually about Merge Strategies, but I have to describe our git flow first. I have done a lot of reading best practises for an ideal Git Workflow, but nothing I found was perfectly suitable for our needs. So we might be using an unideal methodlogy.
Here is the flow:
We have a master branch, aligned with the production environment. We have a releasable branch to test the release package in a pre-prod environment with realistic data. We have a stable branch for testing in stable environment. And when we're starting to work on a new feature, we create a feature branch from master. When the feature is completed, we merge it to stable via pull pequest. Here is the problem; a lot of features either get cancelled after testing is completed or they have to wait for future releases, so we have to branch off of master because we don't want those features to be in our new branches. For that reason, we also cannot merge stable with releasable. So, if the feature is ready to go ahead, we merge the feature branch to releasable via another pull request. Now, there is a different commit between stable and releasable because of the merge commits. After the package is ready for deployment, we merge releasable with master. Here comes my problem; when we create a new feature branch from master to start working on a new feature, it has a slightly different commit history to stable. Because of this difference, sometimes all the file changes show up in the diff between the feature branch and stable even though they are identical in content.
We are using Bitbucket. I have considered using -ff instead of --no--ff in pull requests, but I also do not want to lose merge commits. I have also considered using Rebase, merge (rebase merge --no-ff) merge strategy in Bitbucket, but I am not sure it would solve our issue of not having a clean pull request.
To summarize, I need to have clean pull requests to stable with only the changes that are done in that feature branch without having to sacrifice too much.
Any help would be appreciated.
CodePudding user response:
There isn't a one-size fits all Git Branching Strategy but there are generalizations that cover the majority of scenarios. They tend to fall into one of these categories:
- Single Long-Lived Shared Branch (usually
main
ormaster
). This can be further broken down into 2 subcategories: A.) Trunk Based Development (TBD) where developers all work on a local copy ofmain
, and B.) Devs all branch off ofmain
with their own personal branches and merge back intomain
. Even this has many options, such as rebase then fast-forward merge, or rebase and--no-ff
, or no rebase at all, or with/without pull requests, etc, but the overall encompassing idea is a single shared branch that everyone works off of. This is popular with CI/CD type delivery. - At least one Long-Lived Shared Branch, and some number of Short-Lived throwaway integration branches. This is what the maintainers of Git use, and it is called "Gitworkflows". This is the category I would recommend for you; more details below.
- Separate Long-Lived Shared Branches for simultaneous development on the current pending release, and also the next future release after the pending one. This category is the flavor of strategies that are similar to "Git Flow".
- Some combination of the other three.
Note your question is very similar to this one, and the answer there is almost what I would recommend in your case, but with a tweak. The main difference is that in your case, you have 2 long-lived branches (master
and releasable
), and you would likely benefit from making your stable
branch a throwaway branch that you reset to master
every so often. (You could also rename stable
to next
if you wish to align more closely with Gitworkflows.) I have found that a reset frequency of 1 or 2 weeks usually works nicely for the next
branch. The more often you reset, the better, since it more closely resembles what will happen when you merge into master
. But you don't want it so often as to upset devs who aren't done testing yet and would then have to redo their merges into next
to continue testing after a reset. A possible reset frequency that would solve your immediate problem would be to reset stable
to master
as soon as you merge releasable
into master
.
Side Note: At my company we use all 3 categories of strategies in the same repo, depending on the project (so that puts us in category 4). For our Git Flow projects, we also utilize next
as a "pre-test" in a sandbox Dev environment so that a decent level of integration can be achieved prior to merging into develop
. We reset next
once per week for that project.