Submitter | Lucas Moscovicz |
---|---|
Date | Jan. 14, 2014, 9:46 p.m. |
Message ID | <5fb7f56049148d73db25.1389735977@devrs047.prn2.facebook.com> |
Download | mbox | patch |
Permalink | /patch/3321/ |
State | Rejected |
Headers | show |
Comments
On Jan 14, 2014, at 4:46 PM, Lucas Moscovicz <lmoscovicz@fb.com> wrote: > # HG changeset patch > # User Lucas Moscovicz <lmoscovicz@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@selenic.com > http://selenic.com/mailman/listinfo/mercurial-devel
Patch
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()