##// END OF EJS Templates
bmstore: add handling of the active bookmark...
Augie Fackler -
r27698:dad6404c default
parent child Browse files
Show More
@@ -44,16 +44,15 b' def _getbkfile(repo):'
44 class bmstore(dict):
44 class bmstore(dict):
45 """Storage for bookmarks.
45 """Storage for bookmarks.
46
46
47 This object should do all bookmark reads and writes, so that it's
47 This object should do all bookmark-related reads and writes, so
48 fairly simple to replace the storage underlying bookmarks without
48 that it's fairly simple to replace the storage underlying
49 having to clone the logic surrounding bookmarks.
49 bookmarks without having to clone the logic surrounding
50 bookmarks. This type also should manage the active bookmark, if
51 any.
50
52
51 This particular bmstore implementation stores bookmarks as
53 This particular bmstore implementation stores bookmarks as
52 {hash}\s{name}\n (the same format as localtags) in
54 {hash}\s{name}\n (the same format as localtags) in
53 .hg/bookmarks. The mapping is stored as {name: nodeid}.
55 .hg/bookmarks. The mapping is stored as {name: nodeid}.
54
55 This class does NOT handle the "active" bookmark state at this
56 time.
57 """
56 """
58
57
59 def __init__(self, repo):
58 def __init__(self, repo):
@@ -79,6 +78,20 b' class bmstore(dict):'
79 if inst.errno != errno.ENOENT:
78 if inst.errno != errno.ENOENT:
80 raise
79 raise
81 self._clean = True
80 self._clean = True
81 self._active = _readactive(repo, self)
82 self._aclean = True
83
84 @property
85 def active(self):
86 return self._active
87
88 @active.setter
89 def active(self, mark):
90 if mark is not None and mark not in self:
91 raise AssertionError('bookmark %s does not exist!' % mark)
92
93 self._active = mark
94 self._aclean = False
82
95
83 def __setitem__(self, *args, **kwargs):
96 def __setitem__(self, *args, **kwargs):
84 self._clean = False
97 self._clean = False
@@ -107,6 +120,9 b' class bmstore(dict):'
107 '''
120 '''
108 msg = 'bm.write() is deprecated, use bm.recordchange(transaction)'
121 msg = 'bm.write() is deprecated, use bm.recordchange(transaction)'
109 self._repo.ui.deprecwarn(msg, '3.7')
122 self._repo.ui.deprecwarn(msg, '3.7')
123 # TODO: writing the active bookmark should probably also use a
124 # transaction.
125 self._writeactive()
110 if self._clean:
126 if self._clean:
111 return
127 return
112 repo = self._repo
128 repo = self._repo
@@ -128,8 +144,10 b' class bmstore(dict):'
128
144
129 def _writerepo(self, repo):
145 def _writerepo(self, repo):
130 """Factored out for extensibility"""
146 """Factored out for extensibility"""
131 if repo._activebookmark not in self:
147 rbm = repo._bookmarks
132 deactivate(repo)
148 if rbm.active not in self:
149 rbm.active = None
150 rbm._writeactive()
133
151
134 wlock = repo.wlock()
152 wlock = repo.wlock()
135 try:
153 try:
@@ -146,12 +164,33 b' class bmstore(dict):'
146 finally:
164 finally:
147 wlock.release()
165 wlock.release()
148
166
167 def _writeactive(self):
168 if self._aclean:
169 return
170 wlock = self._repo.wlock()
171 try:
172 if self._active is not None:
173 f = self._repo.vfs('bookmarks.current', 'w', atomictemp=True)
174 try:
175 f.write(encoding.fromlocal(self._active))
176 finally:
177 f.close()
178 else:
179 try:
180 self._repo.vfs.unlink('bookmarks.current')
181 except OSError as inst:
182 if inst.errno != errno.ENOENT:
183 raise
184 finally:
185 wlock.release()
186 self._aclean = True
187
149 def _write(self, fp):
188 def _write(self, fp):
150 for name, node in self.iteritems():
189 for name, node in self.iteritems():
151 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
190 fp.write("%s %s\n" % (hex(node), encoding.fromlocal(name)))
152 self._clean = True
191 self._clean = True
153
192
154 def readactive(repo):
193 def _readactive(repo, marks):
155 """
194 """
156 Get the active bookmark. We can have an active bookmark that updates
195 Get the active bookmark. We can have an active bookmark that updates
157 itself as we commit. This function returns the name of that bookmark.
196 itself as we commit. This function returns the name of that bookmark.
@@ -172,7 +211,7 b' def readactive(repo):'
172 # static-http which only tries to load the file when we try
211 # static-http which only tries to load the file when we try
173 # to read from it.
212 # to read from it.
174 mark = encoding.tolocal((file.readlines() or [''])[0])
213 mark = encoding.tolocal((file.readlines() or [''])[0])
175 if mark == '' or mark not in repo._bookmarks:
214 if mark == '' or mark not in marks:
176 mark = None
215 mark = None
177 except IOError as inst:
216 except IOError as inst:
178 if inst.errno != errno.ENOENT:
217 if inst.errno != errno.ENOENT:
@@ -188,35 +227,15 b' def activate(repo, mark):'
188 follow new commits that are made.
227 follow new commits that are made.
189 The name is recorded in .hg/bookmarks.current
228 The name is recorded in .hg/bookmarks.current
190 """
229 """
191 if mark not in repo._bookmarks:
230 repo._bookmarks.active = mark
192 raise AssertionError('bookmark %s does not exist!' % mark)
231 repo._bookmarks._writeactive()
193
194 active = repo._activebookmark
195 if active == mark:
196 return
197
198 wlock = repo.wlock()
199 try:
200 file = repo.vfs('bookmarks.current', 'w', atomictemp=True)
201 file.write(encoding.fromlocal(mark))
202 file.close()
203 finally:
204 wlock.release()
205 repo._activebookmark = mark
206
232
207 def deactivate(repo):
233 def deactivate(repo):
208 """
234 """
209 Unset the active bookmark in this repository.
235 Unset the active bookmark in this repository.
210 """
236 """
211 wlock = repo.wlock()
237 repo._bookmarks.active = None
212 try:
238 repo._bookmarks._writeactive()
213 repo.vfs.unlink('bookmarks.current')
214 repo._activebookmark = None
215 except OSError as inst:
216 if inst.errno != errno.ENOENT:
217 raise
218 finally:
219 wlock.release()
220
239
221 def isactivewdirparent(repo):
240 def isactivewdirparent(repo):
222 """
241 """
@@ -266,7 +285,7 b' def update(repo, parents, node):'
266 deletefrom = parents
285 deletefrom = parents
267 marks = repo._bookmarks
286 marks = repo._bookmarks
268 update = False
287 update = False
269 active = repo._activebookmark
288 active = marks.active
270 if not active:
289 if not active:
271 return False
290 return False
272
291
@@ -2530,13 +2530,14 b' def amend(ui, repo, commitfunc, old, ext'
2530 # First, do a regular commit to record all changes in the working
2530 # First, do a regular commit to record all changes in the working
2531 # directory (if there are any)
2531 # directory (if there are any)
2532 ui.callhooks = False
2532 ui.callhooks = False
2533 activebookmark = repo._activebookmark
2533 activebookmark = repo._bookmarks.active
2534 try:
2534 try:
2535 repo._activebookmark = None
2535 repo._bookmarks.active = None
2536 opts['message'] = 'temporary amend commit for %s' % old
2536 opts['message'] = 'temporary amend commit for %s' % old
2537 node = commit(ui, repo, commitfunc, pats, opts)
2537 node = commit(ui, repo, commitfunc, pats, opts)
2538 finally:
2538 finally:
2539 repo._activebookmark = activebookmark
2539 repo._bookmarks.active = activebookmark
2540 repo._bookmarks.recordchange(tr)
2540 ui.callhooks = True
2541 ui.callhooks = True
2541 ctx = repo[node]
2542 ctx = repo[node]
2542
2543
@@ -459,13 +459,13 b' class localrepository(object):'
459 pass
459 pass
460 return proxycls(self, name)
460 return proxycls(self, name)
461
461
462 @repofilecache('bookmarks')
462 @repofilecache('bookmarks', 'bookmarks.current')
463 def _bookmarks(self):
463 def _bookmarks(self):
464 return bookmarks.bmstore(self)
464 return bookmarks.bmstore(self)
465
465
466 @repofilecache('bookmarks.current')
466 @property
467 def _activebookmark(self):
467 def _activebookmark(self):
468 return bookmarks.readactive(self)
468 return self._bookmarks.active
469
469
470 def bookmarkheads(self, bookmark):
470 def bookmarkheads(self, bookmark):
471 name = bookmark.split('@', 1)[0]
471 name = bookmark.split('@', 1)[0]
General Comments 0
You need to be logged in to leave comments. Login now