##// END OF EJS Templates
bookmarks: keep bookmarks in .hg/store if new config set...
Martin von Zweigbergk -
r42512:526750cd default
parent child Browse files
Show More
@@ -125,6 +125,10 b' def extsetup(ui):'
125
125
126 def _hassharedbookmarks(repo):
126 def _hassharedbookmarks(repo):
127 """Returns whether this repo has shared bookmarks"""
127 """Returns whether this repo has shared bookmarks"""
128 if bookmarks.bookmarksinstore(repo):
129 # Kind of a lie, but it means that we skip our custom reads and writes
130 # from/to the source repo.
131 return False
128 try:
132 try:
129 shared = repo.vfs.read('shared').splitlines()
133 shared = repo.vfs.read('shared').splitlines()
130 except IOError as inst:
134 except IOError as inst:
@@ -33,6 +33,14 b' from . import ('
33 # custom styles
33 # custom styles
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
34 activebookmarklabel = 'bookmarks.active bookmarks.current'
35
35
36 BOOKMARKS_IN_STORE_REQUIREMENT = 'bookmarksinstore'
37
38 def bookmarksinstore(repo):
39 return BOOKMARKS_IN_STORE_REQUIREMENT in repo.requirements
40
41 def bookmarksvfs(repo):
42 return repo.svfs if bookmarksinstore(repo) else repo.vfs
43
36 def _getbkfile(repo):
44 def _getbkfile(repo):
37 """Hook so that extensions that mess with the store can hook bm storage.
45 """Hook so that extensions that mess with the store can hook bm storage.
38
46
@@ -40,7 +48,7 b' def _getbkfile(repo):'
40 bookmarks or the committed ones. Other extensions (like share)
48 bookmarks or the committed ones. Other extensions (like share)
41 may need to tweak this behavior further.
49 may need to tweak this behavior further.
42 """
50 """
43 fp, pending = txnutil.trypending(repo.root, repo.vfs, 'bookmarks')
51 fp, pending = txnutil.trypending(repo.root, bookmarksvfs(repo), 'bookmarks')
44 return fp
52 return fp
45
53
46 class bmstore(object):
54 class bmstore(object):
@@ -91,8 +99,11 b' class bmstore(object):'
91 # ValueError:
99 # ValueError:
92 # - node in nm, for non-20-bytes entry
100 # - node in nm, for non-20-bytes entry
93 # - split(...), for string without ' '
101 # - split(...), for string without ' '
94 repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n')
102 bookmarkspath = '.hg/bookmarks'
95 % pycompat.bytestr(line))
103 if bookmarksinstore(repo):
104 bookmarkspath = '.hg/store/bookmarks'
105 repo.ui.warn(_('malformed line in %s: %r\n')
106 % (bookmarkspath, pycompat.bytestr(line)))
96 except IOError as inst:
107 except IOError as inst:
97 if inst.errno != errno.ENOENT:
108 if inst.errno != errno.ENOENT:
98 raise
109 raise
@@ -192,8 +203,9 b' class bmstore(object):'
192 """record that bookmarks have been changed in a transaction
203 """record that bookmarks have been changed in a transaction
193
204
194 The transaction is then responsible for updating the file content."""
205 The transaction is then responsible for updating the file content."""
206 location = '' if bookmarksinstore(self._repo) else 'plain'
195 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
207 tr.addfilegenerator('bookmarks', ('bookmarks',), self._write,
196 location='plain')
208 location=location)
197 tr.hookargs['bookmark_moved'] = '1'
209 tr.hookargs['bookmark_moved'] = '1'
198
210
199 def _writerepo(self, repo):
211 def _writerepo(self, repo):
@@ -203,9 +215,14 b' class bmstore(object):'
203 rbm.active = None
215 rbm.active = None
204 rbm._writeactive()
216 rbm._writeactive()
205
217
206 with repo.wlock():
218 if bookmarksinstore(repo):
207 with repo.vfs('bookmarks', 'w', atomictemp=True,
219 vfs = repo.svfs
208 checkambig=True) as f:
220 lock = repo.lock()
221 else:
222 vfs = repo.vfs
223 lock = repo.wlock()
224 with lock:
225 with vfs('bookmarks', 'w', atomictemp=True, checkambig=True) as f:
209 self._write(f)
226 self._write(f)
210
227
211 def _writeactive(self):
228 def _writeactive(self):
@@ -428,7 +445,11 b' def listbookmarks(repo):'
428 return d
445 return d
429
446
430 def pushbookmark(repo, key, old, new):
447 def pushbookmark(repo, key, old, new):
431 with repo.wlock(), repo.lock(), repo.transaction('bookmarks') as tr:
448 if bookmarksinstore(repo):
449 wlock = util.nullcontextmanager()
450 else:
451 wlock = repo.wlock()
452 with wlock, repo.lock(), repo.transaction('bookmarks') as tr:
432 marks = repo._bookmarks
453 marks = repo._bookmarks
433 existing = hex(marks.get(key, ''))
454 existing = hex(marks.get(key, ''))
434 if existing != old and existing != new:
455 if existing != old and existing != new:
@@ -676,6 +676,9 b" coreconfigitem('extdata', '.*',"
676 default=None,
676 default=None,
677 generic=True,
677 generic=True,
678 )
678 )
679 coreconfigitem('format', 'bookmarks-in-store',
680 default=False,
681 )
679 coreconfigitem('format', 'chunkcachesize',
682 coreconfigitem('format', 'chunkcachesize',
680 default=None,
683 default=None,
681 )
684 )
@@ -879,6 +879,15 b' https://www.mercurial-scm.org/wiki/Missi'
879
879
880 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
880 On some system, Mercurial installation may lack `zstd` supports. Default is `zlib`.
881
881
882 ``bookmarks-in-store``
883 Store bookmarks in .hg/store/. This means that bookmarks are shared when
884 using `hg share` regardless of the `-B` option.
885
886 Repositories with this on-disk format require Mercurial version 5.1.
887
888 Disabled by default.
889
890
882 ``graph``
891 ``graph``
883 ---------
892 ---------
884
893
@@ -122,6 +122,25 b' class storecache(_basefilecache):'
122 def join(self, obj, fname):
122 def join(self, obj, fname):
123 return obj.sjoin(fname)
123 return obj.sjoin(fname)
124
124
125 class mixedrepostorecache(_basefilecache):
126 """filecache for a mix files in .hg/store and outside"""
127 def __init__(self, *pathsandlocations):
128 # scmutil.filecache only uses the path for passing back into our
129 # join(), so we can safely pass a list of paths and locations
130 super(mixedrepostorecache, self).__init__(*pathsandlocations)
131 for path, location in pathsandlocations:
132 _cachedfiles.update(pathsandlocations)
133
134 def join(self, obj, fnameandlocation):
135 fname, location = fnameandlocation
136 if location == '':
137 return obj.vfs.join(fname)
138 else:
139 if location != 'store':
140 raise error.ProgrammingError('unexpected location: %s' %
141 location)
142 return obj.sjoin(fname)
143
125 def isfilecached(repo, name):
144 def isfilecached(repo, name):
126 """check if a repo has already cached "name" filecache-ed property
145 """check if a repo has already cached "name" filecache-ed property
127
146
@@ -891,6 +910,7 b' class localrepository(object):'
891 'treemanifest',
910 'treemanifest',
892 REVLOGV2_REQUIREMENT,
911 REVLOGV2_REQUIREMENT,
893 SPARSEREVLOG_REQUIREMENT,
912 SPARSEREVLOG_REQUIREMENT,
913 bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT,
894 }
914 }
895 _basesupported = supportedformats | {
915 _basesupported = supportedformats | {
896 'store',
916 'store',
@@ -1205,7 +1225,8 b' class localrepository(object):'
1205 cls = repoview.newtype(self.unfiltered().__class__)
1225 cls = repoview.newtype(self.unfiltered().__class__)
1206 return cls(self, name, visibilityexceptions)
1226 return cls(self, name, visibilityexceptions)
1207
1227
1208 @repofilecache('bookmarks', 'bookmarks.current')
1228 @mixedrepostorecache(('bookmarks', ''), ('bookmarks.current', ''),
1229 ('bookmarks', 'store'))
1209 def _bookmarks(self):
1230 def _bookmarks(self):
1210 return bookmarks.bmstore(self)
1231 return bookmarks.bmstore(self)
1211
1232
@@ -1962,7 +1983,7 b' class localrepository(object):'
1962 (self.vfs, 'journal.dirstate'),
1983 (self.vfs, 'journal.dirstate'),
1963 (self.vfs, 'journal.branch'),
1984 (self.vfs, 'journal.branch'),
1964 (self.vfs, 'journal.desc'),
1985 (self.vfs, 'journal.desc'),
1965 (self.vfs, 'journal.bookmarks'),
1986 (bookmarks.bookmarksvfs(self), 'journal.bookmarks'),
1966 (self.svfs, 'journal.phaseroots'))
1987 (self.svfs, 'journal.phaseroots'))
1967
1988
1968 def undofiles(self):
1989 def undofiles(self):
@@ -1977,8 +1998,9 b' class localrepository(object):'
1977 encoding.fromlocal(self.dirstate.branch()))
1998 encoding.fromlocal(self.dirstate.branch()))
1978 self.vfs.write("journal.desc",
1999 self.vfs.write("journal.desc",
1979 "%d\n%s\n" % (len(self), desc))
2000 "%d\n%s\n" % (len(self), desc))
1980 self.vfs.write("journal.bookmarks",
2001 bookmarksvfs = bookmarks.bookmarksvfs(self)
1981 self.vfs.tryread("bookmarks"))
2002 bookmarksvfs.write("journal.bookmarks",
2003 bookmarksvfs.tryread("bookmarks"))
1982 self.svfs.write("journal.phaseroots",
2004 self.svfs.write("journal.phaseroots",
1983 self.svfs.tryread("phaseroots"))
2005 self.svfs.tryread("phaseroots"))
1984
2006
@@ -2048,8 +2070,9 b' class localrepository(object):'
2048 vfsmap = {'plain': self.vfs, '': self.svfs}
2070 vfsmap = {'plain': self.vfs, '': self.svfs}
2049 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2071 transaction.rollback(self.svfs, vfsmap, 'undo', ui.warn,
2050 checkambigfiles=_cachedfiles)
2072 checkambigfiles=_cachedfiles)
2051 if self.vfs.exists('undo.bookmarks'):
2073 bookmarksvfs = bookmarks.bookmarksvfs(self)
2052 self.vfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2074 if bookmarksvfs.exists('undo.bookmarks'):
2075 bookmarksvfs.rename('undo.bookmarks', 'bookmarks', checkambig=True)
2053 if self.svfs.exists('undo.phaseroots'):
2076 if self.svfs.exists('undo.phaseroots'):
2054 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2077 self.svfs.rename('undo.phaseroots', 'phaseroots', checkambig=True)
2055 self.invalidate()
2078 self.invalidate()
@@ -3003,6 +3026,9 b' def newreporequirements(ui, createopts):'
3003 if createopts.get('lfs'):
3026 if createopts.get('lfs'):
3004 requirements.add('lfs')
3027 requirements.add('lfs')
3005
3028
3029 if ui.configbool('format', 'bookmarks-in-store'):
3030 requirements.add(bookmarks.BOOKMARKS_IN_STORE_REQUIREMENT)
3031
3006 return requirements
3032 return requirements
3007
3033
3008 def filterknowncreateopts(ui, createopts):
3034 def filterknowncreateopts(ui, createopts):
@@ -337,7 +337,7 b' def _calcmode(vfs):'
337 mode = None
337 mode = None
338 return mode
338 return mode
339
339
340 _data = ('narrowspec data meta 00manifest.d 00manifest.i'
340 _data = ('bookmarks narrowspec data meta 00manifest.d 00manifest.i'
341 ' 00changelog.d 00changelog.i phaseroots obsstore')
341 ' 00changelog.d 00changelog.i phaseroots obsstore')
342
342
343 def isrevlog(f, kind, st):
343 def isrevlog(f, kind, st):
@@ -612,7 +612,7 b' class fncachestore(basicstore):'
612 raise
612 raise
613
613
614 def copylist(self):
614 def copylist(self):
615 d = ('narrowspec data meta dh fncache phaseroots obsstore'
615 d = ('bookmarks narrowspec data meta dh fncache phaseroots obsstore'
616 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
616 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
617 return (['requires', '00changelog.i'] +
617 return (['requires', '00changelog.i'] +
618 ['store/' + f for f in d.split()])
618 ['store/' + f for f in d.split()])
@@ -1513,6 +1513,8 b' Separate sections from subsections'
1513
1513
1514 "revlog-compression"
1514 "revlog-compression"
1515
1515
1516 "bookmarks-in-store"
1517
1516 "profiling"
1518 "profiling"
1517 -----------
1519 -----------
1518
1520
@@ -1,6 +1,13 b''
1 #testcases vfs svfs
2
1 $ echo "[extensions]" >> $HGRCPATH
3 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "share = " >> $HGRCPATH
4 $ echo "share = " >> $HGRCPATH
3
5
6 #if svfs
7 $ echo "[format]" >> $HGRCPATH
8 $ echo "bookmarks-in-store = yes " >> $HGRCPATH
9 #endif
10
4 prepare repo1
11 prepare repo1
5
12
6 $ hg init repo1
13 $ hg init repo1
@@ -33,17 +40,21 b' test sharing bookmarks'
33 $ cd ../repo2
40 $ cd ../repo2
34 $ hg book bm2
41 $ hg book bm2
35 $ hg bookmarks
42 $ hg bookmarks
43 bm1 2:c2e0ac586386 (svfs !)
36 * bm2 2:c2e0ac586386
44 * bm2 2:c2e0ac586386
37 $ cd ../repo3
45 $ cd ../repo3
38 $ hg bookmarks
46 $ hg bookmarks
39 bm1 2:c2e0ac586386
47 bm1 2:c2e0ac586386
48 bm2 2:c2e0ac586386 (svfs !)
40 $ hg book bm3
49 $ hg book bm3
41 $ hg bookmarks
50 $ hg bookmarks
42 bm1 2:c2e0ac586386
51 bm1 2:c2e0ac586386
52 bm2 2:c2e0ac586386 (svfs !)
43 * bm3 2:c2e0ac586386
53 * bm3 2:c2e0ac586386
44 $ cd ../repo1
54 $ cd ../repo1
45 $ hg bookmarks
55 $ hg bookmarks
46 * bm1 2:c2e0ac586386
56 * bm1 2:c2e0ac586386
57 bm2 2:c2e0ac586386 (svfs !)
47 bm3 2:c2e0ac586386
58 bm3 2:c2e0ac586386
48
59
49 check whether HG_PENDING makes pending changes only in relatd
60 check whether HG_PENDING makes pending changes only in relatd
@@ -70,14 +81,18 b' Therefore, this test scenario ignores ch'
70 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
81 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
71 @repo1
82 @repo1
72 bm1 2:c2e0ac586386
83 bm1 2:c2e0ac586386
84 bm2 2:c2e0ac586386 (svfs !)
73 bm3 2:c2e0ac586386
85 bm3 2:c2e0ac586386
74 * bmX 2:c2e0ac586386
86 * bmX 2:c2e0ac586386
75 @repo2
87 @repo2
88 bm1 2:c2e0ac586386 (svfs !)
76 * bm2 2:c2e0ac586386
89 * bm2 2:c2e0ac586386
90 bm3 2:c2e0ac586386 (svfs !)
77 @repo3
91 @repo3
78 bm1 2:c2e0ac586386
92 bm1 2:c2e0ac586386
93 bm2 2:c2e0ac586386 (svfs !)
79 * bm3 2:c2e0ac586386
94 * bm3 2:c2e0ac586386
80 bmX 2:c2e0ac586386
95 bmX 2:c2e0ac586386 (vfs !)
81 transaction abort!
96 transaction abort!
82 rollback completed
97 rollback completed
83 abort: pretxnclose hook exited with status 1
98 abort: pretxnclose hook exited with status 1
@@ -92,11 +107,15 b' src), because (1) HG_PENDING refers only'
92 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
107 $ hg --config hooks.pretxnclose="sh $TESTTMP/checkbookmarks.sh" -q book bmX
93 @repo1
108 @repo1
94 * bm1 2:c2e0ac586386
109 * bm1 2:c2e0ac586386
110 bm2 2:c2e0ac586386 (svfs !)
95 bm3 2:c2e0ac586386
111 bm3 2:c2e0ac586386
96 @repo2
112 @repo2
113 bm1 2:c2e0ac586386 (svfs !)
97 * bm2 2:c2e0ac586386
114 * bm2 2:c2e0ac586386
115 bm3 2:c2e0ac586386 (svfs !)
98 @repo3
116 @repo3
99 bm1 2:c2e0ac586386
117 bm1 2:c2e0ac586386
118 bm2 2:c2e0ac586386 (svfs !)
100 bm3 2:c2e0ac586386
119 bm3 2:c2e0ac586386
101 * bmX 2:c2e0ac586386
120 * bmX 2:c2e0ac586386
102 transaction abort!
121 transaction abort!
@@ -105,6 +124,11 b' src), because (1) HG_PENDING refers only'
105 [255]
124 [255]
106 $ hg book bm3
125 $ hg book bm3
107
126
127 clean up bm2 since it's uninteresting (not shared in the vfs case and
128 same as bm3 in the svfs case)
129 $ cd ../repo2
130 $ hg book -d bm2
131
108 $ cd ../repo1
132 $ cd ../repo1
109
133
110 test that commits work
134 test that commits work
General Comments 0
You need to be logged in to leave comments. Login now