I don’t understand it. Every time I see something about a rebase it’s some purist telling me it’s “cleaner”. Never got it to do what it says on the tin, and never hit a situation that I couldn’t solve using more straightforward tools like merge.
What’s your mental model for a Git commit, and a Git branch?
Once I properly learned those two concepts, understanding rebases became a lot easier.
I’ll try to explain it to the best of my abilities.
Think of a commit being a patch - a description of how to take a particular file from one state to another
A branch is a list of patches to be applied in order, from the point where the branch was created until the last commit on the branch
When you rebase a particular branch, what you’re essentially doing is taking all of the commits that are currently on your branch, checking out the other branch, and then applying each of the patches in order on that new branch.
A rebase can be cleanly applied if the premise for each commit has not changed when applied, but if the premise has changed, you get a conflict to be resolved before being able to continue the rebase.
I mentally model a rebase a bit as a fast version of how it would look like to build the branch I was on, but on top of the branch I’m rebasing on.
That’s a good explanation of what it’s supposed to do. That was how I understood it as well.
But anytime I’ve tried it, I’ve ended up with conflicts where there shouldn’t be (like, I already solved that conflict when I merged earlier) and/or completely undesirable results in the end (for instance, some of my changes are just NOT in the result).
So I just gave up on the whole feature. Simpler to just merge the source branch into mine.
Depending on how structured your commits have been, it can either be very difficult to get a rebase through or a complete breeze. There are some features to make it easier - rerere being the main one I’m thinking about.
If you ever find yourself in a situation where rebase or a force push seems to be the solution, take a step back, clone your repo in a new directory and copy the changes into you’re new checkout - ‘cause you gon’ and screwed somethin’ up, son.
Hmm, I’m less afraid of force push. It does what it says on the tin. If I pushed a fuck-uo to remote and a reset is the simplest way out, you can bet I’m force-pushing that reset.
I’m the opposite. I just let git take care of the stupid content. Why mess with the commit graph? Merging locally (instead of squashing) works better with merge requests because the graph clearly shows what changes went where.
I do some branch maintenance on my local branch (rebasing) until there are conflicts, but other than that I don’t see any benefit for messing with commit history.
Force pushing is necessary when using rebases, and rebases are an essential tool, so you should not be afraid to force push under normal circumstances.
A few days ago I had to gently explain to someone why their rebase-and-force-push strategy not only prevented the use of “review latest” feature on GitHub, but was also pointless because all PRs are squash committed to main.
They didn’t get it and now they seem a little mad at me.
I’m guessing this is in reference to a scenario where a review of the PR has already been performed, and the rebase+force push is made to introduce new changes to the PR, possibly to address PR feedback.
I agree that these changes should be made in separate commits, for the benefit of the reviewer.
There are other scenarios where rebases are appropriate though, such as getting potentially incompatible changes from the main branch into the PR, and here I believe a rebase+force push is the right tool for the job.
Oh there’s totally a time and place for rebase strategies, this just wasn’t one of them.
Git’s biggest problems come from
people taking ritualistic views on what is “right” instead of thinking about which strategies work best for the situation, project, and team.
Even if you rebase you can still recover the original commits until they are garbage collected. You are generally safe as long as the .git directory isn’t deleted, in which case your whole history is gone anyway.
As long as you never touch the rebase button, you’ll be fine. Probably.
Don’t be afraid of rebases, they are an essential tool in Git.
This particular fear can only be addressed by understanding.
I don’t understand it. Every time I see something about a rebase it’s some purist telling me it’s “cleaner”. Never got it to do what it says on the tin, and never hit a situation that I couldn’t solve using more straightforward tools like merge.
What’s your mental model for a Git commit, and a Git branch?
Once I properly learned those two concepts, understanding rebases became a lot easier.
I’ll try to explain it to the best of my abilities.
When you rebase a particular branch, what you’re essentially doing is taking all of the commits that are currently on your branch, checking out the other branch, and then applying each of the patches in order on that new branch.
A rebase can be cleanly applied if the premise for each commit has not changed when applied, but if the premise has changed, you get a conflict to be resolved before being able to continue the rebase.
I mentally model a rebase a bit as a fast version of how it would look like to build the branch I was on, but on top of the branch I’m rebasing on.
That’s a good explanation of what it’s supposed to do. That was how I understood it as well.
But anytime I’ve tried it, I’ve ended up with conflicts where there shouldn’t be (like, I already solved that conflict when I merged earlier) and/or completely undesirable results in the end (for instance, some of my changes are just NOT in the result).
So I just gave up on the whole feature. Simpler to just merge the source branch into mine.
Depending on how structured your commits have been, it can either be very difficult to get a rebase through or a complete breeze. There are some features to make it easier -
rerere
being the main one I’m thinking about.Is that what interactive rebase tools use?
I don’t do CLI git
You enable it using
git config
, after that it will apply to whatever frontend you’re using.… and force push.
If you ever find yourself in a situation where rebase or a force push seems to be the solution, take a step back, clone your repo in a new directory and copy the changes into you’re new checkout - ‘cause you gon’ and screwed somethin’ up, son.
Hmm, I’m less afraid of force push. It does what it says on the tin. If I pushed a fuck-uo to remote and a reset is the simplest way out, you can bet I’m force-pushing that reset.
I rebase and force push daily. I like squashing all my commits, and our main branch moves quickly so I rebase off that often. Zero issues for me.
Yeah, I hate it when my repo is a chain of merge commits. I want to see actual changes to the code, not branch management history.
I’m the opposite. I just let git take care of the stupid content. Why mess with the commit graph? Merging locally (instead of squashing) works better with merge requests because the graph clearly shows what changes went where.
I do some branch maintenance on my local branch (rebasing) until there are conflicts, but other than that I don’t see any benefit for messing with commit history.
I rebase and force push PR branches all the time. Master is moving quicker than my PR.
Yeah, our whole workflow is based on rebasing our feature branches on develop. Makes for a clean git log. :)
Don’t be afraid of
git reset --hard
if you rebased with the button on GitHub/gitlab, though. :DForce pushing is necessary when using rebases, and rebases are an essential tool, so you should not be afraid to force push under normal circumstances.
A few days ago I had to gently explain to someone why their rebase-and-force-push strategy not only prevented the use of “review latest” feature on GitHub, but was also pointless because all PRs are squash committed to main.
They didn’t get it and now they seem a little mad at me.
I’m guessing this is in reference to a scenario where a review of the PR has already been performed, and the rebase+force push is made to introduce new changes to the PR, possibly to address PR feedback.
I agree that these changes should be made in separate commits, for the benefit of the reviewer.
There are other scenarios where rebases are appropriate though, such as getting potentially incompatible changes from the main branch into the PR, and here I believe a rebase+force push is the right tool for the job.
Oh there’s totally a time and place for rebase strategies, this just wasn’t one of them.
Git’s biggest problems come from
people taking ritualistic views on what is “right” instead of thinking about which strategies work best for the situation, project, and team.
Even if you rebase you can still recover the original commits until they are garbage collected. You are generally safe as long as the
.git
directory isn’t deleted, in which case your whole history is gone anyway.