I basically only use git merge
like Theo from T3 stack. git rebase
rewrites your commit history, so I feel there’s too much risk to rewriting something you didn’t intend to. With merge
, every commit is a real state the code was in.
It’s not rebase vs merge, it’s rebase AND merge.
Commit your changes into logical commits as you go.
Then just before submitting a pull request, review your own code. That includes reviewing your own commits too, not just the code diff.
Use rebase to:
- Swap commits so that related changes are together
- Edit your commit messages if you find a mistake or now have a better idea of what to put in your messages
- Drop any useless commits that you just end up reverting later
- Squash any two commits together where the first was the meat of desired change and the second was the one thing that you forgot to add to that commit so you immediately followed it up with another commit for that one missing thing.
Then, and only then, after you have reviewed your own code and used rebase to make the git history easier to read (and thus make it easier to review), then you can submit a pull request.
This sounds like a really good work flow. I’ve only started working professionally with git only few months ago when I switched jobs to gamedev (for some reason, even though I worked for three years as a pentester in cybesecurity company they literally didnt use VCS for anything), so I still don’t have proper git workflow of my own, and this sounds way better. Thanks!
Before I had to start making PRs, my whole git experience on personal projects was
git add . ; git commit; git push;
It’s correct that rebase
rewrites history, but it’s important to identify when it’s not acceptable. If you are working on a branch that is shared by others (typically main
), you should never use rebase
. But it’s an acceptable practice when used properly. I use rebase
on my feature branches whenever necessary. If it fell behind the main
branch I do git fetch
followed by git rebase origin/main
, resolve the merge conflicts and keep coding. I also use interactive rebase
when I need to tidy things up before merging the feature branch to main
.
That’s what I do as well. Where I work, it’s common to have branches that take long to be ready for merge (because of bureaucracy), but because of many teams working on the same app, the upstream branch changes quite often.
I see some coworkers make just a few changes and a lot of times reverting stuff so the diff might be 1 line in the end, but the commit history is a mess of 30 commits of merges, triggering pipelines and undone stuff that was discarded later.
Then sometimes they have to find where they changed something they broke their feature and it’s a hell time to find what commit actually has any relevance for the final result.
They’re both different commands and I use them for different things.
I rebase my dev branches on main to get rid of garbage commit messages due to me being lazy.
Squash and merge PRs into main, no merge commits allowed.
I think there are reasonable arguments for allowing rebase and merge to main, but it often doesn’t apply for me.
Merge commits in main will break a lot of out of the box GitOps tools.
I’m okay with squashing consecutive silly commits before a merge, but having worked on a codebase that used the policy described above for a decade before I got there, I really, really hate it. Git blame and other history inspection tools are nearly totally useless. I’ll have access to commit messages, but when things have been shuffled around feature branches for a while, they end up concatenated into mega commits with little hope of figuring out why anyone did anything or what they were thinking when they did it. Some of this might be mitigated if stale branches weren’t deleted, but people don’t like stale branches.
If there are genuinely Git tools that can’t handle merge commits in <current year>, I’d be surprised if they didn’t have Fisher Price or Hasbro written on the side.
I’ll often commit half finished or outright broken code to a private branch for my own purposes. Then I’ll rebase before pushing to make the history make more sense to the team and get rid of fluff commits.