How often should we 'git commit' ?
Just want to take the temperature on the community's thoughts towards commit size - Do you commit little and often (eg. "Added foo() method to Bar") or do you do fewer larger commits (eg. "Added fooList feature")?
It's currently a debate that's heating up where I am and I'm curious what the community thinks.
I'm a fan of the former - doing lots of small commits because my release process is fully automated, meaning I can keep track of lots of small changes to prod.
Here's a strawpoll because numbers, but I'd like to hear your thoughts on the topic;
I'm inclined to agree with you. Frequent small scale commits of working complete code is the way to go. Makes rolling back a whole lot better as you're not gonna undo a huge chunk of work. Plus it makes for much more meaningful commit messages and all other sorts of good things.
However, sometimes a big, chunky commit is unavoidable and not necessarily bad. In my experience during the lifetime of a project commits become smaller and more focused as time goes on. But initially there can be a couple of hefty commits with a bunch of changes that implement big features from scratch. Not always bad as long as you know that you're doing it and why, I think.
Personally i like branches cause they allow best of both. You make small commits until a feature is finished and smoke tested then squash the history into one commit before merging to keep the main branch clean
@PerfectAsshole I suggested that as well, everything I do is in topic branches with a ton of small commits, I suggested rebasing/squashing into a single commit before it gets merged but apparently that's not a solution :/
I commit for whole features or whole bugfixes because I hate it when the history is littered with hundreds of stupid one line commits.
Of course, make small commits. But don't commits pieces of code like setters and getters. Instead, commit your workflow, one commit per step. For example:
1. Stub SomeClass
This commit contains stub methods, i.e., the interface of a class.
2. Stub SomeClassTest
This commit contains the test methods you will write for SomeClass.
3. Test SomeClass
This commit implements the tests. At this point they fail, but at least you now have tested the specification for SomeClass.
4. Implement SomeClass
Here is when you write SomeClass. All your tests turn green.
Of course, some of these steps might require many steps, refactoring, adding libraries, etc., but that's where branching comes in. All this work happens on a feature branch for SomeClass. Any smaller steps can be committed to smaller subbranches. When ready, they can be squash merged into the feature branch to create the 4 commits above.
In turn, when SomeClass + tests are ready, I'd squash merge them to a development branch.
Finally, when all features and bug fixes are ready to be released, they can be squash merged into master or some other production branch.
In this way you have the best of all worlds:
- There are huge (squash or regular) merge commits with entire releases, features or development steps on the longer-lived branches.
- There are tiny commits per nitty-gritty change, that can easily tell you where bugs have been introduced.
Using a system like GitHub really makes it easy to keep a pristine history with few commits (one per release is possible!), while a the individual PRs and their commits can be found as well.
In this way, the details cascade in and out of view when required!
So in conclusion: commit small workflow steps, but (squash or --no-ff) merge them away!
I branch, then do small commits there, then squash and merge once the feature is done back to master
I make any number of commits of various sizes in my feature branch, but then I squash them all so I have one commit per issue when merging to master.