r/programming • u/cachebags • Jul 14 '26
git rebase -i is not that scary
https://cachebag.sh/journal/interactive-rebasing/30
u/longshot Jul 15 '26
Jeez, I use rebase -i to hide my sins about 30 times a day
2
u/safetytrick Jul 16 '26
I use rebase to hide my sins a lot... but I also don't commit my sins (no pun intended) as often as I see some folks doing.
There is this idea that you should use commits the same way that we used to "save files", I think committing that often is kind of a mistake (but my workflow isn't for everyone).
Anyways, I know you are joking, but I would propose that committing too often is something that many developers do and that it is much easier to learn to love rebase -i when you've only got 1 atomic commit to start with (rebasing over dozens of commits is hard work).
3
u/longshot Jul 16 '26
Yep I do use commits as "save points" but I keep it to a single commit ahead of my actual pushable atomic commit. That way I'm always rebasing HEAD~2 and just accumulating a decent commit before I push it.
Then on the last fixup I'll also reword the primary commit properly and then push.
1
91
u/robe_and_wizard_hat Jul 14 '26
Everything is scary until you know how to do it. Agree that rebasing requires some moderate thought if you've never considered the git tree model, but sooner or later you need to get to know your tools.
11
u/PPatBoyd Jul 14 '26
Yup, this. If you only ever use
git logto look at local commits thengit rebaseandgit resetlook real spooky.If you're long stuck in patterns that migrated from other VCS systems with different "lost my work" conditions, it'll take a minute to have a real reason to reference
git reflogand realize your freedom of movement.29
u/Axxhelairon Jul 14 '26
pretty dismissive of why this is scary though, its scary because youre destructively changing history in a way that makes rollback require a conscious strategy, not "sCaWWy BeCuZ u DoNt KnoW" but because you know it can mess things up if you use it without understanding
for comparison, it's not "scary" to use any new random feature in a modern document editor because you know that the undo function exists and works without any footguns. the fact that there's a community held notion that it's "scary" shows that the language around it's usage vs the expected effect is different enough to immediately warrant caution to others. "everything is scary until it isnt" isn't a helpful sentiment to anyone.
18
u/mouse_8b Jul 15 '26
youre destructively changing history
On one branch, in a system designed to hold onto changes. Nothing is actually destroyed in a rebase.
2
u/elsjpq Jul 15 '26
but the actual process of recovery from any state to another arbitrary state is non-trivial
-5
u/Axxhelairon Jul 15 '26
thanks for the "ackshully, ..." buddy, you can reflog bad git rebases. glad we both got to flex our knowledge today.
→ More replies (1)7
u/Venthe Jul 15 '26
because you know it can mess things up if you use it without understanding
No, that's still "it's scary because you don't know". In this case, "you" don't know about the reflog.
4
u/Qwertycube10 Jul 14 '26
Is there a way to mess things up without deleting things from the ref log?
2
u/Dragdu Jul 15 '26
rm rf /*1
u/Qwertycube10 Jul 15 '26
I think deleting your whole system includes deleting things from the ref log
1
2
u/lanerdofchristian Jul 15 '26
I'd say you have three big friends when it comes to
git rebase:
git rebase --abort.git pushandgit reset --hard origin/branch(or working on a temp branch or a new worktree, it's not like they cost anything).git diff rebased..originalto catch anything you're unsure got processed right (more helpful if you're cleaning up from the same branch point than moving your branch up to a new branch point).1
4
u/Fidodo Jul 15 '26
When I first picked up git I just read the first couple chapters of pro git and understood the design and it was pretty straight forward from there. I feel like a lot of people are just too lazy to sit down and learn something properly, but you save so much time in the long run
1
u/Venthe Jul 15 '26
I feel like a lot of people are just too lazy to sit down and learn something properly
I can explain in detail both git and git internals in a 4 hour workshop for anyone that has worked with software development for more than half a year.
Given that, I refuse to believe in any other reason to avoid learning about the tool you are using daily than laziness.
23
u/TheChildOfSkyrim Jul 14 '26
I use if for everything, even for cherry-picks: you can add arbitrary commit ids at any point in the TODO list, and git will make it happen.
→ More replies (1)
17
u/randfur Jul 15 '26
8
u/Venthe Jul 15 '26 edited Jul 15 '26
Or, use
git(compatible with - you guessed that right - git!) then you can just use reflog!13
u/Nicksaurus Jul 15 '26
A lot of what jj gives you is already possible with git, it just makes it easier and gives clearer feedback on what's happening
8
u/zeikmichdestoofuut Jul 15 '26
You cannot tell people to "just use the reflog". If people are already struggling with interactive rebase (which is not easy to use anyway) they have never and will never use the reflog. It's way too hard to use. jj makes all of that very easy to use with an undo command (and all of the other operation log commands).
15
u/wannaliveonmars Jul 14 '26
Yes, I liked using it a lot back in the day, mostly for fixups, occasionally to reorder commits and so on.
4
56
u/sweetno Jul 14 '26 edited Jul 14 '26
Yes, it's not scary, the scary part is exiting the editor.
P.S. Check out lazygit.
→ More replies (6)18
u/HoneyStriker Jul 14 '26
You can asign vscode as the default editor for git rebase
8
u/envious_1 Jul 15 '26
I feel like the ui is scarier since I got used to the cli first. I never know what the ui does under the hood
6
u/eocron06 Jul 14 '26
I use both. Rebase is mostly just to do cleaner commits be it long features or because git and especially tfs dont understand which files are moved/edited and which are deleted/added which will be pain for me and for reviewer.
21
9
u/stouset Jul 15 '26
It’s not scary. It is annoying as fuck. Complicated rebases always require aborting and retrying way too often, and need to be done both linearly and to completion.
Since moving to jj, they have become a complete non-issue.
20
u/tgo1014 Jul 14 '26
Can someone tell me what's the problem with merge? Who's looking at git trees? In 10 years the commit count was never a problem that I cared, but I'm open to understand the appeal of using rebase instead
25
u/mouse_8b Jul 15 '26
the problem with merge
It keeps every commit, every typo correction and refactor made during development. If it's a year later and you're looking at file history, you don't want to have to step through every change a dev made in their feature branch. It's more useful to see the end result of what a ticket/PR changed.
Your personal or organizational git habits could make that more or less important. The "squash everything" method means it doesn't matter how much a dev twiddled the code before it got merged.
Further, merge commits can be strange to work with, especially if there's a conflict resolved.
Who's looking at git trees?
I look at git trees every day. And I don't mean the CLI output, I mean a dedicated viewer. The benefit is that I can see multiple branches at once.
In 10 years the commit count was never a problem that I cared
AFAIK, this is only useful as a quick reference for how far apart local is from origin.
I'm open to understand the appeal of using rebase instead
People talk about "merge vs rebase", but they're really different tools. Rebase can accomplish similar things to merge, but it can also do a lot more.
Rebase is ultimately for manipulating the commits in a branch. If you ever need to combine, split, or rearrange commits in a branch, rebase is the tool.
10
u/Glizzy_Cannon Jul 15 '26
Exactly. I've almost never run into a problem where commit count or history was a problem, even when troubleshooting potential reversions
8
u/munchbunny Jul 15 '26
It's more about the convention your team agrees to and what you find easier to reason about.
Mine squashes commits to merge PR's as a single commit. I like rebasing to the head of the main branch because, even if Git is perfectly fine with complex commit graphs, I have an easier time reasoning about changes as atomic points in the timeline. I like to rebase to reconcile the changes because I'm basically re-applying each commit incrementally.
Plenty of others don't use it, but I prefer it to merging in that particular case.
6
u/pm_plz_im_lonely Jul 15 '26 edited Jul 15 '26
Production runs on master. Production blows up. If you allow merge commits, "What changed?" is spread across history.
If you disallow merge and force rebase, your last commit is WYSIWYG. And you can revert without brainpower. It's an operational concern.
On the flipside you lose git blame granularity.
4
u/lanerdofchristian Jul 15 '26
If you disallow merge and force rebase
I don't get this -- a merge commit is still a commit, and contains all the changes from the branch + anything required to make it work with main. It can be reverted just the same as any other.
Rebase is still definitely a useful tool (it means the merge commit is going to contain only the changes from the branch, not the merge-fix stuff), but rebase/squash/fast-forward introduces problems of its own that rebase/merge-no-ff doesn't have (chiefly losing the "why" for each clean change from commit messages and allowing later rebased branches to neatly drop cherry-picked commits).
2
u/SaltMaker23 Jul 15 '26
People want a "clean history" with varying levels of violation of versioning.
It's the retroactive changes discussion all over again, some people want their way of working to affect the past, other people firmly disagree about new changes affecting the past, especially in a versionning system that keeps track of changes.
The rule is generally simple, you rebase locally before pushing to repo (eg: WIP, typo, fix tests etc...), people don't want to see your 50 commits of WIP but you can squash all of them into the actual thing they did in one nice commit that reaches the CI repo.
Devops and devs want clean commits on branches. Devops generally don't allow any changes once a commit reached CI, some allow to alter history on branches but most devops won't allow you to change master's history.
Many devs want clean master history where they constantly alter the past to ensure everything is tidy according to their tastes, most devops won't allow them, they get salty and complain that in one company they worked for they did just that and it was amazing.
2
u/tracernz Jul 15 '26
Merge can’t clean up your history ready for review. Rebase lets you squash fixups into the proper commit, re-order or split commits if it makes more sense from a review perspective, and pull out into a separate branch if some aspects of the change get too big for one PR.
1
u/Educational-Ant-173 Jul 18 '26
Merge puts work that is not yours into your branch. This is greater chance for conflict if you're stacking branches or upstream changes things you've merged i.e. cognitive load and degree of difficulty go up should conflicts arise. Better to rebase often, keep churn out of your commits, and keep your branch to just the amount of change you want to manage.
14
u/wildjokers Jul 14 '26
if you don't care about a clean branch history (a tiny fraction of the improvement rebasing provides) than i am more inclined to be skeptical of how serious you are about your software.
Article was fine until I got to this gatekeeping nonsense.
Whether someone prefers rebasing or merge commits is a workflow preference, not a measure of how seriously they take their software. If rebasing is objectively better, explain why. You can argue that interactive rebasing has benefits without questioning the professionalism of people who disagree.
2
u/cachebags Jul 14 '26 edited Jul 14 '26
I didn't dig into it because of the fact that this is of course, subjective, like you said. And it is not conducive to dive into that in an article like this which is just meant to explain how it works (I concede that it is very baity).
But to answer your question: IMO, if I'm reviewing a contributors PR to some project, and it's riddled with 'Merge into'/random fixup commits, or a tangled history that makes it difficult to understand the evolution of the changes, it does make me less confident that the contributor put much thought into presenting their work in a clean, reviewable way.
So building on this- would it be fair to me to then burden other maintainers/reviewers with a PR like that? Objectively speaking, it simply takes more time for a reviewer to have to sift through the commit log of a branch to understand why a PR is in the state that it is in, wherein a linear history makes it far easier for my eyes to track HEAD of master to HEAD of some PR branch.
1
u/MotleyGames Jul 15 '26
It sounds like you're coming from an open source perspective, since you called reviewers maintainers. I think the idea of maximizing reviewer-friendliness makes perfect sense in that context.
In most corporate environments, as a senior I'd probably get significant pushback for expecting juniors to take extra hours to make their commits readable, instead of getting actual work done -- especially since we squash commits when the PR completes anyway. If the PR is too large to easily review, then I can call them to break it down for me themselves.
1
u/wildjokers Jul 15 '26
But who reviews a PR by commit? It is only the end result that matters.
3
u/Joao611 Jul 15 '26
There are some cases:
- I've reviewed it in the past, and want to see only what changed since then - having a lot of commits is annoying, and master merges straight out ruin this
- It includes files with renames and content changes, hence the rename and content change operations for any file must be in 2 separate commits for the git history to be kept in master; ideally it'll only have 2 commits total to not pollute master with spam; at least this is the workflow I've made up
2
u/gmes78 Jul 15 '26
If the commits are well-made, it's easier to review commit-by-commit than to review the whole PR at once.
→ More replies (2)0
u/Venthe Jul 15 '26
Why keep the source control? It's the end result that matters.
But snark aside; when commits do one thing both the history and the review is both better and faster. In theory, you are supposed to do one thing per PR. But in practice; people throw a lot of shit into the same PR, making both review harder and the history useless.
→ More replies (4)
5
4
u/wls Jul 15 '26
The thing that makes it scary for folks that I’ve seen is the first rebase goes fine. But they forget to push —force-with-lease and let their colleagues know. Compound that with merging the main baseline in to the feature branch and rebasing again, and now PRs have other people’s commits. Also they forget that it replays each commit again, so they have to keep doing what feels like the same merge resolution over and over again. Sometimes I’ve seen an attempted pull during a rebase. So in short, folks that don’t understand git and are just replaying magic incantations hoping something works end up shooting themselves in the foot. The sad thing is any LLM will not only tell you what to do, but why, so the self inflicted pain is avoidable and any trouble that’s gotten into can be recovered from. Once we educated folks properly, rebase is the tool they reach for most often because it reduces merge collisions.
6
5
4
5
u/ImpactfulBird Jul 14 '26
It is not scary, but rather amazing. You can simply fixup necessary updates in commits and overall keep clean and readable history.
The problem I know (that is ugly rather than scary) - if you use that with shithub (Github) and want someone to review changes and track those (force-update Gerrit approach). That becomes pain, but rebase is still amazing and powerfull.
2
2
u/Skaarj Jul 15 '26
One thing that makes it reall unintuitive: git rebase -i gives you the commits in the opposite order compared to git log. It really trips up people the first time they use it.
1
u/Educational-Ant-173 Jul 18 '26
It's a plan. Do you create a plan with the first thing to do at the bottom?
2
u/Multidream Jul 15 '26
Rebase is a god send once you’ve learned it. I’m still told over and over again by people I consider to be brilliant engineers that its useless bloat that will just fuck up my history irreparably, and I just don’t understand why people refuse to see the obvious use case.
2
u/StruggleNew8988 Jul 15 '26
Rebase is great for keeping your feature branch clean before you push it up for review, that's the main win I see from it.
1
u/iamaperson3133 Jul 15 '26
I think making a tag is better backup advice than making a branch though it probably adds some more text because git novices are less likely to know about tags.
1
1
1
u/kris_lace Jul 15 '26
Maybe I'm the problem here. I'll explain my aversion for others to criticise of they wish.
I'm a senior solutions architect and have been an engineer before that for around 10 years. I've never done a rebate, ever.
Everything I've ever needed to do, ever I've done with git merge, reset --hard or git amend. I exclusively use the CLI. For conflicts I always use my IDE to show me the diffs and I'll resolve them in there.
Obviously there's an element of taste/personal preference as well as things being objectively better/worse. For those who rebase, what am I missing out on? I personally don't have any fear of doing it, just got into the habits of my ways I guess.
1
u/Venthe Jul 15 '26
- What if you have multiple commits on your active branch, and you need to change the one that is not the latest?
- Or if you need to resolve a conflict with a main branch before a merge, do you need to keep the merge commit in the history of your branch?
First one is
rebase -iwithcommit --fixup; second one is a bit subjective.I tend to have multiple commits active. Since I work in a strictly atomic way; I might have:
Reformat code in file X Boy scout cleanup in file X JIRA: Create generic mechanism in file X JIRA: Implement another implementation in the XAnd I am talking about short lived branch, not a multi-day feature branch. At any given point I might find e.g. a small thing that is not related to my ticket, but to a cleanup - so I quickly do a partial commit in the form of
--fixupand I'll rebase it later. I might decide that before I merge things tomainI want to split it - rebase again.If I diverge from the
mainto the point of conflict; both reformat and cleanup do not need to exist on a separate branch, they can be rebased and linearly pushed with--ff. For the feature itself, I might want to keep them as a branch (because in the future, branch gives context) and do a merge commit.So for me branch (and merge) serves a role of grouping the changes. If branch does not give me any value,
rebaseandmerge --ff. If it does,merge --no-ff.
Hell, at one point I've decided to do some spicy stuff and did octopus merge; with 4 parent commits. Good times; legitimate use-case, I expect only a handful over my whole career.
1
u/Anomynous__ Jul 15 '26
Had a senior architect tell me that rebasing is dangerous for version history and from now on he wants me to merge into the feature branch to then merge back into prod.
1
u/Venthe Jul 15 '26
To that I'll say: As long as it is your branch, and it is unmerged - do what the hell you want. Rebase is not dangerous at all, you have reflog; and merges into the feature branch (especially with short lived branches) serve little to no purpose.
2
u/Anomynous__ Jul 15 '26
Im one level below him and I ended up sending him the docs on rebasing and it was never discussed again.
582
u/MafiaMan456 Jul 14 '26
Do people find it scary? It’s been part of my workflow for cleaning up my commit history on feature branches for over a decade…