annotate mercurial/bookmarks.py @ 13352:f9cd37fca5ba

bookmarks: move update into core
author Matt Mackall <mpm@selenic.com>
date Thu, 10 Feb 2011 13:46:27 -0600
parents 6c5368cd2df9
children 689bf32b3bbd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # Mercurial bookmark support code
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2008 David Soria Parra <dsp@php.net>
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
8 from mercurial.i18n import _
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9 from mercurial.node import nullid, nullrev, bin, hex, short
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
10 from mercurial import encoding
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
11 import os
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
12
13351
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
13 def read(repo):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
14 '''Parse .hg/bookmarks file and return a dictionary
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
15
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
16 Bookmarks are stored as {HASH}\\s{NAME}\\n (localtags format) values
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
17 in the .hg/bookmarks file.
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
18 Read the file and return a (name=>nodeid) dictionary
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
19 '''
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
20 try:
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
21 bookmarks = {}
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
22 for line in repo.opener('bookmarks'):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
23 sha, refspec = line.strip().split(' ', 1)
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
24 refspec = encoding.tolocal(refspec)
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
25 bookmarks[refspec] = repo.changelog.lookup(sha)
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
26 except:
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
27 pass
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
28 return bookmarks
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
29
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
30 def readcurrent(repo):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
31 '''Get the current bookmark
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
32
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
33 If we use gittishsh branches we have a current bookmark that
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
34 we are on. This function returns the name of the bookmark. It
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
35 is stored in .hg/bookmarks.current
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
36 '''
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
37 mark = None
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
38 if os.path.exists(repo.join('bookmarks.current')):
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
39 file = repo.opener('bookmarks.current')
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
40 # No readline() in posixfile_nt, reading everything is cheap
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
41 mark = (file.readlines() or [''])[0]
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
42 if mark == '':
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
43 mark = None
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
44 file.close()
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
45 return mark
6c5368cd2df9 bookmarks: move read methods to core
Matt Mackall <mpm@selenic.com>
parents: 13350
diff changeset
46
13350
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
47 def write(repo):
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
48 '''Write bookmarks
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
49
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
50 Write the given bookmark => hash dictionary to the .hg/bookmarks file
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
51 in a format equal to those of localtags.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
52
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
53 We also store a backup of the previous state in undo.bookmarks that
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
54 can be copied back on rollback.
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
55 '''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
56 refs = repo._bookmarks
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
57
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
58 try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
59 bms = repo.opener('bookmarks').read()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
60 except IOError:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
61 bms = ''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
62 repo.opener('undo.bookmarks', 'w').write(bms)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
63
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
64 if repo._bookmarkcurrent not in refs:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
65 setcurrent(repo, None)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
66 wlock = repo.wlock()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
67 try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
68 file = repo.opener('bookmarks', 'w', atomictemp=True)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
69 for refspec, node in refs.iteritems():
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
70 file.write("%s %s\n" % (hex(node), encoding.fromlocal(refspec)))
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
71 file.rename()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
72
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
73 # touch 00changelog.i so hgweb reloads bookmarks (no lock needed)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
74 try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
75 os.utime(repo.sjoin('00changelog.i'), None)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
76 except OSError:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
77 pass
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
78
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
79 finally:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
80 wlock.release()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
81
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
82 def setcurrent(repo, mark):
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
83 '''Set the name of the bookmark that we are currently on
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
84
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
85 Set the name of the bookmark that we are on (hg update <bookmark>).
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
86 The name is recorded in .hg/bookmarks.current
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
87 '''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
88 current = repo._bookmarkcurrent
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
89 if current == mark:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
90 return
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
91
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
92 refs = repo._bookmarks
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
93
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
94 # do not update if we do update to a rev equal to the current bookmark
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
95 if (mark and mark not in refs and
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
96 current and refs[current] == repo.changectx('.').node()):
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
97 return
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
98 if mark not in refs:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
99 mark = ''
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
100 wlock = repo.wlock()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
101 try:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
102 file = repo.opener('bookmarks.current', 'w', atomictemp=True)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
103 file.write(mark)
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
104 file.rename()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
105 finally:
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
106 wlock.release()
a7376b92caaa bookmarks: move basic io to core
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
107 repo._bookmarkcurrent = mark
13352
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
108
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
109 def update(repo, parents, node):
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
110 marks = repo._bookmarks
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
111 update = False
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
112 if repo.ui.configbool('bookmarks', 'track.current'):
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
113 mark = repo._bookmarkcurrent
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
114 if mark and marks[mark] in parents:
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
115 marks[mark] = node
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
116 update = True
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
117 else:
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
118 for mark, n in marks.items():
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
119 if n in parents:
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
120 marks[mark] = node
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
121 update = True
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
122 if update:
f9cd37fca5ba bookmarks: move update into core
Matt Mackall <mpm@selenic.com>
parents: 13351
diff changeset
123 write(repo)