[PATCH V2] init: changed creation order of 00changelog and requires files (issue3960)

Augie Fackler raf at durin42.com
Fri Feb 28 13:56:20 CST 2014


On Jan 14, 2014, at 4:46 PM, Lucas Moscovicz <lmoscovicz at fb.com> wrote:

> # HG changeset patch
> # User Lucas Moscovicz <lmoscovicz at fb.com>
> # Date 1389639192 28800
> #      Mon Jan 13 10:53:12 2014 -0800
> # Node ID 5fb7f56049148d73db2566d8b5d7ba791bed938b
> # Parent  f694cd81b600b65d23dcdc7a02cfd6a57dd1d018
> init: changed creation order of 00changelog and requires files (issue3960)

This looks completely reasonable to me, but I'd like mpm to comment...

> 
> When initializing a repo with hg init if another client cloned the repo after
> the 00changelog file was created but before the requires file was created they
> would get an error about unknown revlog format.  To fix it, I changed the
> creation order of those files since the changelog file can be created at any
> time during the initialization.
> 
> Also, to solve the race problem that came up where an old client commited
> something to the repo before both the requires and the 00changelog file were
> created and then the 00changelog file would overwrite that commit, the initial
> name of the .hg folder was changed to .hgtmp, getting renamed back to .hg once
> the requires and 00changelog files are created leaving no point in time where
> an old client can commit to the new styled repo.
> 
> diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py
> --- a/mercurial/localrepo.py
> +++ b/mercurial/localrepo.py
> @@ -195,26 +195,36 @@
> 
>         if not self.vfs.isdir():
>             if create:
> -                if not self.wvfs.exists():
> -                    self.wvfs.makedirs()
> -                self.vfs.makedir(notindexed=True)
> -                requirements = self._baserequirements(create)
> -                if self.ui.configbool('format', 'usestore', True):
> -                    self.vfs.mkdir("store")
> -                    requirements.append("store")
> -                    if self.ui.configbool('format', 'usefncache', True):
> -                        requirements.append("fncache")
> -                        if self.ui.configbool('format', 'dotencode', True):
> -                            requirements.append('dotencode')
> -                    # create an invalid changelog
> -                    self.vfs.append(
> -                        "00changelog.i",
> -                        '\0\0\0\2' # represents revlogv2
> -                        ' dummy changelog to prevent using the old repo layout'
> -                    )
> -                if self.ui.configbool('format', 'generaldelta', False):
> -                    requirements.append("generaldelta")
> -                requirements = set(requirements)
> +                oldvfs = self.vfs
> +                try:
> +                    self.vfs = scmutil.vfs(self.wvfs.join(".hgtmp"))
> +                    self.opener = self.vfs
> +                    if not self.wvfs.exists():
> +                        self.wvfs.makedirs()
> +                    self.vfs.makedir(notindexed=True)
> +                    requirements = self._baserequirements(create)
> +                    if self.ui.configbool('format', 'usestore', True):
> +                        self.vfs.mkdir("store")
> +                        requirements.append("store")
> +                        if self.ui.configbool('format', 'usefncache', True):
> +                            requirements.append("fncache")
> +                            if self.ui.configbool('format', 'dotencode', True):
> +                                requirements.append('dotencode')
> +                    if self.ui.configbool('format', 'generaldelta', False):
> +                        requirements.append("generaldelta")
> +                    requirements = set(requirements)
> +                    self._writerequirements(requirements)
> +                    if self.ui.configbool('format', 'usestore', True):
> +                        # create an invalid changelog
> +                        self.vfs.append(
> +                            "00changelog.i",
> +                            '\0\0\0\2' # represents revlogv2
> +                            ' dummy changelog to prevent using the old repo layout'
> +                        )
> +                    self.wvfs.rename(".hgtmp", ".hg")
> +                finally:
> +                    self.vfs = oldvfs
> +                    self.opener = oldvfs
>             else:
>                 raise error.RepoError(_("repository %s not found") % path)
>         elif create:
> @@ -247,9 +257,6 @@
>         self.sjoin = self.store.join
>         self.vfs.createmode = self.store.createmode
>         self._applyrequirements(requirements)
> -        if create:
> -            self._writerequirements()
> -
> 
>         self._branchcaches = {}
>         self.filterpats = {}
> @@ -285,9 +292,11 @@
>         if chunkcachesize is not None:
>             self.sopener.options['chunkcachesize'] = chunkcachesize
> 
> -    def _writerequirements(self):
> +    def _writerequirements(self, requirements=None):
>         reqfile = self.opener("requires", "w")
> -        for r in sorted(self.requirements):
> +        if requirements is None:
> +            requirements = self.requirements
> +        for r in sorted(requirements):
>             reqfile.write("%s\n" % r)
>         reqfile.close()
> 
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel



More information about the Mercurial-devel mailing list