Show More
@@ -219,9 +219,10 b' class mercurial_sink(converter_sink):' | |||
|
219 | 219 | return |
|
220 | 220 | |
|
221 | 221 | self.ui.status(_("updating bookmarks\n")) |
|
222 | destmarks = self.repo._bookmarks | |
|
222 | 223 | for bookmark in updatedbookmark: |
|
223 |
|
|
|
224 |
|
|
|
224 | destmarks[bookmark] = bin(updatedbookmark[bookmark]) | |
|
225 | destmarks.write() | |
|
225 | 226 | |
|
226 | 227 | def hascommit(self, rev): |
|
227 | 228 | if rev not in self.repo and self.clonebranches: |
@@ -144,7 +144,6 b' except ImportError:' | |||
|
144 | 144 | import pickle |
|
145 | 145 | import os |
|
146 | 146 | |
|
147 | from mercurial import bookmarks | |
|
148 | 147 | from mercurial import cmdutil |
|
149 | 148 | from mercurial import discovery |
|
150 | 149 | from mercurial import error |
@@ -740,12 +739,13 b' def movebookmarks(ui, repo, mapping, old' | |||
|
740 | 739 | # nothing to move |
|
741 | 740 | moves.append((bk, new[-1])) |
|
742 | 741 | if moves: |
|
742 | marks = repo._bookmarks | |
|
743 | 743 | for mark, new in moves: |
|
744 |
old = |
|
|
744 | old = marks[mark] | |
|
745 | 745 | ui.note(_('histedit: moving bookmarks %s from %s to %s\n') |
|
746 | 746 | % (mark, node.short(old), node.short(new))) |
|
747 |
|
|
|
748 |
|
|
|
747 | marks[mark] = new | |
|
748 | marks.write() | |
|
749 | 749 | |
|
750 | 750 | def cleanupnode(ui, repo, name, nodes): |
|
751 | 751 | """strip a group of nodes from the repository |
@@ -63,7 +63,7 b' from mercurial.i18n import _' | |||
|
63 | 63 | from mercurial.node import bin, hex, short, nullid, nullrev |
|
64 | 64 | from mercurial.lock import release |
|
65 | 65 | from mercurial import commands, cmdutil, hg, scmutil, util, revset |
|
66 |
from mercurial import repair, extensions, error, phases |
|
|
66 | from mercurial import repair, extensions, error, phases | |
|
67 | 67 | from mercurial import patch as patchmod |
|
68 | 68 | import os, re, errno, shutil |
|
69 | 69 | |
@@ -1675,9 +1675,10 b' class queue(object):' | |||
|
1675 | 1675 | patchf.write(chunk) |
|
1676 | 1676 | patchf.close() |
|
1677 | 1677 | |
|
1678 | marks = repo._bookmarks | |
|
1678 | 1679 | for bm in bmlist: |
|
1679 |
|
|
|
1680 |
|
|
|
1680 | marks[bm] = n | |
|
1681 | marks.write() | |
|
1681 | 1682 | |
|
1682 | 1683 | self.applied.append(statusentry(n, patchfn)) |
|
1683 | 1684 | except: # re-raises |
@@ -2999,7 +3000,7 b' def strip(ui, repo, *revs, **opts):' | |||
|
2999 | 3000 | revs.update(set(rsrevs)) |
|
3000 | 3001 | if not revs: |
|
3001 | 3002 | del marks[mark] |
|
3002 |
|
|
|
3003 | marks.write() | |
|
3003 | 3004 | ui.write(_("bookmark '%s' deleted\n") % mark) |
|
3004 | 3005 | |
|
3005 | 3006 | if not revs: |
@@ -3049,7 +3050,7 b' def strip(ui, repo, *revs, **opts):' | |||
|
3049 | 3050 | |
|
3050 | 3051 | if opts.get('bookmark'): |
|
3051 | 3052 | del marks[mark] |
|
3052 |
|
|
|
3053 | marks.write() | |
|
3053 | 3054 | ui.write(_("bookmark '%s' deleted\n") % mark) |
|
3054 | 3055 | |
|
3055 | 3056 | repo.mq.strip(repo, revs, backup=backup, update=update, |
@@ -479,13 +479,14 b' def updatemq(repo, state, skipped, **opt' | |||
|
479 | 479 | |
|
480 | 480 | def updatebookmarks(repo, nstate, originalbookmarks, **opts): |
|
481 | 481 | 'Move bookmarks to their correct changesets' |
|
482 | marks = repo._bookmarks | |
|
482 | 483 | for k, v in originalbookmarks.iteritems(): |
|
483 | 484 | if v in nstate: |
|
484 | 485 | if nstate[v] != nullmerge: |
|
485 | 486 | # update the bookmarks for revs that have moved |
|
486 |
|
|
|
487 | marks[k] = nstate[v] | |
|
487 | 488 | |
|
488 |
|
|
|
489 | marks.write() | |
|
489 | 490 | |
|
490 | 491 | def storestatus(repo, originalwd, target, state, collapse, keep, keepbranches, |
|
491 | 492 | external): |
@@ -10,32 +10,72 b' from mercurial.node import hex' | |||
|
10 | 10 | from mercurial import encoding, error, util, obsolete |
|
11 | 11 | import errno, os |
|
12 | 12 | |
|
13 | def read(repo): | |
|
14 | '''Parse .hg/bookmarks file and return a dictionary | |
|
13 | class bmstore(dict): | |
|
14 | """Storage for bookmarks. | |
|
15 | ||
|
16 | This object should do all bookmark reads and writes, so that it's | |
|
17 | fairly simple to replace the storage underlying bookmarks without | |
|
18 | having to clone the logic surrounding bookmarks. | |
|
19 | ||
|
20 | This particular bmstore implementation stores bookmarks as | |
|
21 | {hash}\s{name}\n (the same format as localtags) in | |
|
22 | .hg/bookmarks. The mapping is stored as {name: nodeid}. | |
|
23 | ||
|
24 | This class does NOT handle the "current" bookmark state at this | |
|
25 | time. | |
|
26 | """ | |
|
15 | 27 | |
|
16 | Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values | |
|
17 | in the .hg/bookmarks file. | |
|
18 | Read the file and return a (name=>nodeid) dictionary | |
|
19 | ''' | |
|
20 | bookmarks = {} | |
|
21 | try: | |
|
22 | for line in repo.opener('bookmarks'): | |
|
23 | line = line.strip() | |
|
24 | if not line: | |
|
25 | continue | |
|
26 | if ' ' not in line: | |
|
27 | repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') % line) | |
|
28 | continue | |
|
29 |
|
|
|
30 | refspec = encoding.tolocal(refspec) | |
|
28 | def __init__(self, repo): | |
|
29 | dict.__init__(self) | |
|
30 | self._repo = repo | |
|
31 | try: | |
|
32 | for line in repo.vfs('bookmarks'): | |
|
33 | line = line.strip() | |
|
34 | if not line: | |
|
35 | continue | |
|
36 | if ' ' not in line: | |
|
37 | repo.ui.warn(_('malformed line in .hg/bookmarks: %r\n') | |
|
38 | % line) | |
|
39 | continue | |
|
40 | sha, refspec = line.split(' ', 1) | |
|
41 | refspec = encoding.tolocal(refspec) | |
|
42 | try: | |
|
43 | self[refspec] = repo.changelog.lookup(sha) | |
|
44 | except LookupError: | |
|
45 | pass | |
|
46 | except IOError, inst: | |
|
47 | if inst.errno != errno.ENOENT: | |
|
48 | raise | |
|
49 | ||
|
50 | def write(self): | |
|
51 | '''Write bookmarks | |
|
52 | ||
|
53 | Write the given bookmark => hash dictionary to the .hg/bookmarks file | |
|
54 | in a format equal to those of localtags. | |
|
55 | ||
|
56 | We also store a backup of the previous state in undo.bookmarks that | |
|
57 | can be copied back on rollback. | |
|
58 | ''' | |
|
59 | repo = self._repo | |
|
60 | if repo._bookmarkcurrent not in self: | |
|
61 | setcurrent(repo, None) | |
|
62 | ||
|
63 | wlock = repo.wlock() | |
|
64 | try: | |
|
65 | ||
|
66 | file = repo.vfs('bookmarks', 'w', atomictemp=True) | |
|
67 | for name, node in self.iteritems(): | |
|
68 | file.write("%s %s\n" % (hex(node), encoding.fromlocal(name))) | |
|
69 | file.close() | |
|
70 | ||
|
71 | # touch 00changelog.i so hgweb reloads bookmarks (no lock needed) | |
|
31 | 72 | try: |
|
32 | bookmarks[refspec] = repo.changelog.lookup(sha) | |
|
33 |
except |
|
|
73 | os.utime(repo.sjoin('00changelog.i'), None) | |
|
74 | except OSError: | |
|
34 | 75 | pass |
|
35 | except IOError, inst: | |
|
36 | if inst.errno != errno.ENOENT: | |
|
37 |
ra |
|
|
38 | return bookmarks | |
|
76 | ||
|
77 | finally: | |
|
78 | wlock.release() | |
|
39 | 79 | |
|
40 | 80 | def readcurrent(repo): |
|
41 | 81 | '''Get the current bookmark |
@@ -60,37 +100,6 b' def readcurrent(repo):' | |||
|
60 | 100 | file.close() |
|
61 | 101 | return mark |
|
62 | 102 | |
|
63 | def write(repo): | |
|
64 | '''Write bookmarks | |
|
65 | ||
|
66 | Write the given bookmark => hash dictionary to the .hg/bookmarks file | |
|
67 | in a format equal to those of localtags. | |
|
68 | ||
|
69 | We also store a backup of the previous state in undo.bookmarks that | |
|
70 | can be copied back on rollback. | |
|
71 | ''' | |
|
72 | refs = repo._bookmarks | |
|
73 | ||
|
74 | if repo._bookmarkcurrent not in refs: | |
|
75 | setcurrent(repo, None) | |
|
76 | ||
|
77 | wlock = repo.wlock() | |
|
78 | try: | |
|
79 | ||
|
80 | file = repo.opener('bookmarks', 'w', atomictemp=True) | |
|
81 | for refspec, node in refs.iteritems(): | |
|
82 | file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec))) | |
|
83 | file.close() | |
|
84 | ||
|
85 | # touch 00changelog.i so hgweb reloads bookmarks (no lock needed) | |
|
86 | try: | |
|
87 | os.utime(repo.sjoin('00changelog.i'), None) | |
|
88 | except OSError: | |
|
89 | pass | |
|
90 | ||
|
91 | finally: | |
|
92 | wlock.release() | |
|
93 | ||
|
94 | 103 | def setcurrent(repo, mark): |
|
95 | 104 | '''Set the name of the bookmark that we are currently on |
|
96 | 105 | |
@@ -152,7 +161,7 b' def update(repo, parents, node):' | |||
|
152 | 161 | if mark != cur: |
|
153 | 162 | del marks[mark] |
|
154 | 163 | if update: |
|
155 |
|
|
|
164 | marks.write() | |
|
156 | 165 | return update |
|
157 | 166 | |
|
158 | 167 | def listbookmarks(repo): |
@@ -179,7 +188,7 b' def pushbookmark(repo, key, old, new):' | |||
|
179 | 188 | if new not in repo: |
|
180 | 189 | return False |
|
181 | 190 | marks[key] = repo[new].node() |
|
182 |
write( |
|
|
191 | marks.write() | |
|
183 | 192 | return True |
|
184 | 193 | finally: |
|
185 | 194 | w.release() |
@@ -188,16 +197,17 b' def updatefromremote(ui, repo, remote, p' | |||
|
188 | 197 | ui.debug("checking for updated bookmarks\n") |
|
189 | 198 | rb = remote.listkeys('bookmarks') |
|
190 | 199 | changed = False |
|
200 | localmarks = repo._bookmarks | |
|
191 | 201 | for k in rb.keys(): |
|
192 |
if k in |
|
|
193 |
nr, nl = rb[k], |
|
|
202 | if k in localmarks: | |
|
203 | nr, nl = rb[k], localmarks[k] | |
|
194 | 204 | if nr in repo: |
|
195 | 205 | cr = repo[nr] |
|
196 | 206 | cl = repo[nl] |
|
197 | 207 | if cl.rev() >= cr.rev(): |
|
198 | 208 | continue |
|
199 | 209 | if validdest(repo, cl, cr): |
|
200 |
|
|
|
210 | localmarks[k] = cr.node() | |
|
201 | 211 | changed = True |
|
202 | 212 | ui.status(_("updating bookmark %s\n") % k) |
|
203 | 213 | else: |
@@ -208,7 +218,7 b' def updatefromremote(ui, repo, remote, p' | |||
|
208 | 218 | # find a unique @ suffix |
|
209 | 219 | for x in range(1, 100): |
|
210 | 220 | n = '%s@%d' % (kd, x) |
|
211 |
if n not in |
|
|
221 | if n not in localmarks: | |
|
212 | 222 | break |
|
213 | 223 | # try to use an @pathalias suffix |
|
214 | 224 | # if an @pathalias already exists, we overwrite (update) it |
@@ -216,17 +226,17 b' def updatefromremote(ui, repo, remote, p' | |||
|
216 | 226 | if path == u: |
|
217 | 227 | n = '%s@%s' % (kd, p) |
|
218 | 228 | |
|
219 |
|
|
|
229 | localmarks[n] = cr.node() | |
|
220 | 230 | changed = True |
|
221 | 231 | ui.warn(_("divergent bookmark %s stored as %s\n") % (k, n)) |
|
222 | 232 | elif rb[k] in repo: |
|
223 | 233 | # add remote bookmarks for changes we already have |
|
224 |
|
|
|
234 | localmarks[k] = repo[rb[k]].node() | |
|
225 | 235 | changed = True |
|
226 | 236 | ui.status(_("adding remote bookmark %s\n") % k) |
|
227 | 237 | |
|
228 | 238 | if changed: |
|
229 |
write( |
|
|
239 | localmarks.write() | |
|
230 | 240 | |
|
231 | 241 | def diff(ui, dst, src): |
|
232 | 242 | ui.status(_("searching for changed bookmarks\n")) |
@@ -10,7 +10,7 b' from i18n import _' | |||
|
10 | 10 | import os, sys, errno, re, tempfile |
|
11 | 11 | import util, scmutil, templater, patch, error, templatekw, revlog, copies |
|
12 | 12 | import match as matchmod |
|
13 |
import subrepo, context, repair |
|
|
13 | import subrepo, context, repair, graphmod, revset, phases, obsolete | |
|
14 | 14 | import changelog |
|
15 | 15 | import lock as lockmod |
|
16 | 16 | |
@@ -1756,9 +1756,10 b' def amend(ui, repo, commitfunc, old, ext' | |||
|
1756 | 1756 | # Move bookmarks from old parent to amend commit |
|
1757 | 1757 | bms = repo.nodebookmarks(old.node()) |
|
1758 | 1758 | if bms: |
|
1759 | marks = repo._bookmarks | |
|
1759 | 1760 | for bm in bms: |
|
1760 |
|
|
|
1761 |
|
|
|
1761 | marks[bm] = newid | |
|
1762 | marks.write() | |
|
1762 | 1763 | #commit the whole amend process |
|
1763 | 1764 | if obsolete._enabled and newid != old.node(): |
|
1764 | 1765 | # mark the new changeset as successor of the rewritten one |
@@ -821,7 +821,7 b' def bookmark(ui, repo, mark=None, rev=No' | |||
|
821 | 821 | if mark == repo._bookmarkcurrent: |
|
822 | 822 | bookmarks.setcurrent(repo, None) |
|
823 | 823 | del marks[mark] |
|
824 |
|
|
|
824 | marks.write() | |
|
825 | 825 | |
|
826 | 826 | elif rename: |
|
827 | 827 | if mark is None: |
@@ -834,7 +834,7 b' def bookmark(ui, repo, mark=None, rev=No' | |||
|
834 | 834 | if repo._bookmarkcurrent == rename and not inactive: |
|
835 | 835 | bookmarks.setcurrent(repo, mark) |
|
836 | 836 | del marks[rename] |
|
837 |
|
|
|
837 | marks.write() | |
|
838 | 838 | |
|
839 | 839 | elif mark is not None: |
|
840 | 840 | mark = checkformat(mark) |
@@ -848,7 +848,7 b' def bookmark(ui, repo, mark=None, rev=No' | |||
|
848 | 848 | marks[mark] = cur |
|
849 | 849 | if not inactive and cur == marks[mark]: |
|
850 | 850 | bookmarks.setcurrent(repo, mark) |
|
851 |
|
|
|
851 | marks.write() | |
|
852 | 852 | |
|
853 | 853 | # Same message whether trying to deactivate the current bookmark (-i |
|
854 | 854 | # with no NAME) or listing bookmarks |
@@ -1321,11 +1321,12 b' def commit(ui, repo, *pats, **opts):' | |||
|
1321 | 1321 | elif marks: |
|
1322 | 1322 | ui.debug('moving bookmarks %r from %s to %s\n' % |
|
1323 | 1323 | (marks, old.hex(), hex(node))) |
|
1324 | newmarks = repo._bookmarks | |
|
1324 | 1325 | for bm in marks: |
|
1325 |
|
|
|
1326 | newmarks[bm] = node | |
|
1326 | 1327 | if bm == current: |
|
1327 | 1328 | bookmarks.setcurrent(repo, bm) |
|
1328 |
|
|
|
1329 | newmarks.write() | |
|
1329 | 1330 | else: |
|
1330 | 1331 | e = cmdutil.commiteditor |
|
1331 | 1332 | if opts.get('force_editor'): |
@@ -4673,11 +4674,12 b' def pull(ui, repo, source="default", **o' | |||
|
4673 | 4674 | |
|
4674 | 4675 | # update specified bookmarks |
|
4675 | 4676 | if opts.get('bookmark'): |
|
4677 | marks = repo._bookmarks | |
|
4676 | 4678 | for b in opts['bookmark']: |
|
4677 | 4679 | # explicit pull overrides local bookmark if any |
|
4678 | 4680 | ui.status(_("importing bookmark %s\n") % b) |
|
4679 |
|
|
|
4680 |
|
|
|
4681 | marks[b] = repo[rb[b]].node() | |
|
4682 | marks.write() | |
|
4681 | 4683 | |
|
4682 | 4684 | return ret |
|
4683 | 4685 |
@@ -391,14 +391,15 b' def clone(ui, peeropts, source, dest=Non' | |||
|
391 | 391 | destrepo = destpeer.local() |
|
392 | 392 | if destrepo and srcpeer.capable("pushkey"): |
|
393 | 393 | rb = srcpeer.listkeys('bookmarks') |
|
394 | marks = destrepo._bookmarks | |
|
394 | 395 | for k, n in rb.iteritems(): |
|
395 | 396 | try: |
|
396 | 397 | m = destrepo.lookup(n) |
|
397 |
|
|
|
398 | marks[k] = m | |
|
398 | 399 | except error.RepoLookupError: |
|
399 | 400 | pass |
|
400 | 401 | if rb: |
|
401 |
|
|
|
402 | marks.write() | |
|
402 | 403 | elif srcrepo and destpeer.capable("pushkey"): |
|
403 | 404 | for k, n in srcrepo._bookmarks.iteritems(): |
|
404 | 405 | destpeer.pushkey('bookmarks', k, '', hex(n)) |
@@ -265,15 +265,12 b' class localrepository(object):' | |||
|
265 | 265 | |
|
266 | 266 | @filecache('bookmarks') |
|
267 | 267 | def _bookmarks(self): |
|
268 |
return bookmarks.re |
|
|
268 | return bookmarks.bmstore(self) | |
|
269 | 269 | |
|
270 | 270 | @filecache('bookmarks.current') |
|
271 | 271 | def _bookmarkcurrent(self): |
|
272 | 272 | return bookmarks.readcurrent(self) |
|
273 | 273 | |
|
274 | def _writebookmarks(self, marks): | |
|
275 | bookmarks.write(self) | |
|
276 | ||
|
277 | 274 | def bookmarkheads(self, bookmark): |
|
278 | 275 | name = bookmark.split('@', 1)[0] |
|
279 | 276 | heads = [] |
@@ -6,7 +6,7 b'' | |||
|
6 | 6 | # This software may be used and distributed according to the terms of the |
|
7 | 7 | # GNU General Public License version 2 or any later version. |
|
8 | 8 | |
|
9 |
from mercurial import changegroup |
|
|
9 | from mercurial import changegroup | |
|
10 | 10 | from mercurial.node import short |
|
11 | 11 | from mercurial.i18n import _ |
|
12 | 12 | import os |
@@ -181,7 +181,7 b' def strip(ui, repo, nodelist, backup="al' | |||
|
181 | 181 | |
|
182 | 182 | for m in updatebm: |
|
183 | 183 | bm[m] = repo[newbmtarget].node() |
|
184 |
b |
|
|
184 | bm.write() | |
|
185 | 185 | except: # re-raises |
|
186 | 186 | if backupfile: |
|
187 | 187 | ui.warn(_("strip failed, full bundle stored in '%s'\n") |
General Comments 0
You need to be logged in to leave comments.
Login now