I think I liked the Mercurial branching model better than git, due to the branches being a first class record of events. What I did not know is how common the git rebase/clean linear history would become or a desire to change history on merge.
Mercurial had bookmarks that were roughly the same as git branches.
The linear version numbers were quite useful to reason about and use in places that call for a "number" version number, and were useful relative to your "master" clone. That was not the primary way though, it had hashes like git too, that were the same from clone to clone.
The clean linear history thing is something I never really got, despite using git for 12 years now. I worked with some smart developers whose rule was "rebase if you want, but if too complicated, just merge", and it didn't hurt the delivery or maintainability of the code they wrote.
Yes - whenever I'm in a team and I hear someone who insists on a linear history, I always wonder why they have trouble with merge when lots of folks like me have no problem with it.
Finally, in one team, I more or less forced a senior engineer use merge (or rather, I was in control of the project and did not force other developers to use rebase). After a year, he admitted that he no longer really saw a benefit in rebase and switched to just using merges in his own projects. He also noticed fewer merge conflicts this way.
Rebase makes sense when you realize git doesn't have branches. Git has tags that move but no branches. That means when you merge you have no clue which branch was the mainline and which was the fork. This is a question I often ask 10 years after switching to git. Sadly git has better tooling so it is worth using despite the issues.
> That means when you merge you have no clue which branch was the mainline and which was the fork.
You mean - when looking at the history?
Incidentally, once you get used to jujutsu, you realize that the question is meaningless. A merge is simply the child of two nodes. It's a symmetric operation between the two branches. The thing that makes it "complicated" in git and traditional VCS's is the insistence in assigning a name to the resulting merge (so if you're merging into main, you want to call the new node "main"). Since jujutsu doesn't automatically carry the name forward, you see the "reality" of merge being a symmetric operation (i.e. you don't merge a branch "into" another branch - you are simply merging two branches).
That is exactly my point. I'm not merging two branches together. I'm merging two branches with very clear different meanings together. One of them is our main line, one of them is a feature branch. Everyone talks about all you should develop in main line, and I certainly encourage that. However, often that just isn't practical in a large project for various reasons. Some of them aren't even good reasons, but nonetheless that is the reality.
Agreed.
For a complicated long running feature branch I can see it. Instead of repeatedly merging the root in during development it can be cleaner. Tools aren’t always good at figuring out in a PR what was written and what was caused by those merges from root. And history looks better at the end.
For a short branch that can merge cleanly or perhaps very close to it, I’d kind of rather have the ‘true’ history. I don’t think it’s worth it.
I’ve never understood the “everything must be rebased before every merge” desire.
exactly the opposite:
"For a complicated long running feature branch" always simpler to repeatedly merge main into dev, easier conflicts solving etc
For simpler cases squash+rebase as default merge strategy trumps leaves a nice clean history.
It really depends on how often you use git bisect and blame. This varies greatly across projects.
That said, if/when stacked PRs become a first-class citizen in GitHub, more projects will see the benefit of this approach (though they'll probably mostly get there through squash-merges).
The branching model being keeping a record is fine, but needing to make up a name for your branch before committing (unless you like rewriting) was not awesome, and the names being a global namespace was unpleasant.
And then, when you pull someone else’s in-progress work to inspect it, you end up with their branches showing up with their names and you ended up with revisions 13564-13592 belonging to someone else and showing up in your history graph even when you continue on your own work at revisions 13563 and 13593. I ended up using temporary clones and strip a lot.
git branches, in contrast, are delightfully unobtrusive.
shame it took years to get bookmarks in.