infinitepush: alias "default" path into "infinitepush"

Summary:
Through Scuba, we can identify quite a few users that are doing `hg push default` for an infinitepush: https://fburl.com/scuba/6vz3ien7.

This is typically happening in repositories where the `default-push` destination is not the hg repository.

In fact, we actually prompt users to use hg push default if they try to perform a scratch push to a svn repository a few lines below!

markbt suggested we should just replicate the push in this case as well, which I think is a good idea.

Simply replicating the push in this case is not quite enough, however!

Indeed, for our infinitepushes to go to both Mercurial and Mononoke, we would have to maintain an number of consistency rules between `default`, `infinitepush`, and `infinitepush-other`:

- `default` and `infinitepush-other` must point to opposite repositories (i.e. one Mercurial, one Mononoke), to serve users using `hg push default`.
- `infinitepush` and `infinitepush-other` must point to opposite repositories, to serve users using `hg push` without a path.

This effectively means `default` and `infinitepush` must be the same, and `infinitepush-other` must be the other. We could do this with path markers, but this is getting so complicated that I don't foresee us getting it right.

At the end of the day, the root cause of this complexity stems from the fact that we're using a destination that is now effectively a read path (`default`) for infinitepush writes. I think this was perfectly valid when default meant "Mercurial, not subversion", but not so much now that we have Mononoke in the mix.

Of course, we could just update the message and ask our users to use `hg push infinitepush` instead, but this would mess with their muscle memory as well as their shell history (not to mention that `hg push default` would silently do the wrong thing).

So, this patch updates the code to use the infinitepush "write" destination for writes when that is what the user intended.

 ---

As a side note, note that the current behavior is actually a little broken. Indeed, if one were to do `hg push default --to scratch/$FOO` while Mononoke is serving reads, the scratch would go to Mononoke. In this scenario, the scratch push would in theory have been accepted but would have had its bookmarks discarded (at least until we support htose in Mononoke :) ).

This probably never happened in practice, however, for two reasons:

- Most users and systems that actively push scratch bookmarks are actually pushing to a specific `hg.vip` path instead of `default` (one notable exception is On Demand WWW).
- `hg push` to Mononoke for a scratch bookmark doesn't actually work if you have the pushrebase extension code loaded in some way (either by enabling the extension, or enabling an extension that uses it). See D15576199 for the details.

Reviewed By: farnz

Differential Revision: D15576545

fbshipit-source-id: c28b808632505bb8e8f4d114029f7d8c17c9749e
This commit is contained in:
Thomas Orozco 2019-06-03 05:23:36 -07:00 committed by Facebook Github Bot
parent b524b5d099
commit d6c8fef226
2 changed files with 63 additions and 8 deletions

View File

@ -100,6 +100,30 @@ def extsetup(ui):
)
def preparepush(ui, dest):
# If the user is saying they want to push to "default", and this is a
# scratch push, then we're going to go to the infinitepush destination
# instead, if it exists. This ensures that as long as infinitepush and
# infinitepush-other (see below) route to different places (respectively
# Mercurial and Mononoke), then infinite pushes without a path OR with a
# path of "default" will be routed to both of them. Put it another way: when
# you do a scratch push, "default" means the infinitepush path.
if dest == "default":
try:
return (True, ui.paths.getpath("infinitepush"))
except error.RepoError:
# Fallthrough to the next block.
pass
if dest is None or dest in ("default", "infinitepush"):
path = ui.paths.getpath(
dest, default=("infinitepush", "default-push", "default")
)
return (True, path)
return (False, ui.paths.getpath(dest))
def _push(orig, ui, repo, dest=None, *args, **opts):
bookmark = opts.get("to") or ""
create = opts.get("create") or False
@ -163,22 +187,23 @@ def _push(orig, ui, repo, dest=None, *args, **opts):
if scratchpush:
ui.setconfig("experimental", "infinitepush-scratchpush", True)
oldphasemove = extensions.wrapfunction(
exchange, "_localphasemove", _phasemove
)
path = ui.paths.getpath(
dest, default=("infinitepush", "default-push", "default")
)
# We'll replicate the push if the user provided no destination and
# intended their push to go to the default infinitepush destination.
if dest is None:
replicate, path = preparepush(ui, dest)
# We'll replicate the push if the user intended their push to go to
# the default infinitepush destination.
if replicate:
try:
otherpath = repo.ui.paths.getpath("infinitepush-other")
except error.RepoError:
pass
else:
path = ui.paths.getpath(dest, default=("default-push", "default"))
# Copy-paste from `push` command
if not path:
raise error.Abort(

View File

@ -24,6 +24,8 @@ Check that we replicate a push
$ cp "$TESTTMP/defaulthgrc" "$HGRCPATH"
$ cat >> "$HGRCPATH" << EOF
> [paths]
> default-push=ssh://user@dummy/repo3
> infinitepush=ssh://user@dummy/repo1
> infinitepush-other=ssh://user@dummy/repo2
> [infinitepush]
> branchpattern=re:scratch/.+
@ -40,6 +42,34 @@ Check that we replicate a push
searching for changes
remote: pushing 1 commit:
remote: 67145f466344 initialcommit
$ mkcommit morecommit
$ hg push infinitepush -r . --to scratch/test123
pushing to ssh://user@dummy/repo1
searching for changes
remote: pushing 2 commits:
remote: 67145f466344 initialcommit
remote: 6b2f28e02245 morecommit
please wait while we replicate this push to an alternate repository
pushing to ssh://user@dummy/repo2
searching for changes
remote: pushing 2 commits:
remote: 67145f466344 initialcommit
remote: 6b2f28e02245 morecommit
$ mkcommit anothercommit
$ hg push default -r . --to scratch/test123
pushing to ssh://user@dummy/repo1
searching for changes
remote: pushing 3 commits:
remote: 67145f466344 initialcommit
remote: 6b2f28e02245 morecommit
remote: 17528c345014 anothercommit
please wait while we replicate this push to an alternate repository
pushing to ssh://user@dummy/repo2
searching for changes
remote: pushing 3 commits:
remote: 67145f466344 initialcommit
remote: 6b2f28e02245 morecommit
remote: 17528c345014 anothercommit
$ cd ..
Check that we do not replicate a push to the same destination
@ -53,7 +83,7 @@ Check that we do not replicate a push to the same destination
> EOF
$ cd client2
$ mkcommit initialcommit
$ hg push -r . --to scratch/test123 --create
$ hg push -r . --to scratch/test456 --create
pushing to ssh://user@dummy/repo1
searching for changes
remote: pushing 1 commit:
@ -70,7 +100,7 @@ Check that we do not replicate a push when the destination is set
> EOF
$ cd client3
$ mkcommit initialcommit
$ hg push ssh://user@dummy/repo3 -r . --to scratch/test123 --create
$ hg push ssh://user@dummy/repo3 -r . --to scratch/test789 --create
pushing to ssh://user@dummy/repo3
searching for changes
remote: pushing 1 commit: