Hacker News new | past | comments | ask | show | jobs | submit login

A large number of Fossil positives are related to not having rebase. It feels like this is a huge concern for functionality that many people, do not use that often. The last time I used rebase at a job was maybe 5 years ago?

Other than that my bigger gripe is when I read something like this:

> Git strives to record what the development of a project should have looked like had there been no mistakes

Git does not strive to do this. It allows it, to some degree. This is not the same thing at all and is basically FUD. I would say the debate is ongoing as to the value of history rewriting. It's probably a tradeoff that some orgs are willing to leverage and Fossil is masking that they allow less flexibility in workflows as an obvious advantage, feels slimy.




Git gets its bias from the Linux kernel development.

When you're sharing your source changes with external people, who need to review your code, it just makes sense to present it in a clean, logical progression of changes. To wit, remove unnecessary noise like your development missteps.

And it's only in that context that the emphatic call for history rewriting is born. Meaning, you can use all the power of Git to record all your changes as you proceed through development, and then rebase them into something presentable for the greater world.


It's also useful in code reviews in general - I don't care about your development noise, and every single person in the future does not need to read it to understand the final result either. Rebases solve that: present a coherent story for easy understanding, rather than the messy reality.

When you're purely local, sure - do whatever the heck you want. Nobody cares. But messy merges are rough for collaboration, both present and future.

