Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

There are benefits to having branches be an inherent property of a commit as opposed to the Git model of a dynamic property of the graph.

Suppose I have a branch A with three commits, and then I make another branch B on top of that with another few commits. The Git model essentially says that B consists of all commits that are an ancestor of B that aren't the ancestor of any other branch. But now I go and rebase A somewhere else--and as a result, B suddenly grew several extra commits on its branch because those commits are no longer on branch A. If I want to rebase B on the new A, well, those duplicated commits will cause me some amount of pain, pain that would go away if only git could remember that some of those commits are really just the old version of A.



> If I want to rebase B on the new A, well, those duplicated commits will cause me some amount of pain

Not really. Git will recognize commits that produce an identical diff and skip them. Your only pain will be that for each skipped commit, you will see a notification line in the output of your `git rebase`:

    warning: skipped previously applied commit <hash>


If I had a nasty rebase of A, then git isn't smart enough to figure out that the new A' commits are similar enough to the old commits to know to skip the old-A commits.


> There are benefits to having branches be an inherent property of a commit

And drawbacks, naturally. Advanced branching/merging workflows become extremely painful if not impossible, which makes mercurial unusable as a "true" DVCS (where everyone maintains a fork of the code and people trade PRs/merges).


> Advanced branching/merging workflows become extremely painful if not impossible

That's really, really not true. First off, I used the word "inherent", which doesn't mean "immutable"; you can retain all the benefits of mutability if you so desire. Of course, Mercurial historically focused a lot heavier on immutable commits than Git did, but hg eventually found a different path that really makes using git feel antediluvian in comparison.

The second thing to note is that there's no requirement that the 'branch' property of a commit correspond to only one head. Actually, I don't think any of the mercurial repositories I've contributed to ever bothered with branches; there's just simply no need in mercurial to create multiple named branches, the way there is in git.

Finally, mercurial solves the workflow problem in another way, by essentially realizing that there is a dichotomy between public, immutable commits and work-in-progress draft commits. The problem with PRs is that you end up in a situation where you have the unenviable choice between making updates with 'address fixes' commits that pollute history or rebases that risk making comments go into the ether (especially on GitHub). You might have extra squashes or rebases that make PRs that depend on other PRs painful. Mercurial instead makes a rebase or other history edit simply mark the old commit as dead and link to the new version, so that any other commits that depend on it can know how to be updated to the new version. And this information is spread to anyone who pulls from your repo, but need not be retained when pushed to anyone who didn't know about the old dead versions!


Like what?

How does it differ from an extra line on each commit message saying the branch name, and some options to parse it if desired?

I definitely get annoyed sometimes when I have to put in extra effort to figure out which side of the tree is which.




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

Search: