mirror of
https://github.com/facebook/sapling.git
synced 2024-10-06 23:07:18 +03:00
cloud rejoin command
Summary: this command will be use in fbclone it does sync and join if a person has been used already the commit cloud workspace in that repo Reviewed By: markbt Differential Revision: D8640667 fbshipit-source-id: 9c8d96497cf7930b995a49c8bdaebe7048e0c1e8
This commit is contained in:
parent
6bd246ce84
commit
4ff0279f08
@ -95,6 +95,50 @@ def cloudjoin(ui, repo, **opts):
|
||||
cloudsync(ui, repo, **opts)
|
||||
|
||||
|
||||
@subcmd("rejoin|reconnect", [])
|
||||
def cloudrejoin(ui, repo, **opts):
|
||||
"""reconnect the local repository to commit cloud
|
||||
|
||||
Reconnect only happens if the machine has been registered with Commit Cloud,
|
||||
and the workspace has been already used for this repo
|
||||
|
||||
Use `hg cloud sync` to trigger a new synchronization.
|
||||
|
||||
Use `hg cloud connect` to connect to commit cloud for the first time.
|
||||
"""
|
||||
|
||||
token = commitcloudutil.TokenLocator(ui).token
|
||||
if token:
|
||||
try:
|
||||
serv = service.get(ui, token)
|
||||
serv.check()
|
||||
reponame, workspace = getdefaultrepoworkspace(ui, repo)
|
||||
highlightstatus(
|
||||
ui,
|
||||
_("trying to reconnect to the '%s' workspace for the '%s' repo\n")
|
||||
% (workspace, reponame),
|
||||
)
|
||||
cloudrefs = serv.getreferences(reponame, workspace, 0)
|
||||
if cloudrefs.version == 0:
|
||||
highlightstatus(
|
||||
ui,
|
||||
_(
|
||||
"unable to reconnect: this workspace has been never connected to commit cloud for this repo\n"
|
||||
),
|
||||
)
|
||||
else:
|
||||
commitcloudutil.WorkspaceManager(repo).setworkspace(workspace)
|
||||
highlightstatus(ui, _("the repository is now reconnected\n"))
|
||||
cloudsync(ui, repo, cloudrefs, **opts)
|
||||
return
|
||||
except commitcloudcommon.RegistrationError:
|
||||
pass
|
||||
|
||||
highlightstatus(
|
||||
ui, _("unable to reconnect: not authenticated with commit cloud on this host\n")
|
||||
)
|
||||
|
||||
|
||||
@subcmd("leave|disconnect")
|
||||
def cloudleave(ui, repo, **opts):
|
||||
"""disconnect the local repository from commit cloud
|
||||
@ -195,6 +239,17 @@ def getrepoworkspace(ui, repo):
|
||||
return reponame, workspace
|
||||
|
||||
|
||||
def getdefaultrepoworkspace(ui, repo):
|
||||
"""get default workspace identity
|
||||
repo may be not joined to this workspace yet
|
||||
"""
|
||||
workspacemanager = commitcloudutil.WorkspaceManager(repo)
|
||||
reponame = workspacemanager.reponame
|
||||
if not reponame:
|
||||
raise commitcloudcommon.ConfigurationError(ui, _("unknown repo"))
|
||||
return reponame, workspacemanager.defaultworkspace
|
||||
|
||||
|
||||
@subcmd(
|
||||
"sync",
|
||||
[
|
||||
@ -229,7 +284,7 @@ def getrepoworkspace(ui, repo):
|
||||
),
|
||||
],
|
||||
)
|
||||
def cloudsync(ui, repo, **opts):
|
||||
def cloudsync(ui, repo, cloudrefs=None, **opts):
|
||||
"""synchronize commits with the commit cloud service"""
|
||||
repo.ignoreautobackup = True
|
||||
if opts.get("use_bgssh"):
|
||||
@ -246,7 +301,7 @@ def cloudsync(ui, repo, **opts):
|
||||
srcrepo = shareutil.getsrcrepo(repo)
|
||||
with lockmod.lock(srcrepo.vfs, _backuplockname, timeout=timeout):
|
||||
currentnode = repo["."].node()
|
||||
_docloudsync(ui, repo, **opts)
|
||||
_docloudsync(ui, repo, cloudrefs, **opts)
|
||||
return _maybeupdateworkingcopy(ui, repo, currentnode)
|
||||
except error.LockHeld as e:
|
||||
if e.errno == errno.ETIMEDOUT:
|
||||
@ -263,14 +318,14 @@ def cloudsync(ui, repo, **opts):
|
||||
raise
|
||||
|
||||
|
||||
def _docloudsync(ui, repo, **opts):
|
||||
def _docloudsync(ui, repo, cloudrefs=None, **opts):
|
||||
start = time.time()
|
||||
|
||||
# external services can run cloud sync and require to check if
|
||||
# auto sync is enabled
|
||||
if opts.get("check_autosync_enabled") and not autosyncenabled(ui, repo):
|
||||
highlightstatus(
|
||||
ui, _("automatic backup and synchronization " "is currently disabled\n")
|
||||
ui, _("automatic backup and synchronization is currently disabled\n")
|
||||
)
|
||||
return 0
|
||||
|
||||
@ -279,7 +334,7 @@ def _docloudsync(ui, repo, **opts):
|
||||
serv = service.get(ui, tokenlocator.token)
|
||||
highlightstatus(ui, _("synchronizing '%s' with '%s'\n") % (reponame, workspace))
|
||||
|
||||
lastsyncstate = state.SyncState(repo)
|
||||
lastsyncstate = state.SyncState(repo, workspace)
|
||||
|
||||
# external services can run cloud sync and know the lasest version
|
||||
version = opts.get("workspace_version")
|
||||
@ -287,7 +342,9 @@ def _docloudsync(ui, repo, **opts):
|
||||
highlightstatus(ui, _("this version has been already synchronized\n"))
|
||||
return 0
|
||||
|
||||
cloudrefs = serv.getreferences(reponame, workspace, lastsyncstate.version)
|
||||
# cloudrefs are passed in cloud rejoin
|
||||
if cloudrefs is None:
|
||||
cloudrefs = serv.getreferences(reponame, workspace, lastsyncstate.version)
|
||||
|
||||
synced = False
|
||||
pushfailures = set()
|
||||
@ -424,7 +481,8 @@ def cloudrecover(ui, repo, **opts):
|
||||
the repository from scratch.
|
||||
"""
|
||||
highlightstatus(ui, "clearing local commit cloud cache\n")
|
||||
state.SyncState.erasestate(repo)
|
||||
_, workspace = getrepoworkspace(ui, repo)
|
||||
state.SyncState.erasestate(repo, workspace)
|
||||
cloudsync(ui, repo, **opts)
|
||||
|
||||
|
||||
|
@ -241,8 +241,14 @@ class WorkspaceManager(object):
|
||||
os.path.basename(self.ui.config("paths", "default")),
|
||||
)
|
||||
|
||||
@property
|
||||
def defaultworkspace(self):
|
||||
"""Default workspace name"""
|
||||
return self._getdefaultworkspacename()
|
||||
|
||||
@property
|
||||
def workspace(self):
|
||||
"""Current connected workspace (reads commitcloudrc file)"""
|
||||
if self.repo.svfs.exists(self.filename):
|
||||
with self.repo.svfs.open(self.filename, r"rb") as f:
|
||||
workspaceconfig = config.config()
|
||||
|
@ -33,22 +33,12 @@ class SyncState(object):
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def erasestate(cls, repo):
|
||||
# get current workspace
|
||||
workspace = commitcloudutil.getworkspacename(repo)
|
||||
if not workspace:
|
||||
raise commitcloudcommon.WorkspaceError(repo.ui, _("undefined workspace"))
|
||||
|
||||
def erasestate(cls, repo, workspace):
|
||||
filename = cls._filename(workspace)
|
||||
# clean up the current state in force recover mode
|
||||
repo.svfs.tryunlink(filename)
|
||||
|
||||
def __init__(self, repo):
|
||||
# get current workspace
|
||||
workspace = commitcloudutil.getworkspacename(repo)
|
||||
if not workspace:
|
||||
raise commitcloudcommon.WorkspaceError(repo.ui, _("undefined workspace"))
|
||||
|
||||
def __init__(self, repo, workspace):
|
||||
self.filename = self._filename(workspace)
|
||||
repo = shareutil.getsrcrepo(repo)
|
||||
self.repo = repo
|
||||
|
@ -1121,3 +1121,57 @@ Check subscription when join/leave and also scm service health check
|
||||
repo_name=server
|
||||
repo_root=$TESTTMP/client1/.hg
|
||||
|
||||
$ cd ..
|
||||
|
||||
Rejoin
|
||||
$ rm -rf client2
|
||||
$ mkdir client2
|
||||
|
||||
$ mkdir $TESTTMP/otherservicelocation
|
||||
$ mkdir $TESTTMP/othertokenlocation
|
||||
|
||||
$ hg clone ssh://user@dummy/server client2 -q
|
||||
$ cd client2
|
||||
$ cat ../shared.rc >> .hg/hgrc
|
||||
|
||||
$ hg cloud reconnect --config "commitcloud.user_token_path=$TESTTMP/othertokenlocation" # invalid token
|
||||
#commitcloud unable to reconnect: not authenticated with commit cloud on this host
|
||||
|
||||
$ hg cloud reconnect --config "commitcloud.servicelocation=$TESTTMP/otherservicelocation" # token is valid but server is different
|
||||
#commitcloud trying to reconnect to the 'user/test/default' workspace for the 'server' repo
|
||||
#commitcloud unable to reconnect: this workspace has been never connected to commit cloud for this repo
|
||||
|
||||
$ hg cloud reconnect # should be able to reconnect
|
||||
#commitcloud trying to reconnect to the 'user/test/default' workspace for the 'server' repo
|
||||
#commitcloud the repository is now reconnected
|
||||
#commitcloud synchronizing 'server' with 'user/test/default'
|
||||
pulling from ssh://user@dummy/server
|
||||
searching for changes
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 2 changesets with 2 changes to 2 files (+1 heads)
|
||||
adding changesets
|
||||
adding manifests
|
||||
adding file changes
|
||||
added 2 changesets with 3 changes to 3 files
|
||||
new changesets 3597ff85ead0:af621240884f
|
||||
(run 'hg heads' to see heads, 'hg merge' to merge)
|
||||
#commitcloud commits synchronized
|
||||
|
||||
$ hg trglog
|
||||
o af621240884f 'stack 1 second'
|
||||
|
|
||||
o 81cd67693e59 'stack 1 first'
|
||||
|
|
||||
| o 799d22972c4e 'stack 2 second'
|
||||
| |
|
||||
| o 3597ff85ead0 'stack 2 first'
|
||||
| |
|
||||
@ | 97250524560a 'public 2' default/publicbookmark2 default/default
|
||||
| |
|
||||
o | acd5b9e8c656 'public' default/publicbookmark1
|
||||
|/
|
||||
o d20a80d4def3 'base'
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user