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
developto prepare for a new release. - hotfix branches: Created from
masterto 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
developbranch 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
masterand 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
developfor integration testing. - Merge to master: Once approved and tested, the feature branch is merged directly into
masterfor immediate release (or included in the next scheduled release).
The Benefits We've Seen
- Reduced Merge Conflicts: By branching from
masterand 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
mastercode. - Cleaner Development Process: The
developbranch 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.