diff --git a/eden/scm/edenscm/mercurial/clone.py b/eden/scm/edenscm/mercurial/clone.py index e31562b4df..eb8c5aceba 100644 --- a/eden/scm/edenscm/mercurial/clone.py +++ b/eden/scm/edenscm/mercurial/clone.py @@ -117,3 +117,28 @@ def emergencyclone(source, repo): repo.invalidate() repo.invalidatechangelog() + + +def segmentsclone(source, clonedata, repo): + """clone using segmented changelog's CloneData + + This produces a repo with lazy commit hashes. + """ + with repo.wlock(), repo.lock(), repo.transaction("clone"): + changelog2.migrateto(repo, "lazy") + repo.requirements.add("remotefilelog") + repo._writerequirements() + + repo.ui.status(_("populating main commit graph\n")) + repo.changelog.inner.importclonedata(clonedata) + tip = repo.changelog.dag.all().first() + if tip: + repo.ui.status(_("tip commit: %s\n") % hex(tip)) + repo.svfs.write("tip", tip) + + repo.ui.status(_("fetching selected remote bookmarks\n")) + remote = bookmod.remotenameforurl(repo.ui, repo.ui.paths.getpath(source).rawloc) + assert remote is not None + repo.pull( + source, bookmarknames=bookmod.selectivepullbookmarknames(repo, remote) + ) diff --git a/eden/scm/edenscm/mercurial/eagerpeer.py b/eden/scm/edenscm/mercurial/eagerpeer.py index beab419811..19fa4e241e 100644 --- a/eden/scm/edenscm/mercurial/eagerpeer.py +++ b/eden/scm/edenscm/mercurial/eagerpeer.py @@ -98,6 +98,11 @@ class eagerpeer(repository.peer): ) yield node, parents + # Clone using dag::CloneData (designed for lazy backend) + + def clonedata(self): + return self.edenapi.clonedata(self._reponame) + # The Python "peer" interface. # Prefer using EdenAPI to implement them. @@ -132,6 +137,7 @@ class eagerpeer(repository.peer): "branchmap", "addblobs", "commitgraph", + "clonedata", } def debugwireargs(self, one, two, three=None, four=None, five=None): diff --git a/eden/scm/edenscm/mercurial/hg.py b/eden/scm/edenscm/mercurial/hg.py index 4ceb5fb29b..eb72e1f127 100644 --- a/eden/scm/edenscm/mercurial/hg.py +++ b/eden/scm/edenscm/mercurial/hg.py @@ -592,9 +592,14 @@ def clone( ) revs = [srcpeer.lookup(r) for r in rev] checkout = revs[0] + + # Can we use EdenAPI CloneData? + if srcpeer.capable("clonedata") and shallow and not update: + data = srcpeer.clonedata() + clonemod.segmentsclone(srcpeer.url(), data, destrepo) # Can we use the new code path (stream clone + shallow + no # update + selective pull)? - if ( + elif ( destrepo and not pull and not update diff --git a/eden/scm/tests/test-eager-exchange.t b/eden/scm/tests/test-eager-exchange.t index 17f4da445c..53b3c1a97c 100644 --- a/eden/scm/tests/test-eager-exchange.t +++ b/eden/scm/tests/test-eager-exchange.t @@ -118,3 +118,22 @@ Trigger file and tree downloading: TRACE eagerepo::api: found: 35e7525ce3a48913275d7061dd9a867ffef1e34d, 41 bytes AB (no-eol) +Clone: + + $ cd $TESTTMP + $ hg clone -U --shallow eager:$TESTTMP/e1 cloned + DEBUG eagerepo::api: clone_data + populating main commit graph + fetching selected remote bookmarks + DEBUG eagerepo::api: bookmarks master + DEBUG edenscm::mercurial::eagerpeer: listkeyspatterns(bookmarks, ['master']) = sortdict([('master', 'dc0947a82db884575bb76ea10ac97b08536bfa03')]) + DEBUG eagerepo::api: bookmarks master + DEBUG edenscm::mercurial::eagerpeer: listkeyspatterns(bookmarks, ['master']) = sortdict([('master', 'dc0947a82db884575bb76ea10ac97b08536bfa03')]) + DEBUG eagerepo::api: bookmarks master + DEBUG edenscm::mercurial::eagerpeer: listkeyspatterns(bookmarks, ['master']) = sortdict([('master', 'dc0947a82db884575bb76ea10ac97b08536bfa03')]) + DEBUG eagerepo::api: commit_known + DEBUG eagerepo::api: commit_graph dc0947a82db884575bb76ea10ac97b08536bfa03 + TRACE edenscm::mercurial::eagerpeer: graph node 426bada5c67598ca65036d57d9e4b64b0c1ce7a0 [] + TRACE edenscm::mercurial::eagerpeer: graph node dc0947a82db884575bb76ea10ac97b08536bfa03 ['426bada5c67598ca65036d57d9e4b64b0c1ce7a0'] + DEBUG eagerepo::api: bookmarks master + DEBUG edenscm::mercurial::eagerpeer: listkeyspatterns(bookmarks, ['master']) = sortdict([('master', 'dc0947a82db884575bb76ea10ac97b08536bfa03')])