In this blog we were going to discuss some “Feature branching and it’s repeated sync” disorder and it’s cure using git “rerere” to keep the sanctity of git BPF – Branch Per Feature.
First of all, I would like to discuss benefits of git BPF and how we miss use it and fall in trap of “Feature branching and it’s repeated sync” disorder.
Some Benefits of using Git BPF :
- Feature branch is used to segregate frequent merges to main branch related to particular feature or bug/hot fix, hence you work on features independently, and so they never affect anyone else’s work during development process.
- Easy to perform code reviews and branch specific testing on the feature branch without holding anyone if there is a bug in your code.
- Our all feature branches are forked/created from a master/develop branch (I would prefer develop branch in sync of master i.e. master is production branch, at the point of the last release).
- We need to merge regularly into a third branch forked from develop as throw-away integration branch (any forked branch from develop) to resolve merge conflicts and validate anything isn’t breaking, which can be throw-away after you use it to perform actual merges to develop.
- We can have QA branches, like idt (Integration and Developement testing), iat (Integration and acceptance testing etc…). After performing test over there branch which contain all content from feature branches which are stable and needed in release, using merge and tested over these branches. Later being merged to master for production release
- One of the Major purpose of using Feature branch : We branched to achieve a particular goal (example : “adding functionality/feature”, “hot fix”, “support”, “testing” etc…”) and for that we can have a dedicated branch to keep the history of that branch more readable and understandable.
There might be many more….
Problem we face using Git BPF related to “Feature branching and it’s repeated sync” disorder syndrome :
When 2 devs are working on the same chunk/part of code over different features branches and when they try to perform merge, it will be obvious for them to get the conflict over code. If feature branch is long-lived branch then they can expect a huge list of conflicts to resolve.
To avoid that pain we mostly fall in the trap of the disorder named “Feature branching and it’s repeated sync”. You will start doing frequent pull of develop branch over your feature branch to remain in sync.
Drawback of syndrome :
It obviate the purpose and major goal of BPF i.e. to keep the history more readable and understandable as we kept merging master/develop into feature branch.
To avoid disorder, we should not commit any changes we pulled from develop branch over feature branch for the purpose of testing the stability of our feature branch. It will led us to trap of resolving the same conflict every-time we take pull and after testing resetting branch to feature branch state which is rather more painful and time consuming majorly in long-lived branch.
Cure : We need to visit and understand about cure from Git Specialist, Dr. ReReRe (Reuse Recorded Resolution) :
To enable “ReReRe” over git, we need to do the following :
git config --global rerere.enabled 1 git config --global rerere.autoupdate true
Understanding enchanting “ReReRe”:
For example : We have a develop branch having file named sql.properties
url=jdbc:mysql://localhost:3306/ dbName=rerere_dummy userName=rerere_test password=rerere_test
We created feature branch from it named “feature/configureDatabase” :
url=jdbc:mysql://localhost:3306/test dbName=rerere_test userName=rerere_test password=rerere_test
Some other person perform the same change over branch “feature/devDatabaseConfiguration” setting :
url=jdbc:mysql://localhost:3306/dev dbName=rerere_dev userName=rerere_dev password=rerere_dev
and merge it back to develop.
Now when I am going to take pull of develop branch over “feature/configureDatabase” will led me to conflict. I will resolve the conflict test the changes with it. After stability and testing I need to revert them back to keep sanctity of feature branch commits dedicated to it only.
Using ReReRe is simple :
Create throw-away branch from develop, for example : rerereDbConfigTest
Now checkout rerereDbConfigTest and merge your feature branch “feature/configureDatabase” to “rerereDbConfigTest” which will led to conflict. Resolve the conflict and run command :
git rerere Recorded resolution for 'sql.properties'
As you can see rerere recorded the conflict resolution for file “sql.properties”.
Now do git reset –hard over it. As your resolution is already recorded in .git/rr-cache
Now whenever you do merge to develop branch, it will give you Conflict but with resolution :
Auto-merging sql.properties CONFLICT (content): Merge conflict in sql.properties Staged 'sql.properties' using previous resolution. Automatic merge failed; fix conflicts and then commit the result.
Highlighted line above shows, you have staged resolution of this conflict. All you need to do is run this command to resolve conflict as per resolution recorded previously by rerere :
git rerere status sql.properties
Your file will get the resolution from the .git/rr-cache file and conflict will get resolved from recorded cache after running above command.
Now you just need to commit/push your changes over develop, no manual conflict resolution.
It will save your time in case of huge conflict resolution while you work on long-lived feature branches. And you can remove or throw away “rerereDbConfigTest” after performing testing and merging your feature branch to develop. Make sure you don’t push throw away branch to remote.
What we achieve :
- Readable and understandable commits over feature branch, which are dedicated to it.
- Cure of “Feature branching and it’s repeated sync” disorder, keeping sanctity of Git BPF.
- Overcoming fear of merge and repeated conflict while using Git BPF over long-lived branches.
Some references :
- Git – Branch Per Feature Documentation
- Git – rerere command Documentation
- Git – rerere command usage – Detailed
I came across this cool feature of git and thought to share with our subscribers. Those who aren’t aware of git goodness, Hope it helps