This is an archive of the discontinued Mercurial Phabricator instance.

rebase: initial support for multiple destinations
ClosedPublic

Authored by quark on Aug 22 2017, 1:16 AM.

Details

Summary

This patch defines SRC (a single source revision) and ALLSRC (all source
revisions) to be valid names in --dest revset if --src or --rev is
used. So destination could be defined differently according to source
revisions. The names are capitalized to make it clear they are "dynamically
defined", distinguishable from normal revsets (Thanks Augie for the
suggestion).

This is useful, for example, -r 'orphan()' -d 'calc-dest(SRC)' to solve
instability, which seems to be a highly wanted feature.

The feature is not completed, namely if -d overlaps with -r, things
could go wrong. A later patch will handle that case.

The feature is also gated by experimental.rebase.multidest config option
which is default off.

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

quark created this revision.Aug 22 2017, 1:16 AM
martinvonz added inline comments.
hgext/rebase.py
822

could pass ALLSRC in the fast-path version too, no? because the concern is not that that calcularing "allsrc" is costly, i assume, but that running the revset over all the revisions is

824

anyrevs() doesn't seem to make much sense here. Why not let localrepo.revs() and localrepo.set() accept "user" and "localalias" arguments too? I realize it's more code, but it seem to make more sense. Unless this is just temporary and you're planning on passing a longer list here later.

824

The destination revset is resolved earlier than I had expected. Or at least I expected it to be evaluated later, *as well*, I suppose.

Let's say my revset is "successors(parents(SRC))" (i.e. a naive attempt at "hg evolve") and my graph looks like this:

o A'
| o C
| o B
| x A
|/
o

If I then do "hg rebase -s B -d <as above>", it seems like only B would be rebased. Do you have plans for making it so C gets rebased too?

tests/test-rebase-dest.t
295

Where is "map" defined?

quark added inline comments.Aug 29 2017, 9:09 AM
hgext/rebase.py
822

Good advice! I was focused on SRC and didn't consider the use-case where ALLSRC is used but not SRC. Will make fast path use it too.

824

repo.revs docstring has:

Revset aliases from the configuration are not expanded. To expand
user aliases, consider calling ``scmutil.revrange()`` or
``repo.anyrevs([expr], user=True)``.

I think it makes sense to expend them. So anyrevs is used. I guess that's also why any is part of the method name.

IIUC, most user-provided revsets are expected to be consumed by scmutil.revrange, which uses repo.anyrev. So anyrev sounds like the right choice here.


For the example, see the test cases in the next patch. You need a more complex revset.

Defer resolving revsets could result in a much more complex patch (state file format, the order of obsmarker creation and bookmark movement need change). Performance may decline since we need to re-resolve and re-sort everything after every DAG change. I guess there are also more corner cases to handle (ex. -d tip may behave undesirably).

Note that even if you'd like to defer resolving destinations, it still need to know destinations first to decide which changesets to begin with (see the next patch). So the code here is still necessary.

I'd like we start simple.

tests/test-rebase-dest.t
295

Line 89.

quark edited the summary of this revision. (Show Details)Aug 29 2017, 9:40 PM
quark updated this revision to Diff 1418.
This revision was automatically updated to reflect the committed changes.