[PATCH] Add ability to clone from all-history bundles

John Mulligan phlogistonjohn at asynchrono.us
Mon Mar 10 12:25:59 UTC 2008


On Monday 10 March 2008, Matt Mackall wrote:
> On Sun, 2008-03-09 at 14:40 -0400, John Mulligan wrote:
> > Hello dev list, this is my first attempt a a non-trivial patch, so please
> > be gentle :-)
> >
> > This patch allows the user to clone from all-history bundles without
> > doing anything special. The bundles must be local files, there is no
> > support for remote urls like mentioned in the thread here
> > [http://www.selenic.com/pipermail/mercurial/2008-February/017330.html].
> >
> > A bug was also recently created on this same subject too
> > [http://www.selenic.com/mercurial/bts/issue1024]. This motivated me to
> > attack this issue again.
> >
> > # HG changeset patch
> > # User John Mulligan <phlogistonjohn at asynchrono.us>
> > # Date 1205087188 14400
> > # Node ID 1cf834046bdafe39929d57c14f8c677bca14a379
> > # Parent  d2353ed8b153eb38dc804b704aa73b7edd4315bb
> > Add ability to clone from all-history bundles
> > - Don't copy a bundle like a normal localrepo on clone
> > - bundlerepos can be cloned from, if CWD is not a repo
> >
> > diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
> > --- a/mercurial/bundlerepo.py
> > +++ b/mercurial/bundlerepo.py
> > @@ -12,8 +12,8 @@
> >
> >  from node import hex, nullid, short
> >  from i18n import _
> > -import changegroup, util, os, struct, bz2, tempfile, mdiff
> > -import localrepo, changelog, manifest, filelog, revlog
> > +import changegroup, util, os, struct, bz2, tempfile, shutil, mdiff
> > +import repo, localrepo, changelog, manifest, filelog, revlog
> >
> >  class bundlerevlog(revlog.revlog):
> >      def __init__(self, opener, indexfile, bundlefile,
> > @@ -151,8 +151,14 @@
> >                                linkmapper)
> >
> >  class bundlerepository(localrepo.localrepository):
> > +    _tempparent = None
>
> You'll want to move that inside __init__ to make it local to the object.

OK.

>
> >      def __init__(self, ui, path, bundlename):
> > -        localrepo.localrepository.__init__(self, ui, path)
> > +        try:
> > +            localrepo.localrepository.__init__(self, ui, path)
> > +        except repo.RepoError, ee:
> > +            self._tempparent = tempfile.mkdtemp()
> > +            tmprepo = localrepo.instance(ui,self._tempparent,1)
> > +            localrepo.localrepository.__init__(self, ui,
> > self._tempparent)
>
> So we're creating an empty repo to build our bundlerepo off? A bit
> suboptimal. 

I couldn't see a less invasive way to do it. You should have seen some of my 
early attempts. :-) 

> The ',ee' is unnecessary. 

Force of habit, will remove.

> >          if path:
> >              self._url = 'bundle:' + path + '+' + bundlename
> > @@ -254,6 +260,8 @@
> >          tempfile = getattr(self, 'tempfile', None)
> >          if tempfile is not None:
> >              os.unlink(tempfile)
> > +        if self._tempparent:
> > +            shutil.rmtree(self._tempparent, True)
> >
> >  def instance(ui, path, create):
> >      if create:
> > diff --git a/mercurial/hg.py b/mercurial/hg.py
> > --- a/mercurial/hg.py
> > +++ b/mercurial/hg.py
> > @@ -148,7 +148,8 @@
> >
> >          abspath = origsource
> >          copy = False
> > -        if src_repo.local() and islocal(dest):
> > +        bundlesrc = isinstance(src_repo, bundlerepo.bundlerepository)
> > +        if src_repo.local() and islocal(dest) and not bundlesrc:
> >              abspath = os.path.abspath(util.drop_scheme('file',
> > origsource)) copy = not pull and not rev
>
> Hmm, that suggests if we clone from a bundle+repo today, it breaks. Is
> that right?

Yes. I tested with crew to confirm that I had the same results as issue1024, 
when you are outside of a parent repo. Then I cd'ed into an empty repo and 
tried to clone from my all-history bundle. I got no error, but it simply 
cloned the empty repository. Instead of getting the changesets out of the 
bundle it would do a dir-to-dir copy.

contents of /tmp:
  empty-repo 
  full-bundle.hg
  partial-bundle.hg

$ cd /tmp
hg clone /tmp/full-bundle.hg    /tmp/tclone2
abort: repository  not found!
$ cd /tmp/empty-repo
$ hg manifest | wc -l
0
$ hg clone /tmp/full-bundle.hg    /tmp/tclone3
0 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ hg -R /tmp/full-bundle.hg log  --template '{rev}\n'
2
1
0
$ hg -R /tmp/test.hg manifest | wc -l
6






More information about the Mercurial-devel mailing list