Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

rebase : centralized repo :: merge : decentralized repo

rebase : linked-list :: merge : DAG

If the work/repo is truly distributed and there isn't a single permanently-authoritative repo, a "clean, linear" history is nonsensical to even try to reason about.

In all cases it is a crutch: useful (and nice, and sufficient!) in simple settings, but restricting/misleading in more complex ones (to the point of causing many developers to not see the negative space).

You can get very far thinking of a project as a linked list, but there is a lot to be gained from being able to work effectively with DAGs when a more complex model would better fit the reality being modeled.

It's harder to grok the DAG world because the tooling is less mature, the abstractions are more complex (and powerful!), and almost all the time and money up to now has explored the hub-and-spoke model.

In many areas of technology, however, better tooling and socialization around moving from linked-lists (and even trees) to DAGs is going to unlock more advanced capabilities.

Final point: rebasing is just glorified cherry-picking. Cherry-picking definitely also has a role in a merge-focused/less-centralized world, but merges add something totally new on top of cherry-picking, which rebase does not.



sort by: page size:

Thanks for taking time on such detailed explanation! So, the benefit of rebase is in a graph view of the repo, not in a conflict resolving workflow (which is consistent with the manual). But why

merge-based ... rapidly turns into spaghetti with even just a few people working in the repo

Isn’t it just a detail of how graph/report tools work? Can’t they track these merge points and “rebase in their ram”? I don’t get how a graphical representation of merge points may change the workflow.

One more thing that is unclear is why some people think that rebase is somehow superior in terms if conflict and reintegration. Like they “had issues with svn and now that rebase is a thing, issues gone”. Maybe they didn’t understand that you have to sync-merge your branches (effectively rebasing) periodically to not diverge from trunk (or parent branch) too much?

Added: I know rebase is not congruent with what I’m asking, but my questions are more about how git folks think, not about how git works. Cause I often see its comparison to other VCSs and claims that are vaguely or simply untrue about git competitors. As if before git there was some stoneage.


Yes... it is, until you realize it's a command line manipulation of a data structure.

Rebase, branching, diff, cherry pick, merging is just manipulating a DAG.

When you're on your own branch it's often easier to think of it as a linked list.


I can't comment on the motivations of the maintainers, but in my experience normal merges can handle more conflicts cases smoothly than rebase. Rebase is also controversial because technically it's rewriting history. I think for the special case of pulling from remote, though, that the tradeoffs are often worth it, but nevertheless, merge is the safer default.

Rewriting history with rebase is a destructive operation and I would never advocate for it to juniors. Merges are much more straightforward because they follow the git mental model of acyclical directed graph.

I don't get why people like rebasing as an alternative to merging. It works kind of OK for small histories, but if you do something slightly complex or your history is not meticulous, rebasing becomes extremly tedious. The worse example is a conflict in a reverted commit. A merge will flatten the diff and skip the reverted commit entirely, while a rebase will require you to fix the conflict twice. And while a merge is tedious to revert, it is possible. Good luck saving a branch ravaged by a bad rebase.

Regarding rebasing, the first commenter at the bottom of the linked article mentioned he prefers rebasing to merging, and referenced a blog post of his explaining why:

http://darwinweb.net/articles/the-case-for-git-rebase

Worth reposting here in case anyone missed.


A point I've tried to make is that we don't need a "happy medium", we can keep the mess that the sausage was made from and still get the sausage final product.

We have the power of a DAG to both record and hide all the mess. I can take my messiest repository and with a couple DAG traversal options still get that clean "story" back out of it. On the flipside with rebase you are absolutely erasing history and there is no way to dig deeper into any information lost or discarded in that rebase. I can give you what you want to see from my repositories, but you can't give me what I sometimes want to see from yours.

Merge commits are a great place to tell the story of "the whole change I intended to make". A good PR system even encourages and automates exactly that. (It also makes it easier to review the branch as a whole, or incrementally, or what have you in between to suit your needs/interests.)

I don't outlaw rebasing locally. There are absolutely cases in which a local rebase is necessary, and if a developer feels comfortable with rebasing I'm not going to stop them from doing it in a branch they control.

But I also don't encourage rebasing. I'd rather see how the sausage was made, ugly as it was, as it does tell a story even if you may not find it an "interesting" story, and sometimes in code archaeology or debugging nightmares you do need to dive into tiny incremental trivia.


