This revision was automatically updated to reflect the committed changes. Closed by commit rHG526750cdd02d: bookmarks: keep bookmarks in .hg/store if new config set (authored by martinvonz, committed by ).
REPOSITORY rHG Mercurial CHANGES SINCE LAST UPDATE https://phab.mercurial-scm.org/D6387?vs=15131&id=15166 REVISION DETAIL https://phab.mercurial-scm.org/D6387 AFFECTED FILES hgext/share.py mercurial/bookmarks.py mercurial/configitems.py mercurial/help/config.txt mercurial/localrepo.py mercurial/store.py tests/test-help.t tests/test-share-bookmarks.t CHANGE DETAILS diff --git a/tests/test-share-bookmarks.t b/tests/test-share-bookmarks.t --- a/tests/test-share-bookmarks.t +++ b/tests/test-share-bookmarks.t @@ -1,6 +1,13 @@ +#testcases vfs svfs + $ echo "[extensions]" >> $HGRCPATH $ echo "share = " >> $HGRCPATH +#if svfs + $ echo "[format]" >> $HGRCPATH + $ echo "bookmarks-in-store = yes " >> $HGRCPATH +#endif + prepare repo1 $ hg init repo1 @@ -33,17 +40,21 @@ $ cd ../repo2 $ hg book bm2 $ hg bookmarks + bm1 2:c2e0ac586386 (svfs !) * bm2 2:c2e0ac586386 $ cd ../repo3 $ hg bookmarks bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) $ hg book bm3 $ hg bookmarks bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) * bm3 2:c2e0ac586386 $ cd ../repo1 $ hg bookmarks * bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) bm3 2:c2e0ac586386 check whether HG_PENDING makes pending changes only in relatd @@ -70,14 +81,18 @@ $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX @repo1 bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) bm3 2:c2e0ac586386 * bmX 2:c2e0ac586386 @repo2 + bm1 2:c2e0ac586386 (svfs !) * bm2 2:c2e0ac586386 + bm3 2:c2e0ac586386 (svfs !) @repo3 bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) * bm3 2:c2e0ac586386 - bmX 2:c2e0ac586386 + bmX 2:c2e0ac586386 (vfs !) transaction abort! rollback completed abort: pretxnclose hook exited with status 1 @@ -92,19 +107,28 @@ $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX @repo1 * bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) bm3 2:c2e0ac586386 @repo2 + bm1 2:c2e0ac586386 (svfs !) * bm2 2:c2e0ac586386 + bm3 2:c2e0ac586386 (svfs !) @repo3 bm1 2:c2e0ac586386 + bm2 2:c2e0ac586386 (svfs !) bm3 2:c2e0ac586386 * bmX 2:c2e0ac586386 transaction abort! rollback completed abort: pretxnclose hook exited with status 1 [255] $ hg book bm3 +clean up bm2 since it's uninteresting (not shared in the vfs case and +same as bm3 in the svfs case) + $ cd ../repo2 + $ hg book -d bm2 + $ cd ../repo1 test that commits work diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1513,6 +1513,8 @@ "revlog-compression" + "bookmarks-in-store" + "profiling" ----------- diff --git a/mercurial/store.py b/mercurial/store.py --- a/mercurial/store.py +++ b/mercurial/store.py @@ -337,7 +337,7 @@ mode = None return mode -_data = ('narrowspec data meta 00manifest.d 00manifest.i' +_data = ('bookmarks narrowspec data meta 00manifest.d 00manifest.i' ' 00changelog.d 00changelog.i phaseroots obsstore') def isrevlog(f, kind, st): @@ -612,7 +612,7 @@ raise def copylist(self): - d = ('narrowspec data meta dh fncache phaseroots obsstore' + d = ('bookmarks narrowspec data meta dh fncache phaseroots obsstore' ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i') return (['requires', '00changelog.i'] + ['store/' + f for f in d.split()]) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -122,6 +122,25 @@ def join(self, obj, fname): return obj.sjoin(fname) +class mixedrepostorecache(_basefilecache): + """filecache for a mix files in .hg/store and outside""" + def __init__(self, *pathsandlocations): + # scmutil.filecache only uses the path for passing back into our + # join(), so we can safely pass a list of paths and locations + super(mixedrepostorecache, self).__init__(*pathsandlocations) + for path, location in pathsandlocations: + _cachedfiles.update(pathsandlocations) + + def join(self, obj, fnameandlocation): + fname, location = fnameandlocation + if location == '': + return obj.vfs.join(fname) + else: + if location != 'store': + raise error.ProgrammingError('unexpected location: %s' % + location) + return obj.sjoin(fname) + def isfilecached(repo, name): """check if a repo has already cached "name" filecache-ed property @@ -891,6 +910,7 @@ 'treemanifest', REVLOGV2_REQUIREMENT, SPARSEREVLOG_REQUIREMENT, + bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT, } _basesupported = supportedformats | { 'store', @@ -1205,7 +1225,8 @@ cls = repoview.newtype(self.unfiltered().__class__) return cls(self, name, visibilityexceptions) - @repofilecache('bookmarks', 'bookmarks.current') + @mixedrepostorecache(('bookmarks', ''), ('bookmarks.current', ''), + ('bookmarks', 'store')) def _bookmarks(self): return bookmarks.bmstore(self) @@ -1962,7 +1983,7 @@ (self.vfs, 'journal.dirstate'), (self.vfs, 'journal.branch'), (self.vfs, 'journal.desc'), - (self.vfs, 'journal.bookmarks'), + (bookmarks.bookmarksvfs(self), 'journal.bookmarks'), (self.svfs, 'journal.phaseroots')) def undofiles(self): @@ -1977,8 +1998,9 @@ encoding.fromlocal(self.dirstate.branch())) self.vfs.write("journal.desc", "%d\n%s\n" % (len(self), desc)) - self.vfs.write("journal.bookmarks", - self.vfs.tryread("bookmarks")) + bookmarksvfs = bookmarks.bookmarksvfs(self) + bookmarksvfs.write("journal.bookmarks", + bookmarksvfs.tryread("bookmarks")) self.svfs.write("journal.phaseroots", self.svfs.tryread("phaseroots")) @@ -2048,8 +2070,9 @@ vfsmap = {'plain': self.vfs, '': self.svfs} transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn, checkambigfiles=_cachedfiles) - if self.vfs.exists('undo.bookmarks'): - self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True) + bookmarksvfs = bookmarks.bookmarksvfs(self) + if bookmarksvfs.exists('undo.bookmarks'): + bookmarksvfs.rename('undo.bookmarks', 'bookmarks', checkambig=True) if self.svfs.exists('undo.phaseroots'): self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True) self.invalidate() @@ -3003,6 +3026,9 @@ if createopts.get('lfs'): requirements.add('lfs') + if ui.configbool('format', 'bookmarks-in-store'): + requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT) + return requirements def filterknowncreateopts(ui, createopts): diff --git a/mercurial/help/config.txt b/mercurial/help/config.txt --- a/mercurial/help/config.txt +++ b/mercurial/help/config.txt @@ -879,6 +879,15 @@ On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`. +``bookmarks-in-store`` + Store bookmarks in .hg/store/. This means that bookmarks are shared when + using `hg share` regardless of the `-B` option. + + Repositories with this on-disk format require Mercurial version 5.1. + + Disabled by default. + + ``graph`` --------- diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -676,6 +676,9 @@ default=None, generic=True, ) +coreconfigitem('format', 'bookmarks-in-store', + default=False, +) coreconfigitem('format', 'chunkcachesize', default=None, ) diff --git a/mercurial/bookmarks.py b/mercurial/bookmarks.py --- a/mercurial/bookmarks.py +++ b/mercurial/bookmarks.py @@ -33,14 +33,22 @@ # custom styles activebookmarklabel = 'bookmarks.active bookmarks.current' +BOOKMARKS_IN_STORE_REQUIREMENT = 'bookmarksinstore' + +def bookmarksinstore(repo): + return BOOKMARKS_IN_STORE_REQUIREMENT in repo.requirements + +def bookmarksvfs(repo): + return repo.svfs if bookmarksinstore(repo) else repo.vfs + def _getbkfile(repo): """Hook so that extensions that mess with the store can hook bm storage. For core, this just handles wether we should see pending bookmarks or the committed ones. Other extensions (like share) may need to tweak this behavior further. """ - fp, pending = txnutil.trypending(repo.root, repo.vfs, 'bookmarks') + fp, pending = txnutil.trypending(repo.root, bookmarksvfs(repo), 'bookmarks') return fp class bmstore(object): @@ -91,8 +99,11 @@ # ValueError: # - node in nm, for non-20-bytes entry # - split(...), for string without ' ' - repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') - % pycompat.bytestr(line)) + bookmarkspath = '.hg/bookmarks' + if bookmarksinstore(repo): + bookmarkspath = '.hg/store/bookmarks' + repo.ui.warn(_('malformed line in %s: %r\n') + % (bookmarkspath, pycompat.bytestr(line))) except IOError as inst: if inst.errno != errno.ENOENT: raise @@ -192,8 +203,9 @@ """record that bookmarks have been changed in a transaction The transaction is then responsible for updating the file content.""" + location = '' if bookmarksinstore(self._repo) else 'plain' tr.addfilegenerator('bookmarks', ('bookmarks',), self._write, - location='plain') + location=location) tr.hookargs['bookmark_moved'] = '1' def _writerepo(self, repo): @@ -203,9 +215,14 @@ rbm.active = None rbm._writeactive() - with repo.wlock(): - with repo.vfs('bookmarks', 'w', atomictemp=True, - checkambig=True) as f: + if bookmarksinstore(repo): + vfs = repo.svfs + lock = repo.lock() + else: + vfs = repo.vfs + lock = repo.wlock() + with lock: + with vfs('bookmarks', 'w', atomictemp=True, checkambig=True) as f: self._write(f) def _writeactive(self): @@ -428,7 +445,11 @@ return d def pushbookmark(repo, key, old, new): - with repo.wlock(), repo.lock(), repo.transaction('bookmarks') as tr: + if bookmarksinstore(repo): + wlock = util.nullcontextmanager() + else: + wlock = repo.wlock() + with wlock, repo.lock(), repo.transaction('bookmarks') as tr: marks = repo._bookmarks existing = hex(marks.get(key, '')) if existing != old and existing != new: diff --git a/hgext/share.py b/hgext/share.py --- a/hgext/share.py +++ b/hgext/share.py @@ -125,6 +125,10 @@ def _hassharedbookmarks(repo): """Returns whether this repo has shared bookmarks""" + if bookmarks.bookmarksinstore(repo): + # Kind of a lie, but it means that we skip our custom reads and writes + # from/to the source repo. + return False try: shared = repo.vfs.read('shared').splitlines() except IOError as inst: To: martinvonz, #hg-reviewers Cc: mjpieters, mercurial-devel _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel