One thing I don't like with Git is the amount of commits. Don't get me wrong, it's a very convenient method of storing (safely) your work but in the long run there is too much granularity to search into.
Let me describe the following scenario while developing with feature branches branched from develop.
- Feature1 is branched from develop and has 5 commits
- Feature2 is branched from develop and has 3 commits
- Feature3 is branched from Feature1 and has 5+2 commits.
The reason there are three branches is because there is a team working on the repository. Feature3 assumes the Feature1 is done, waiting to be merged into develop. There are other use cases for this but this is the simplest example.
My goal is to have three commits on develop when all features are done.
Using git merge/pull
The above scenario works well. Because in essence both commands move commits into the develop branch. When Feature1 is merged, develop references it's five commits. When Feature3 is going to be merge, only the last two commits will be merged into develop.
The only negative aspect of this is that develop gets too many commits. That means that when merging into master all that "noise" moves along. Therefore my goal is not achieved.
Using git merge with squash
When Feature1 is merged, develop gets a new commit which is the aggregation of all Feature1. This is very nice, as the feature is now tracked with only one commit. When Feature1 is removed, all intermediate commits are not visible any more making tracking easier. This also matches with concepts such as one pull request and one github issue.
When Feature3 is going to be merged there are conflicts and the problem starts. To solve this, you need to merge the develop back to feature3. with conflicts. This results to a new commit that has zero files changed. And now we merge squash Feature3 to develop.
My goal is achieved but with a lot of micro-management sacrifice.
Questions/Remarks
As far as I understand this is the git reality. One advice I've read is to create a sibling feature branch that holds the squashed merge commit. Use the sibling branch for the pull request therefore enforcing the usage of one commit per feature. This doesn't solve the conflicts created when trying to merge the other branches in, especially the ones inheriting from other feature branches.
- Can a do an internal squash within the same branch? I don't think so, but doesn't hurt to ask.
- I'm I missing something?
- Is this the trade-off of squash merge? Resolving conflicts that potentially have zero code changes?
- Is it worth while to go after the "one commit per feature" concept?
- If not, then what's the purpose of squash? Who is using this?
I've read alternative with rebase and simulating the squash with reset after merge, but as far as I understand none solves the overhead mentioned to merge feature3.