Mercurial Changeset Evolution
Mercurial Changeset Evolution
Posted Apr 25, 2023 10:01 UTC (Tue) by farnz (subscriber, #17727)In reply to: Mercurial Changeset Evolution by kleptog
Parent article: Avoiding the merge trap
So the point of the distinction between "secret", "draft" and "public" is to prevent user error.
If you try to push a set of commits where one of them is secret (e.g. with the equivalent of git push origin HEAD), Mercurial will refuse and tell you which secret commits you tried to push. You have to use hg phase to change the secret commit to draft; similarly, someone pulling from your repo cannot pull secret commits until you use hg phase to make them draft.
Mercurial knows at the protocol level whether a remote branch is immutable or not - and will automatically convert commits from draft to public when they're pushed to an immutable branch. Similarly, if you pull from an immutable branch, it can include markers to tell you that a public commit obsoletes one of your draft commits, whereas if you pull from a mutable branch, it'll keep the commits as drafts.
You can always tell Mercurial that it's got it wrong with hg phase --force, and convert a public commit to a draft. Mercurial's revset language makes it relatively easy to script this, too, because you can define a revset that catches all the commits you're going to work with, and force their phase to draft.
There is, though, a different mindset between git and hg in this respect - git assumes that the user is infallible, and trusts you to never make a mistake. hg assumes that you're fallible, and expects to provide "safety rails" so that you can do your "normal" workflow without fear of doing something bad (like accidentally modifying a commit that's supposed to be immutable). But, like any good safety rails, hg provides ways for you to remove them - that's not going to be part of your normal workflow (you wouldn't do hg phase … && hg rebase … normally), but it's there for you if you need it.
Posted Apr 25, 2023 18:26 UTC (Tue)
by marcH (subscriber, #57642)
[Link]
Well put, thank you again!
[The rest is answering HEAD~2]
> > Secret commits: if I don't want people to see them I can just not push them. But then again, none of my code is particularly special so if I accidentally pushed it somewhere it wouldn't matter anyway. They'd just become draft instead of secret.
Maybe "private" would be a better name. "Secret" sounds like helping with security but "security secrets" need to be shared within a team more often than not and this is clearly not the intention of that sort of "secret".
> > Public commits: are those merged with one of the branches destined for release. These are also effectively immutable.
"Public" looks again like a poor name because linux-next style branches are public and they're not immutable. I find "Final" better.
> > The thing is that at its core, git really is a stupid content tracker. So it focusses on mechanism rather than policy. I can understand the distinctions that "hg evolve" is drawing, but I'm not really understanding why I need the tool to track this for me. (Nice summary by the way).
It's very likely that "hg evolve" goes much further than core git will ever go for that reason. There is often a fine line between holding the users' hand too much and making sure they have all the rope they need to hang themselves with and yes we know on which side of that line git always prefers to err :-)
That's all fine and good however the mere _concepts_ that "hg evolve" deals with (private/public/draft/volatile/final, etc.) are not just "policy". They became universal since we moved away from centralized version control yet they are missing from even git's documentation, which is a bit ironic when you think about it. The evidence is that you can easily find famous lectures about "don't rebase public branches"... where the term "public" does not make sense because linux-next is public. There are also regularly articles on these topics in some weekly Linux gazette.
Don't just "blame the users"; if they need to be repeatedly "educated" then there's probably something wrong or missing with the tool instead. Well at least don't blame most users most of the time, if you do that then it's clear evidence that there is a gap of some kind. Maybe not a big feature gap as big as "hg evolve" (although we just got "git range-diff", so there was clearly at least that gap) but at the very least a big _conceptual_ gap. I critized "hg evolve"'s terminology but it's at least unambiguous because it's defined by its implementation. Git's counterpart to "hg evolve" is emptiness, not even basic conceptual documentation and IMHO articles like this one keep trying to fill that void.
Another demonstration of this conceptual gap is when people discover how most Github projects use git in a totally different way yet they struggle to describe the difference in less than a few hundred words: https://github.com/zephyrproject-rtos/zephyr/issues/53566
Hey maybe _I_ should stop complaining and "send patches" to git man pages offering some standard terminology, I bet it could be already useful in some existing man pages. This shouldn't require any development knowledge and would be a start
https://public-inbox.org/git/70ccb8fc-30f2-5b23-a832-9e470787a945@intel.com/
Mercurial Changeset Evolution