The Conflict-Free Git Flow We Implemented at Kesia.id
Hey folks! At Kesia.id, we were facing a classic development dilemma: How do we keep our codebase organized, support rapid feature releases, and minimize the dreaded merge conflicts that slow everyone down? We found our answer by adapting a well-known Git workflow to our specific needs.
nvie's Git Flow – A Solid Foundation
We started with nvie's Git Flow, a widely adopted model that uses dedicated branches for features, releases, and hotfixes.
The core idea is elegant:
- master: Represents the stable, production-ready code.
- develop: The main integration branch where all finished features converge before release.
- feature branches: Created from
develop
, these are where individual features are built. - release branches: Forked from
develop
to prepare for a new release. - hotfix branches: Created from
master
to address urgent production issues.
The Challenge with nvie's Git Flow
nvie's Git Flow works beautifully when development timelines align perfectly with feature release cycles. However, at Kesia.id, we often need to cherry-pick features for immediate release, bypassing the standard release schedule. This led to:
- Increased merge conflicts: Frequent cherry-picking caused our
develop
branch to diverge significantly frommaster
, making merging a nightmare. - Slowed development: Resolving these conflicts took valuable time away from building new features.
Our Solution: A Tweak with Big Impact
To overcome this, we made a simple but impactful change to nvie's model:
We always branch features from master
, not develop
.
Here's how it works:
- Feature Branch: A developer creates a new feature branch directly from the latest commit on
master
. We keep these branches small and focused, with each branch addressing only one specific task or issue. - Development: The feature is built on the branch.
- Rebase and Squash: Before creating a pull request, the developer must rebase their feature branch onto the latest
master
and squash all their commits into a single, clean commit. This ensures a linear project history and minimizes conflicts when merging. - Pull Request to develop: When the feature is ready, a pull request is created to merge the feature into
develop
for integration testing. - Merge to master: Once approved and tested, the feature branch is merged directly into
master
for immediate release (or included in the next scheduled release).
The Benefits We've Seen
- Reduced Merge Conflicts: By branching from
master
and rebasing regularly, our feature branches stay much closer to the production code, drastically reducing conflicts. - Faster Feature Releases: Cherry-picking is no longer necessary, as features are already based on the latest
master
code. - Cleaner Development Process: The
develop
branch remains a cleaner staging area for integration testing before features are merged intomaster
. The linear history due to squashing makes it easier to track changes and identify issues.
Key Considerations
While this modified Git Flow has been a game-changer for us, it might not be the perfect fit for every team. Consider your own release cycles, team size, and frequency of hotfixes before adopting this workflow.
Let me know if you'd like a more detailed walkthrough of our branching and merging strategies!
I hope this is helpful for your blog post! Feel free to ask if you have any other questions.