My only beef with rebasing is that it seems to fail much more often, whereas merges will usually do the right thing. I realize this is git-specific, but rebases have still given me much more trouble than merges.

Merging and rebasing both have their benefits and use cases. Just do not fall for the "squash everything into one commit and rebase" BS recently afflicting otherwise rational people.

I'm the guy who started this DAG model (also at Sun with NSElite and then later with BitKeeper).

I agree that rebase == centralized. It's a math thing. If you rebase and someone has a clone of your work prior to the rebase chaos happens when they come together. So you have to enforce a centralized flow to make it work in all cases. It's pretty much provable as in a math proof.


That's an unfortunate generalization. You can rebase all you want as long as you didn't make your private branch public. (and even then some communication with the other people makes it pullable: tell them to first git reset --hard xxxxx)

We use this more othen then not here, and never have problems. It's a great way to work on a dedicated feature while still getting features from others, yet doesn't suffer from sometimes hard to read history. Does this mean rebase is king and merge isn't? No. Is it the other way around then? Also no. Both are fine if you know how to use them.


Wouldn’t you have the same amount of merge conflicts with rebase? Especially if you don’t do it often, which you frankly also should with merge?

I have to admit that I never really understood the advantages of rebase, and what I mean by this is they I actually don’t understand how the dangers of rebase out-weighs any form of advantages. Especially because on of the major advantages of merge is that you can squash your local commit history when you submit it to your main branch.

What we do is that we tie every pull request to a relatively small feature task, and because we do this, we genuinely don’t care about the individual commits developers do. Which means they can commit really silly messages if they are heading to a meeting or if they are just tired at the end of the day. It also helps with them merging main into their branch often, because it doesn’t taint the history.

The biggest advantage we’ve seen, that maybe we didn’t expect, is that nobody ever fucks up our tree in a way that needs someone who actually understands git to solve. We’ve also locked down the use of force push so that is not available to anyone unless it’s absolutely needed. Part of the reason I set this up initially was to protect myself from me, but it’s been a good thing since.

But I’m actually curious if it’s wrong.


I tend to rebase branches rather than merge. Anyone have any thoughts on this?

FWIW, I was mainly referring to making local branches presentable and/or just organizing things, not to rebase as a merge strategy. Don’t assume that rebase always means moving the local branch to the head of main, and don’t assume that rebase and merge are interchangeable. There are a lot of ways to rebase.

Exactly my point. How do you reconcile the idea of rebase "should not be" used vs "a merge should only occur to merge a finalized branch in".

I'm on your side. My objection was to the latter statement, not the former. The basis of my objection to the former was (in part) because of the problems with rebasing when a branch is distributed. The idea that the only merges that occur are merges of finalized branches seemed very naive to me.


Rebasing and cherry-picking are awesome tools once you know how what they're actually doing. I think people avoid rebase for a few reasons; the term "rebase" doesn't mean anything outside of Git so it's not obvious what it is doing under the hood, and inexperienced Git users might use it to change the history on the main branch, which I see as an antipattern.

There's nothing inherently wrong with merging, but I personally don't like it because I find merge commits harder to understand than regular commits. Better to use things like rebasing and cherry-picking to move commits arbitrarily and then squash some commits into units of work that make sense.

Stash is crappy though, IMO, because it's not branch-specific. Instead of stash, I like to fork the branch I'm working on and create a "WIP" commit. That way I don't lose track of work I had in progress that only belongs in a certain branch.


I’ve used git successfully professionally for almost 10 years and I’m not lying when I say I’ve used rebase about 5 times. We just merge. We squash sometimes. I think it must be because I’ve always worked in smaller orgs but rebase just seems to always be over complicating something simple (a merge). I get that there’s a benefit of a cleaner history but to me the benefit of simplicity merge offers makes it superior

`rebase` is simpler than `merge` in larger teams/projects, as the history will be much cleaner.

I've found that when teaching people Git, the most important thing is that they understand the state of their DAG, since that is at the core of everything we do in Git. A confusing DAG full of unnecessary merge commits is much worse for a beginner than exposing them to rebase.

Git lends itself as a development tool as well as a version tracker, and rebase is an important part of that for both beginners and experts.

next

Legal | privacy