mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 14:58:03 +03:00
edenscm: add a separate path type for infinitepush writes
Summary: In order to support gradual rollout of infinitepush for other backends (e.g. Mononoke), we need the ability to route read vs write requests separately. To achieve this, we need a separate path type: `infinitepush-write` (kind of like `default-push`, the naming inconsistency is a little unfortunate, as I don't want to use `infinitepush-push`). The desired behavior of the new path type is as follows: - takes precedence over `infinitepush` path when the user does `hg push -r . --to scratch/bla` - replaces `infinitepush` path when the user does `hg push infinitepush -r . --to scratch/bla` - absence of this path means draft pushes will go to `infinitepush` path - draft pulls always go to `infinitepush` path, and *there's no fallback to `infinitepush-write`* - commit cloud always talks to `infinitepush-write`, if it is present (meaning that commit cloud pulls do go to `infinitepush-write` path - this is done, as commitcloud uses infinitepush paths to also check whether something is backed up - and also, commitcloud may need to pull very soon after something has been pushed Reviewed By: quark-zju Differential Revision: D20368158 fbshipit-source-id: 59db174cebbf2b48765dff37bc93aad176c2d7c1
This commit is contained in:
parent
7fcd49242c
commit
30e39de418
@ -10,7 +10,7 @@ import os
|
||||
from edenscm.mercurial import commands, encoding, error, pycompat, util
|
||||
from edenscm.mercurial.i18n import _
|
||||
|
||||
from . import error as ccerror
|
||||
from . import dependencies, error as ccerror
|
||||
|
||||
|
||||
SERVICE = "commitcloud"
|
||||
@ -67,7 +67,12 @@ def getreponame(repo):
|
||||
|
||||
def getremotepath(repo, dest):
|
||||
# If dest is empty, pass in None to get the default path.
|
||||
path = repo.ui.paths.getpath(dest or None, default=("infinitepush", "default"))
|
||||
pathname = dependencies.infinitepush.constants.pathname
|
||||
path = repo.ui.paths.getpath(
|
||||
dest or None,
|
||||
default=(pathname.infinitepushwrite, pathname.infinitepush, pathname.default),
|
||||
)
|
||||
|
||||
if not path:
|
||||
raise error.Abort(
|
||||
_("default repository not configured!"),
|
||||
|
@ -32,6 +32,7 @@ from edenscm.mercurial import (
|
||||
from edenscm.mercurial.i18n import _
|
||||
|
||||
from . import bookmarks, constants
|
||||
from .constants import pathname
|
||||
|
||||
|
||||
_maybehash = re.compile(r"^[a-f0-9]+$").search
|
||||
@ -109,16 +110,35 @@ def preparepush(ui, dest):
|
||||
# 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":
|
||||
if dest == pathname.default:
|
||||
try:
|
||||
return (True, ui.paths.getpath("infinitepush"))
|
||||
return (True, ui.paths.getpath(pathname.infinitepushwrite))
|
||||
except error.RepoError:
|
||||
# Fallthrough to the next block.
|
||||
pass
|
||||
|
||||
if dest is None or dest in ("default", "infinitepush"):
|
||||
try:
|
||||
return (True, ui.paths.getpath(pathname.infinitepush))
|
||||
except error.RepoError:
|
||||
# Fallthrough to the next block.
|
||||
pass
|
||||
|
||||
if dest == pathname.infinitepush:
|
||||
try:
|
||||
return (True, ui.paths.getpath(pathname.infinitepushwrite))
|
||||
except error.RepoError:
|
||||
# Fallthrough to the next block.
|
||||
pass
|
||||
|
||||
if dest in {None, pathname.default, pathname.infinitepush}:
|
||||
path = ui.paths.getpath(
|
||||
dest, default=("infinitepush", "default-push", "default")
|
||||
dest,
|
||||
default=(
|
||||
pathname.infinitepushwrite,
|
||||
pathname.infinitepush,
|
||||
pathname.defaultpush,
|
||||
pathname.default,
|
||||
),
|
||||
)
|
||||
return (True, path)
|
||||
|
||||
@ -201,11 +221,13 @@ def _push(orig, ui, repo, dest=None, *args, **opts):
|
||||
# the default infinitepush destination.
|
||||
if replicate:
|
||||
try:
|
||||
otherpath = repo.ui.paths.getpath("infinitepush-other")
|
||||
otherpath = repo.ui.paths.getpath(pathname.infinitepushother)
|
||||
except error.RepoError:
|
||||
pass
|
||||
else:
|
||||
path = ui.paths.getpath(dest, default=("default-push", "default"))
|
||||
path = ui.paths.getpath(
|
||||
dest, default=(pathname.defaultpush, pathname.default)
|
||||
)
|
||||
|
||||
# Copy-paste from `push` command
|
||||
if not path:
|
||||
@ -276,7 +298,7 @@ def _bookmarks(orig, ui, repo, *names, **opts):
|
||||
pattern = opts.get("list_remote")
|
||||
delete = opts.get("delete")
|
||||
remotepath = opts.get("remote_path")
|
||||
path = ui.paths.getpath(remotepath or None, default=("default"))
|
||||
path = ui.paths.getpath(remotepath or None, default=(pathname.default,))
|
||||
|
||||
if pattern:
|
||||
destpath = path.pushloc or path.loc
|
||||
@ -306,7 +328,7 @@ def _bookmarks(orig, ui, repo, *names, **opts):
|
||||
|
||||
if len(scratch_bms) > 0:
|
||||
if remotepath == "":
|
||||
remotepath = "default"
|
||||
remotepath = pathname.default
|
||||
bookmarks.deleteremotebookmarks(ui, repo, remotepath, scratch_bms)
|
||||
|
||||
if len(other_bms) > 0 or len(scratch_bms) == 0:
|
||||
@ -357,8 +379,10 @@ def _resetinfinitepushpath(ui, **opts):
|
||||
"""
|
||||
|
||||
overrides = {}
|
||||
infinitepushpath = "infinitepush"
|
||||
infinitepushbookmarkpath = "infinitepushbookmark"
|
||||
defaultpath = pathname.default
|
||||
infinitepushpath = pathname.infinitepush
|
||||
infinitepushwritepath = pathname.infinitepushwrite
|
||||
infinitepushbookmarkpath = pathname.infinitepushbookmark
|
||||
|
||||
pullingsinglecommithash = False
|
||||
if opts.get("rev"):
|
||||
@ -374,16 +398,23 @@ def _resetinfinitepushpath(ui, **opts):
|
||||
path = None
|
||||
|
||||
if path is not None:
|
||||
overrides[("paths", "default")] = ui.paths[path].loc
|
||||
overrides[("paths", defaultpath)] = ui.paths[path].loc
|
||||
overrides[("paths", infinitepushpath)] = "!"
|
||||
overrides[("paths", infinitepushwritepath)] = "!"
|
||||
overrides[("paths", infinitepushbookmarkpath)] = "!"
|
||||
with ui.configoverride(overrides, "infinitepush"):
|
||||
loc, sub = ui.configsuboptions("paths", "default")
|
||||
ui.paths["default"] = uimod.path(ui, "default", rawloc=loc, suboptions=sub)
|
||||
if infinitepushpath in ui.paths:
|
||||
del ui.paths[infinitepushpath]
|
||||
if infinitepushbookmarkpath in ui.paths:
|
||||
del ui.paths[infinitepushbookmarkpath]
|
||||
loc, sub = ui.configsuboptions("paths", defaultpath)
|
||||
ui.paths[defaultpath] = uimod.path(
|
||||
ui, defaultpath, rawloc=loc, suboptions=sub
|
||||
)
|
||||
for p in [
|
||||
infinitepushpath,
|
||||
infinitepushbookmarkpath,
|
||||
infinitepushwritepath,
|
||||
]:
|
||||
if p not in ui.paths:
|
||||
continue
|
||||
del ui.paths[p]
|
||||
yield
|
||||
else:
|
||||
yield
|
||||
|
@ -7,3 +7,12 @@ scratchbranchparttype = "b2x:infinitepush"
|
||||
scratchbookmarksparttype = "b2x:infinitepushscratchbookmarks"
|
||||
scratchmutationparttype = "b2x:infinitepushmutation"
|
||||
pushrebaseparttype = "b2x:rebase"
|
||||
|
||||
|
||||
class pathname(object):
|
||||
default = "default"
|
||||
defaultpush = "default-push"
|
||||
infinitepush = "infinitepush"
|
||||
infinitepushother = "infinitepush-other"
|
||||
infinitepushbookmark = "infinitepushbookmark"
|
||||
infinitepushwrite = "infinitepush-write"
|
||||
|
134
eden/scm/tests/test-infinitepush-write.t
Normal file
134
eden/scm/tests/test-infinitepush-write.t
Normal file
@ -0,0 +1,134 @@
|
||||
#chg-compatible
|
||||
|
||||
$ enable remotefilelog
|
||||
$ enable treemanifest
|
||||
|
||||
Setup the test
|
||||
$ . "$TESTDIR/library.sh"
|
||||
$ . "$TESTDIR/infinitepush/library.sh"
|
||||
$ setupcommon
|
||||
$ enable infinitepush pushrebase
|
||||
$ cat >> "$HGRCPATH" << EOF
|
||||
> [treemanifest]
|
||||
> sendtrees=True
|
||||
> treeonly=True
|
||||
> EOF
|
||||
$ cp "$HGRCPATH" "$TESTTMP/defaulthgrc"
|
||||
|
||||
$ hg init repo1
|
||||
$ cd repo1
|
||||
$ setupserver
|
||||
$ cat >> .hg/hgrc << EOF
|
||||
> [treemanifest]
|
||||
> server=true
|
||||
> EOF
|
||||
$ cd ..
|
||||
|
||||
$ hg init repo2
|
||||
$ cd repo2
|
||||
$ setupserver
|
||||
$ cat >> .hg/hgrc << EOF
|
||||
> [treemanifest]
|
||||
> server=true
|
||||
> EOF
|
||||
$ cd ..
|
||||
|
||||
$ hg init repo3
|
||||
$ cd repo3
|
||||
$ setupserver
|
||||
$ cat >> .hg/hgrc << EOF
|
||||
> [treemanifest]
|
||||
> server=true
|
||||
> EOF
|
||||
$ cd ..
|
||||
|
||||
Check that we push to the write path if it is present
|
||||
$ hg clone ssh://user@dummy/repo1 client -q
|
||||
$ cp "$TESTTMP/defaulthgrc" "$HGRCPATH"
|
||||
$ cat >> "$HGRCPATH" << EOF
|
||||
> [paths]
|
||||
> default-push=ssh://user@dummy/repo3
|
||||
> infinitepush=ssh://user@dummy/repo1
|
||||
> infinitepush-write=ssh://user@dummy/repo2
|
||||
> [remotefilelog]
|
||||
> fallbackpath=ssh://user@dummy/repo2
|
||||
> [infinitepush]
|
||||
> branchpattern=re:scratch/.+
|
||||
> EOF
|
||||
$ cd client
|
||||
$ mkcommit initialcommit
|
||||
$ hg push -r . --to scratch/test123 --create
|
||||
pushing to ssh://user@dummy/repo2
|
||||
searching for changes
|
||||
remote: pushing 1 commit:
|
||||
remote: 67145f466344 initialcommit
|
||||
$ mkcommit morecommit
|
||||
$ hg push infinitepush -r . --to scratch/test123
|
||||
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/repo2
|
||||
searching for changes
|
||||
remote: pushing 3 commits:
|
||||
remote: 67145f466344 initialcommit
|
||||
remote: 6b2f28e02245 morecommit
|
||||
remote: 17528c345014 anothercommit
|
||||
|
||||
-- check that we fallback to non-write path, when write path is not there
|
||||
$ mkcommit yetanothercommit
|
||||
$ hg push -r . --to scratch/test123 --create --config paths.infinitepush-write=
|
||||
pushing to ssh://user@dummy/repo1
|
||||
searching for changes
|
||||
remote: pushing 4 commits:
|
||||
remote: 67145f466344 initialcommit
|
||||
remote: 6b2f28e02245 morecommit
|
||||
remote: 17528c345014 anothercommit
|
||||
remote: 8785135185c9 yetanothercommit
|
||||
$ cd ..
|
||||
|
||||
Check that we pull/update from the read path, regardless of the write path presence
|
||||
$ hg clone ssh://user@dummy/repo1 client2 -q
|
||||
$ cp "$TESTTMP/defaulthgrc" "$HGRCPATH"
|
||||
$ cat >> "$HGRCPATH" << EOF
|
||||
> [paths]
|
||||
> infinitepush=ssh://user@dummy/repo2
|
||||
> infinitepush-write=ssh://user@dummy/repo3
|
||||
> [remotefilelog]
|
||||
> fallbackpath=ssh://user@dummy/repo2
|
||||
> [infinitepush]
|
||||
> branchpattern=re:scratch/.+
|
||||
> EOF
|
||||
$ cd client2
|
||||
$ mkcommit initialcommit
|
||||
$ hg pull -r 67145f466344
|
||||
pulling from ssh://user@dummy/repo2
|
||||
no changes found
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 0 changesets with 0 changes to 1 files
|
||||
$ hg update -r 6b2f28e02245
|
||||
'6b2f28e02245' does not exist locally - looking for it remotely...
|
||||
pulling from ssh://user@dummy/repo2
|
||||
searching for changes
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 1 changesets with 1 changes to 2 files
|
||||
'6b2f28e02245' found remotely
|
||||
pull finished in * (glob)
|
||||
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
|
||||
|
||||
-- check that we can pull from read path, when write path is not present
|
||||
$ hg pull -r 8785135185c9 --config paths.infinitepush-write= --config paths.infinitepush=ssh://user@dummy/repo1
|
||||
pulling from ssh://user@dummy/repo1
|
||||
searching for changes
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 2 changesets with 2 changes to 4 files
|
||||
$ cd ..
|
Loading…
Reference in New Issue
Block a user