4 ms·
I have been contributing code for 10+ years, and I have worked on teams that did rebase and others that did not. Not once have a ever debugged a problem that b
by game_the0ry 9mo ago
I have been contributing code for 10+ years, and I have worked on teams that did rebase and others that did not.
Not once have a ever debugged a problem that benefited from rebase vs merge. Fundamentally, I do not debug off git history. Not once has git history helped debug outside of looking at the blame + offending PR and diff.
Can someone tell me when they were fixing a problem and they were glad that they rebased? Bc I can't.
- nicoburns 9mo agoThe main benefit I've found is when there is work happening concurrently in multiple feature branches at once (e.g. by different people). Rebase-merging greatly simplifies dealing with merge conflicts as you only have a simple diff against a single branch to deal with. The more work you have in progress at once the more important this becomes.
- skipkey 9mo agoI can give you an example of when I am glad I rebased. There have been many times I have been working on a feature that was going to take some time to finish. In that case my general workflow is to rebase against main every day or two. It lets me keep track of changes and handle conflicts early and makes the eventual merge much simpler. As for debugging I’ve never personally had to do this, but I imagine git bisect would probably work better with rebased, squashed commits.
- hnben 9mo ago> I can give you an example of when I am glad I rebased I think the question was about situations where you were glad to rebase, when you could have merged instead
- alemanek 9mo agoThey kind of spoke to it. Rebasing to bring in changes from main to a feature branch which is a bit longer running keeps all your changes together. All the commits for your feature get popped on top the commits you brought in from main. When you are putting together your PR you can more easily squash your commits together and fix up your commit history before putting it out for review. It is a preference thing for sure but I fall into the atomic, self contained, commits camp and rebase workflows make that much cleaner in my opinion. I have worked with both on large teams and I like rebase more but each have their own tradeoffs
- rendaw 9mo agoYou can bring in changes and address conflicts early with merge too, I believe that's GP's point.
- alemanek 9mo agoYes but specifically with a rebase merge the commits aren’t interleaved with the commits brought in from mainline like they are with a merge commit. EDIT: I may have read more into GPs post but on teams that I have been on that used merge commits we did this flow as well where we merged from main before a PR. Resolving conflicts in the feature branch. So that workflow isn’t unique to using rebase. But using rebase to do this lets you later more easily rewrite history to cleanup the commits for the feature development.
- cluckindan 9mo agoSo use --merges when browsing main.
- tsimionescu 9mo agoYou'll still get interleaved commits. If I work on a branch for a week, committing daily and merging daily from main, when I merge to main, git log will show one commit of mine, then 3 from someone else, then another of mine, etc. The real history of the main branch is that all my commits went in at the same time, after seven days, even if some of them were much older. Rebase tells the real story in this case, merge does not.
- cluckindan 9mo agogit log --oneline --graph --first-parent
- thousand_nights 9mo agoi don't think i have ever even looked at what order the commits are, i only care about the diff vs the target branch when reviewing especially since every developer has a different idea of what a commit should be, with there being no clear right answer
- cryptonector 9mo agoThat's hard to answer because I only rebase.
- bluGill 9mo agoI used hg (mercurial) before git. Every time I see someone make an argument like yours I think "only because git's merge/branch model is bad and so you need hacks to make it acceptable". Git won, which is why I've been using it for more than 10 years, but that doesn't mean it was ever best, it was just most popular and so the rest of the eco system makes it worth it accepting the flaws (code review tools and CI system both have much better git support - these are two critical things that if you use anything else will work against you).
- doctorpangloss 9mo agoNot only is git not the best, but one of the central value props of coding agents and chatbots used for programming is not having to use git in order to interact with free code.
- jason_s 9mo agoSigh. I will forever hate Atlassian for killing Bitbucket hg hosting. What code review tools do you prefer?
- BeetleB 9mo agoI do the same except with merge. I don't see how rebase makes it any better.
- gaoshan 9mo agoFWIW I have used git bisect with merged commits and it works just as well (unless the commit is enormous... nothing like settling on a sprawling 100 file change commit as the culprit... good argument for discrete commits, but then it wouldn't matter if it were rebased or merged)
- d_watt 9mo agoOnce we had a slowdown in our application that went unadressed for a couple of months. Using git bisect to binary search across a bunch of different commits and run a perf test, every commit being a "good" historical commit allowed that to be much easier, and I found the offending commit fast.
- game_the0ry 9mo agoOk, I see. This is a use case I did not think about. Worthy of a blog post, I think. Besides testing for a perf slow down, any other use cases for git bisect + rebase?
- OptionOfT 9mo agoIn fact, for searching how a file got to the state it is I prefer that when PRs are merged, they are merged and not rebased. I want the commit shas to be the same. Rebasing on main loses provenance. If you want a clean history doing it in the PR, before merging it. That way the PR is the single unit of work.
- game_the0ry 9mo ago> That way the PR is the single unit of work. Well if I have a diff of the PR with just the changes, then the PR is already a "unit of work," regardless of merge or rebase, right?
- yawaramin 9mo agoMerging a PR with rebase doesn't lose provenance. You can just keep all the commits in the PR branch. But even if you squash the branch into a single commit and merge (which these tools automate and many people do), it still doesn't lose provenance. The provenance is the PR itself. The PR is connected to a work item in the ticketing system. The git history preserves all the relevant info.
- noisem4ker 9mo agoThe provenance that is lost is the original base.
- yawaramin 9mo agoNo, the original base is in the commit history. It's just not relevant any more after rebase. It's like your individual keystrokes before a commit are not relevant any more after a commit. They're not lost provenance.
- dcre 9mo agoThis is the post that made jj click for me, and not coincidentally it is about a rebase operation that feels complicated in git but trivial in jj. https://lottia.net/notes/0013-git-jujutsu-miniature.html https://lottia.net/notes/0013-git-jujutsu-miniature.html
- any1 9mo ago> Fundamentally, I do not debug off git history. Are you saying that you've never used git bisect? If that's the case, I think you're missing out.
- yawaramin 9mo agoFrom what I can tell the vast majority of developers don't use git bisect and never will.
- appplication 9mo agoFWIW, having squashed merge commits also reduces the relevance of bisect. It can still be useful but it’s not necessarily as critical of a tool.
- cryptonector 9mo agoThis. This is why small commits are nice. If you do that you might as well rebase. If you squash you lose.
- PaulDavisThe1st 9mo agoGit bisect is a wonder, especially combined with its ability to potentially do the success/fail testing on its own (with the help of some command you provide). It is a tragedy that more people don't know about it.
- zbentley 9mo agoBisect is one of those things where if you're on a certain kind of project, it's really useful, and if you're not on that kind of project you never need it. If the contributor count is high enough (or you're otherwise in a role for which "contribution" is primarily adjusting others' code), or the behaviors that get reported in bugs are specific and testable, then bisect is invaluable. If you're in a project where buggy behavior wasn't introduced so much as grew (e.g. the behavior evolved A -> B -> C -> D -> E over time and a bug is reported due to undesirable interactions between released/valuable features in A, C, and E), then bisecting to find "when did this start" won't tell you that much useful. If you often have to write bespoke test scripts to run in bisect (e.g. because "test for presence of bug" is a process that involves restarting/orchestrating lots of services and/or debugging by interacting with a GUI), then you have to balance the time spent writing those with the time it'd take for you to figure out the causal commit by hand. If you're in a project where you're personally familiar with roughly what was released when, or where the release process/community is well-connected, it's often better to promote practices like "ask in Slack/the mailing list whether anyone has made changes to ___ recently, whoever pipes up will help you debug" rather than "everyone should be really good at bisect". Those aren't mutually exclusive, but they both do take work to install in a community and thus have an opportunity cost. This and many other perennial discussions about Git (including TFA) have a common cause: people assume that criticisms/recommendations for how to use Git as a release coordinator/member of a disconnected team of volunteers apply to people who use Git who are members of small, tightly-coupled teams of collaborators (e.g. working on closed-source software).
- nothrabannosir 9mo agoDebugging from git history is a separate question from merge vs rebase. Debugging from history can be done with non-rebased merges, with rebased merges, and with squashed commits, without any noticeable difference. Pass `--first-parent` to git-log and git-bisect in the first two cases and it's virtually identical. My preference for rebasing comes from delivering stacked PRs: when you're working on a chain of individually reviewable changes, every commit is a clean, atomic, deliverable patch. git-format-patch works well with this model. GitHub is a pain to use this way but you can do it with some extra scripts and setting a custom "base" branch. The reason in that scenario to prefer rebasing over "merging in master" is that every merge from master into the head of your stack is a stake in the ground: you can't push changes to parent commits anymore. But the whole point of stacked diffs is that I want to be able to identify different issues while I work, which belong to different changes. I want to clean things up as I go, without bothering reviewers with irrelevant changes. "Oh this README could use a rewrite; let me fix that and push it all the way up the chain into its own little commit," or "Actually now that I'm here, let me update dependencies and ensure we're on latest before I apply my changes". IME, an ideal PR is 90% refactors and "prefactors" which don't change semantics, all the way up to "implemented functionality behind a feature flag", and 10% actual changes which change the semantics. Having an editable history that you can "keep bringing with you" is indispensible. Debugging history isn't really related. Other than that this workflow allows you to create a history of very small, easily testable, easily reviewable, easily revertible commits, which makes debugging easier. But that's a downstream effect.
- DenisM 9mo agoIf you have not already, try Graphite. You will be delighted as it serves that exact purpose.
- nothrabannosir 9mo agoI use magit which afaik is still undefeated for this workflow. Particularly with this snippet to “pop down” individual ranges of changes from a commit: https://br0g.0brg.net/notes/2026-01-13T09:49:00-0500.html https://br0g.0brg.net/notes/2026-01-13T09:49:00-0500.html .
- __MatrixMan__ 9mo agoIf you haven't used git bisect to find a regression, you should try it. You can write a test (outside of source control) and run `git bisect good` on a good commit and `git bisect bad` on bad one and it'll do a binary search (it's up to you to rerun your test each time and tell git whether that's a good or a bad commit). Rather quickly, it'll point you to the commit that caused the regression. If you rebase, that commit will be part of a block of commits all from the same author, all correlated with the same feature (and likely in the same PR). Now you know who you need to talk to about it. If you merge, you can still start with the author of the commit that git bisect found, but it's more likely to be interleaved with nearby commits in such a way that when it was under development, it had a different predecessor. That's a recipe for bugs that get found later than they otherwise would've. If you're not using git history to debug, you're probably not really aware of which problems would've turned out differently if the history was handled differently. If you do, you'll catch cases where one author or another would've caught the bug before merging to main, had they bothered to rebase, but instead the bug was only visible after both authors thought they were done.
- PaulDavisThe1st 9mo ago> it's up to you to rerun your test each time and tell git whether that's a good or a bad commit not true. You can use git bisect run script-command arguments where script-command is a ... script that will test the result of the build.
- simonw 9mo agoDo you ever use git bisect? I like to keep a linear history mainly so I don't have to think very hard about tools like that.
- tcoff91 9mo ago--first-parent with bisect really helps when the history is messy.
- recursive 9mo agoI've used git bisect on a repo whose commit graph is at least 20-wide at some points. In the two cases I used it, it identified the individual commit. I didn't think very hard about it. It was the first time I used bisect. Maybe I got lucky.
- tsimionescu 9mo agoI have often been happy to have a clean linear history when asking myself things like "does build X.Y.Z include this buggy change I found in commit abcdefg?". With a history full of merges, where a commit from 1st of January might be merged only on the 20th of July, this gets MUCH harder to answer. This is especially true if you have multiple repos and builds from each one, such that you can't just checkout the commit for build X.Y.Z and easily check if the code contains that or not (you'd have to track through dependency builds, checkout those other dependencies, possibly repeat for multiple levels). If the date of a commit always reflects the date it made it into the common branch, a quick git log can tell you the basic info a lot of the time.
- deleted 9mo ago[deleted]
- languid-photic 9mo agoI manage a maintained fork and periodically rebase our changes on top of upstream. In this case, rebasing is nice because our changes stay in a contiguous block at the top (vs merging which would interleave them), so it's easy for me and others to see exactly where our fork diverges.
- friedbeef 9mo agoDoesn’t that mean you have to fix all the merge conflicts introduced by your commits on every rebase though?
- skribanto 9mo agorerere can help, but OP probably has their own workflow
- chuckadams 9mo agoGit has gotten pretty smart about that recently: once you resolve a conflict, if you get the same conflict again it automatically resolves it the same way. Works for both rebase and merge.
- deleted 9mo ago[deleted]
- froh 9mo agoif you don't have a merge from main into the branch further down, then git only bothers you about the most recently introduced conflicts conflicts --- the ones you'd have to resolve anyhow, and it remembers how you've resolved those.
- cryptonector 9mo agoYou'd have merge conflicts whether you merge or rebase.
- gwking 9mo agoThis may be outdated because git’s defaults have improved a lot over the years. When I first used git on a team was in 2011. As I recall, there were various commands like git log -p that would show nothing for a merge commit. So without extra knowledge of the git flags you would not find what you were looking for if it was in a side path of the merge history. This caused a lot of confusion at times. We switched to a rebase approach because linear history is easier for people to use. To answer your question directly, if somewhat glibly, I’m glad I rebased every time I go looking for something in the history because I don’t have to think about the history as a graph. It’s easier. More to your point, there are times when blame on a line does not show the culprit. If you move code, or do anything else to that line, then you have to keep searching. Sometimes it’s easier to look at the entire patch history of a file. If there is a way to repeatedly/recursively blame on a line, that’s cool and I’d love to know about it. I now manage two junior engineers and I insist that they squash and rebase their work. I’ve seen what happens if they don’t. The merges get tangled and crazy, they include stuff from other branches they didn’t mean to, etc. the squash/rebase flow has been a way to make them responsible for what they put into the history, in a way that is simple enough that they got up to speed and own it.
- rpcope1 9mo agoI have worked on several codebases where it was enforced that the commit be rebased off of whatever the main branch was, all units of work squashed to a single commit, and only "working" code be checked into the main branch. This gives you a really good linear history, and when you're disciplined about writing good final commit messages and tagging them to a ticket, it means bisecting to find challenging bugs later becomes tractable, as each commit nominally should work and should be ready to deploy for testing. I've personally solved a number of challenging regressions this way.
- drysine 9mo ago>each commit nominally should work Except it can be the result of 10 squashed commits.
- bastardoperator 9mo agoWhich is the entire point of it. Why should I look at ten commits when I can look at one and get the same exact data? Why should I pollute my production history for what a is likely a bunch of debugging commits? The branch is a scratchpad, you should feel empowered within your own branch, rebase allows you to be lazy in the development cycle while presenting a nice clean set of changes at the end of it.
- bonzini 9mo agoYou can split your work in multiple commits and at the same time drop/squash debugging or wip changes. The result allows you to go into much better detail than a PR description.
- shawndumas 9mo agoYes! When you are deep in the code, your brain operates in a non-linear way. You try a solution, it breaks a test. You patch the test. You realize the variable name is wrong. You fix a typo. Without Squash, the main branch history becomes a timeline of your mental struggle. With Squash, the main branch becomes a catalog of features delivered. No body needs to take a trip on the struggle bus with me...
- jefurii 9mo agoI use `git rebase` all the time, along with `git add -p`, `git diff` and other tools. It helps me to maintain logical commit history. - Reshuffle commits into a more logical order. - Edit commit subjects if I notice a mistake. - Squash (merge) commits. Often, for whatever reason pieces of a fix end up in separate commits and it's useful to collect and merge them. I'd like to make every commit perfect the first time but I haven't managed to do that yet. git-rebase really helps me clean things up before pushing or merging a branch.
- just6979 9mo agoI'd be willing to bet most devs do something like this, or wish they could be doing it, but don't know about rebase or are scared of it. However, that might be because they're only thinking about rebase as OP's article uses it: only as an alternative to merge for get changes from another branch. Interactive rebasing to write local history on your working branch is incredibly useful, but also doesn't have anything to do with the "rebase vs merge" conundrum, and as long as you're not pushing to a shared branch, it doesn't have much to do with "erasing other's history".* If you can look at a working branch (with more than a trivial addition or fix) and not feel the need to do a interactive rebase (once you know how) before making a PR, then you're either a magical 100x unicorn dev that makes every commit the perfect commit, or you cheated and made a new branch and cherry-pick-squashed your way to a clean history.
- e40 9mo agoThis "debate" is just insane. Any workflow that has a review process uses rebase. FULL STOP. If you don't have your code reviewed and you push code to a shared repo, fine, don't use rebase if you don't want to.
- xorcist 9mo agoWhat is the argument here? Does it still hold if you s/rebase/comments/g ? Of course a readable code history aids in debugging. Just as comments and indentation do. None of these are technically necessary, but still a good idea. Of course running the rebase command doesn't guarantee a readable commit history, but it's hard to craft commits without it. Each and every commit on linux-kernel has been rebased probably a dozen times.
- douglee650 9mo agoIsn't it more of a style decision where if your team rebases, and practices clean code discipline, and excellence is a habit rather than an enforcement — the signals visibly emit in `status`. Most committers don't really understand remotes, much less rebasing.
- mrkeen 9mo agoAny time I'm doing anything remotely to do with merging, I use 'git diff' or 'git difftool'. If I diff against master, I see changes in 300+ files, when I've only changed 5 (because other people have changed 300+ files.) > Fundamentally, I do not debug off git history. Neither. The usual argument I hear against rebase is that it destroys history. Since I don't debug off git history, I'm quite happy to destroy it, and get back to diffing my 5-file changes against (current) master.
- MrDarcy 9mo agoTwo very useful use cases for rebase: 1) rewrite history to organize the change list clearly. 2) stacked pull requests of arbitrary depth. You’ve never run a bisect to identify which commit introduced a specific behavior? This is when I’ve found it most useful. Having commits merged instead of squashed narrows down and highlights the root problem. It’s a rare enough situation I don’t push for merge commits over squashed rebases because it’s not worth it, but when I have had to bisect and the commits are merged instead of squashed it is very very useful. Those commit authors are who I noted as clear thinkers and have tracked over my career to great benefit.
- cryptonector 9mo agoWhenever I go spelunking in the history I always find clean, linear history, with small commits (where possible) to be much easier to understand and search than merges.
- mathis-l 9mo agoI’ve worked on a code base that was about 15 years old and had gone through many team changes. It was a tricky domain with lots of complicated business logic. When making changes to the code, the commit history was often the only way to figure out if certain behavior was intended and why it was implemented this way. Documentation about how the product should behave often lacked the level of detail. I was certainly always thankful when a dev that was long gone from the team had written commit messages that communicated the intent behind a change.
- lucasoshiro 9mo ago> Fundamentally, I do not debug off git history. I'm really sorry. Using bisect and log -S saved hours of code debugging
- tunesmith 9mo agoI love rebase locally, especially when I have a few non-urgent branches that sit around for a little while. I hate rebase after pushing. The rule of thumb that has worked for me is "don't rewrite someone else's history". Rewriting origin's history is not so bad, but if there's even a chance that a team member has pulled, or based work off your pushed branch (ugh), rebase is horrible.