(rough, not fundamentally wrong, to be clear. It's just a friction tradeoff, dealing with human behavior has next to no absolutes)


My largest problem about rebasing a branch onto master as a single commit is that it becomes harder to do provenance.

When the tip of my branch gets built (1) and the merge target is not ahead (2) I can actually retag the output of the build of the branch as what is now on master.

When you do a squash, while the default commit message contains the SHA, it no longer carries a semantical meaning. It's just a string of text.


It feels like overindexing on git as a source of truth for the iterative development process itself is just bikeshedding. Do whatever you want to do locally, then squash your commits into a single unit change. Document that comprehensively in your commit message for that squashed change. If there was some profound learning that feels like it needs rebase history for, just explain it narratively.

Perhaps a more contentious take: rebasing doesn’t bring any real value. To the original comment above, I would say a significant percentage of teams never use rebase and drive business value just fine. I do not think there exists and evidence to suggest teams that use rebase over squash merging are in some way higher performing. Rebase is something that some people’s obsessiveness compels them to care abut because they can, and then retroactively justify their decisions by suggesting value that isn’t there.


> squash your commits into a single unit change.

Again, Git gets its bias from Linux kernel development. You can not present your entire work as a single unit change to sub-system maintainers for inclusion in the mainline. You can use the power of Git to present it in a digestible way that aids understanding, and allows piecemeal selection of acceptable bits, and rejection of others.

This is clearly not relevant to everyone, but to suggest there is no value at all, is laughable.


> You can not present your entire work as a single unit change to sub-system maintainers for inclusion in the mainline.

If we take away “this is how it’s historically done” or “because I know how these maintainers act and they would not accept it” - why not? From what principles is the Linux kernel special that standalone incremental units of change are inappropriate or undesirable?

> allows piecemeal selection of acceptable bits, and rejection of others

Sure, is a good thing, but doesn’t have much to do with git and can be done without rebasing.


> From what principles is the Linux kernel special that standalone incremental units of change are inappropriate or undesirable?

Human limitations. You are simply better able to digest small incremental changes, instead of one big blob. This is not controversial and i don't understand why you would even raise this as a point.

> Sure, is a good thing, but doesn’t have much to do with git and can be done without rebasing.

It does have something to do with Git. Git has tools to facilitate it. And that is the case because Git was born out of Linux kernel development where it was the norm, and necessary.

If you want to use another tool to achieve the same result, nobody is stopping you. Or if you don't want to do it at all, that's fine too. But the simple fact of the matter is, you must do it today if you want to participate in kernel development.


> Human limitations. You are simply better able to digest small incremental changes, instead of one big blob. This is not controversial and i don't understand why you would even raise this as a point.

Because I agree with you on your assessment of human limitations, and rebase doesn’t change this. If I need to merge 500 lines of code over 20 affected files, and none of that can be merged individually while retaining functionality, it doesn’t matter if I split that into 50 10-line commits if I need to merge in the monolith at once, which means understanding the set of changes as a monolith, regardless of git history.

If for some reason any of this can be merged in as standalone, you just do that instead. This is what I mean by bikeshedding. Rebase culture is purely preference. There is nothing it offers that is not solved equally as well by potentially less complicated alternatives. It’s not the wrong way to do things, it’s just not also objectively right, and creates more work than it claims to solve.


> it doesn’t matter if I split that into 50 10-line commits if I need to merge in the monolith at once

That is a misunderstanding of how to use this feature. It is not meant to break changes down into useless divisions. It is meant to allow the grouping of changes into logical units. Logical units that help human comprehension.

This is very important when communicating with people who have never seen your code before. It allows you to include a narrative description (commit message) with each logical group of changes that is directly connected to the source code implementation of just that descriptive piece. It also allows you to connect a chain of those logical units into a progression toward a greater, cohesive goal.

You may dismiss all this as irrelevant to your particular environment, and that is fine. But Git provides tools that are directed toward it, and they're quite powerful and useful for those who understand and use them correctly.


> to suggest there is no value at all, is laughable.

It can have no value at all to common workflows. Usually, this kind of singular change consideration is done at the PR level in another tool (github), which is divorced from git. Being able to present missteps/demonstrate specific commits where something didn't work (without another developer having to write the scenario) has utility that I have leveraged.


> Being able to present missteps/demonstrate specific commits where something didn't work (without another developer having to write the scenario) has utility that I have leveraged

Fortunately, you're able to include anything you think is relevant. If you think a change is worthy of inclusion, include it. But there are clearly things that are just silly mistakes that provide no such value, and cleaning those up as a courtesy for the person who has to review your code, just makes sense.


> But there are clearly things that are just silly mistakes that provide no such value, and cleaning those up as a courtesy for the person who has to review your code, just makes sense.

Maybe nobody cares about your missteps, true. What about less senior developers? Is there a learning opportunity both ways? Yes. The history pepper doesn't matter either way. There's a little value to think about that in the workflow I described, so we don't toss it (not that anyone can make you expose it).


> The history pepper doesn't matter either way.

Having a clean history, where every commit is capable of being compiled, is quite nice. This will keep your CI happy and allow you to more easily use git bisect to determine when a bug was introduced to the codebase.

> There's a little value to think about that in the workflow I described

Sure. Git is flexible and doesn't require you to follow the workflow for which it was originally designed.


> Perhaps a more contentious take: rebasing doesn’t bring any real value.

I strongly disagree. I rebase feature branches on a daily basis and it's a must-have feature for anyone who works on feature branches that you want to keep updated and mergeable as fast-forward merges and ideally peel off small commits in separate pull requests.

Here's a small example of a very mundane workflow. I was assigned an issue where I needed to enable a component in a legacy project. I cut the feature branch and started going the "lean on the compiler" approach to fix blockers. Each individual blocker I addressed I saved as a local commit. Throughout the process I spotted a couple of bugs in mainline, which I also saved as local commits. Finally I got a working local build, but team members already merged a few updates onto mainline that created conflicts. I rebased my feature branch onto mainline's HEAD and fixed the conflicts in each local commit. Time to post pull requests for the fixes. I noticed a few of them were related so it would be preferable they went in before everything else. I did an interactive rebase to reorder local commits to move these bugfix commits to the start of the local branch. I squashed them, cleaned them up, and posted a pull request. The pull request was merged into mainline and in the meantime other PRs went in as well. I rebase the remaining commits in the local branch. Followed the same process for another bug. Rinse and repeat. Finally all I had left was the fix for the original issue. I rebased the remaining commits onto mainline, cleaned them up, and posted a PR. Done.

One ticket, around 3 PRs, and almost a 1:1 ratio of rebase-to-PR.

And here you are, saying rebasing doesn't bring any real value.

I think those who complain about rebase are overrepresented by the subset of Git users who barely go beyond the very basic features of checking out branches, pulling changes, and committing stuff. They have no idea how and why other features work, so they complain about things they know nothing about. When pressed about basic usecases, they fall back to trying to fill in the holes in their reasoning by arguing that workflows should be different or that other features are similar, while completely ignoring that features like rebase do the job and do the job very well and very easily.


Regarding rebase, it's been my experience that among many developers rebase has a mythical status. You're "supposed to" rebase, but no one knows the benefit of doing so.

It's a big downside of git being treated like some magical difficult spell. Same with exiting Vim, people treat it as way harder than it really is.


I tend to agree. I haven't used Git in a large project, but...why would I want to rewrite history? The project is what it is. What happened, happened. If there are a couple of weird commits, who cares? At most, maybe edit the commit messages to explain.


Because when I am developing in my local repo I have a stream of commits that go “adding xyz because abc is being a pain”. They’re informational for me as I progress through iterating on a feature, but when I’m ready to merge I really don’t want that mess polluting the global commit history. I may also be working on multiple things in parallel and want to isolate them from each other, both to keep a cleaner history but also for code review purposes.

There’s plenty of reason to use rebase, but if you’re fine letting the occasional mess slip into the history then it’s fine to NOT use it as well.

The one universal case though. Rebase before you submit a patchset for review. I don’t want to fight through merge conflicts to review a change, make sure it’s applied to the current HEAD before you send it.


Rebasing to squash commits or even split commits up before/during making a PR makes sense to me and I do it all the time just to clean up my mess. The order of development and the state of the repo over time isn't faked, this is just labelling and granularity.

What doesn't make sense to me is rebasing instead of merging. If master has a lot of changes and you want to pick those up, you can merge in which case history reflects reality - each commit has an actual state of the repo that you had on your machine.

Or you can rebase, in which case all of the commits on your branch now contain code that no-one ever had on their machine, not tested, never run, maybe it doesn't compile, maybe it's nonsense.

Both result in the same diff from master so are equivalent for submitting a patchset.

It's really hard for me to see the value of trashing your history like that. People like linear history but history actually is not linear sometimes.


Lots of criss-cross merges make it really difficult to follow history, making it less useful.

Note that merge vs rebase a false dichotomy. After rebasing you still have to merge your branch anyway, either fast-forward or with an explicit merge commit.

In the end, it's about commutating your changes effectively. The less noise there is, the better you can communicate. That takes effort from both sides, but many persons put all the burden on the receiving side.


> After rebasing you still have to merge your branch anyway, either fast-forward or with an explicit merge commit

You can push directly to the target branch.

git push origin my-branch:master

If your branch is a direct continuation of master -- which is often the desired result of rebasing -- then no merge and no force-push are necessary.

(I'm not saying this is a good workflow, btw.)


Which is the equivalent of a fast-forward merge. Same result, different mechanism.


Usually it's if you committed something you shouldn't have.

You still have to change api keys if you ever pushed, because things like github store orphan commits, but if you have something you can't change in there or you catch it before you push, it will at least go away eventually.


There are a few legitimate cases where you want to rewrite history.

1. Assume you are a user who is cloning the master/main branch and building it. If that branch contains your development missteps, then you are in for a world of pain. We as users always assume that the master/main Head is always buildable (excluding inadvertent mistakes).

2. If you are sending the commits as patches, then it makes sense to include a complete feature in a single patch. It will otherwise be very hard for the reviewer to make sense of any patch.


> I tend to agree. I haven't used Git in a large project, but...why would I want to rewrite history?

There are plenty of reasons if you're doing non-trivial tasks on local branches within a team. I've mentioned a common usecases I have, which is to reorder commits I make in local branches to afterwards peel them off as stand-alone pull requests.


I like that git allows rebase, as long as it is only done in prs or local. Rebase in the sheets, merge in the streets.


Or, more conventionally put:

> The golden rule of git rebase is to never use it on public branches.

https://www.atlassian.com/git/tutorials/merging-vs-rebasing#...

If you're doing trunk based development, with continuous integration, then you're approximately always on a public branch, and rebasing is not very useful.


Forgive my dumb question, how do you avoid rebase (ex: when making PR)?


Generally you merge main into your branch to resolve the conflicts there, then push to make the PR. Sometimes it's easier to rebase, sometimes easier to merge your main. The frequency of one or the other being more useful/easier often influences the accepted workflow.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: