Using changeset obsoletion with Kallithea

Thomas De Schampheleire patrickdepinguin at gmail.com
Sun May 29 19:01:12 UTC 2016


On Sun, May 29, 2016 at 12:53 PM, Andrew Shadura <andrew at shadura.me> wrote:
> Hello everyone,
>
> I've been using and advocating use of changeset obsoletion for quite a
> while now, and tried to use it when submitting pull requests to
> Kallithea as well, but I noticed very few people seem to understand how
> it works, and some people seem to be a bit wary about it, so I thought
> it may be worth explaining how I use it to others, and when Mads
> suggested I do so, I felt motivated enough to write something up on this
> topic :)
>
> First of all, I need to admit I do not use Evolve extension, even though
> I might benefit from it if I did, but in my opinion it adds to much
> automation I don't need at the moment; in any case, obsoletion makes
> work with Mercurial much more pleasant even without Evolve.

This is an important point that I used to not know: changeset
evolution does not require Evolve.
Obsolescence markers are already handled and created by vanilla Mercurial.

>
> One thing you need to know about obsoletion to be able to use it is what
> an obsoletion marker is. Basically, Mercurial can store a list of
> changeset identifiers, sort of a map, which maps "old" changesets to
> "new" ones every time you amend some changeset. Every such pair of
> changeset identifiers is called an obsoletion marker: it "obsoletes" a
> changeset, replacing it with another. Obsoletion markers can be pushed
> and pulled, all at once, propagating between repositories. Every
> obsoletion marker also stores some metadata: a timestamp and an email of
> its author.
>
> The way it works is the following. When you amend a changeset without
> using obsoletion, this is what happens:
>
>  → A → B → C    ⇒    → A → B    ⇒    → A → B → C’
>
> (Mercurial first strips the original changeset, then creates a new one)
>
> With obsoletion, no changesets are stripped. Instead, a new changeset is
> created, along with an obsoletion marker:
>
>  → A → B → C    ⇒    → A → B ⇢ C
>                              ↘ C’
>
>   (C’ obsoletes C)
>
> Obsolete changesets become hidden as soon as nothing references them
> (including the working directory) provided they're not public. To be
> able to see hidden changesets, you need to use --hidden option;
> otherwise the changesets will be skipped from the log and other commands
> will complain they don't exist.
>
> Obsoletion markers are created automatically by many Mercurial commands,
> most notably commit --amend and rebase. You can also manually create
> them using an undocumented debugobsolete command.
>
> Obsoletion is very useful in pull request-based workflows. With Git,
> when you're submitting another iteration of a pull request, you may just
> --force the branch, and the old iteration won't clutter history anymore,
> and will be visible only if you know the commit hash — unless someone
> garbage collected the repository. With Mercurial, every iteration of the
> pull request is forever, unless you nuke the repository or strip extra
> branches of history or use bundle repository overlays.
>
> With obsoletion, it is possible to rebase your branch, rewrite the
> history in whatever way you like, then push it again to a non-publishing
> repository and have your previous iteration disappear from the default
> view, while still being available for review from an old iteration of a
> pull request. Kallithea doesn't directly support this workflow yet, but
> I've written a proof of concept patch which is applied at Ook, so I can
> show some examples:
>
>   https://kallithea-scm.org/repos/kallithea/pull-request/20
>
> This was an original proposal to support "evolution" of pull requests.
> After Mads and Thomas commented on it, I reworked the implementation and
> pushed it along with obsoletion markers. The old changeset,
> af2c5e101157, became obsoleted, and even though it's still visible in
> the pull request, it's no longer possible to pull it or see it in the
> changelog unless you specifically ask for it.
>
>   https://kallithea-scm.org/repos/kallithea/pull-request/32
>
> This is a second iteration of the PR. If you do to
>
>
> https://kallithea-scm.org/repos/andrewsh/kallithea/changeset/02257b8abe8d58fad0e10c929505561f5266bfd8
>
> that page says:
>
>   Replaced by: 892ee667a841
>   Preceded by: af2c5e101157
>
> That's because after I've got some comments, I changed the
> implementation again, and posted that as
>
>   https://kallithea-scm.org/repos/kallithea/pull-request/45
>
> When Mads is happy with the implementation, he can either directly pull
> my changeset, if it's based on the right branch head, or he can rebase
> it on the current default branch — which may produce obsoletion markers
> if he has obsoletion enabled (I know he doesn't). And if it does, when
> he pushes to the main repository, and I pull back from it, I'll have my
> old implementation automatically obsoleted — and if I don't have it
> checked out, it will be automatically replaced by the new changeset.
>
> This helps having cleaner history in the repositories without having
> multiheaded hydras we have now (or we don't actually have them, as I'm
> cleaning up kallithea-incoming from time to time, but Unity's repository
> definitely does, as Bitbucket doesn't support obsoletion).
>
> Oh, and the last thing: how to get that cool thing. Just put this into
> your hgrc:
>
> [experimental]
> evolution = all
>

What exactly does this bring on top of vanilla Mercurial? And where is
this setting defined?
Are you sure it is still relevant with recent versions of Mercurial, say 3.7+ ?

I don't have this setting and use rebase/histedit, and do see obselete
changes with 'log --hidden'.


> Optionally, also this, where applicable:
>
> [phases]
> publish = False

Thanks for writing all this.
What is the plan with this text, will we publish it somewhere?

/Thomas


More information about the kallithea-general mailing list