##// END OF EJS Templates
hgk: remove unused revlog import
Augie Fackler -
r24517:c2c1ce5e default
parent child Browse files
Show More
@@ -1,335 +1,335
1 1 # Minimal support for git commands on an hg repository
2 2 #
3 3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 '''browse the repository in a graphical way
9 9
10 10 The hgk extension allows browsing the history of a repository in a
11 11 graphical way. It requires Tcl/Tk version 8.4 or later. (Tcl/Tk is not
12 12 distributed with Mercurial.)
13 13
14 14 hgk consists of two parts: a Tcl script that does the displaying and
15 15 querying of information, and an extension to Mercurial named hgk.py,
16 16 which provides hooks for hgk to get information. hgk can be found in
17 17 the contrib directory, and the extension is shipped in the hgext
18 18 repository, and needs to be enabled.
19 19
20 20 The :hg:`view` command will launch the hgk Tcl script. For this command
21 21 to work, hgk must be in your search path. Alternately, you can specify
22 22 the path to hgk in your configuration file::
23 23
24 24 [hgk]
25 25 path=/location/of/hgk
26 26
27 27 hgk can make use of the extdiff extension to visualize revisions.
28 28 Assuming you had already configured extdiff vdiff command, just add::
29 29
30 30 [hgk]
31 31 vdiff=vdiff
32 32
33 33 Revisions context menu will now display additional entries to fire
34 34 vdiff on hovered and selected revisions.
35 35 '''
36 36
37 37 import os
38 from mercurial import cmdutil, commands, patch, revlog, scmutil, obsolete
38 from mercurial import cmdutil, commands, patch, scmutil, obsolete
39 39 from mercurial.node import nullid, nullrev, short
40 40 from mercurial.i18n import _
41 41
42 42 cmdtable = {}
43 43 command = cmdutil.command(cmdtable)
44 44 testedwith = 'internal'
45 45
46 46 @command('debug-diff-tree',
47 47 [('p', 'patch', None, _('generate patch')),
48 48 ('r', 'recursive', None, _('recursive')),
49 49 ('P', 'pretty', None, _('pretty')),
50 50 ('s', 'stdin', None, _('stdin')),
51 51 ('C', 'copy', None, _('detect copies')),
52 52 ('S', 'search', "", _('search'))],
53 53 ('[OPTION]... NODE1 NODE2 [FILE]...'),
54 54 inferrepo=True)
55 55 def difftree(ui, repo, node1=None, node2=None, *files, **opts):
56 56 """diff trees from two commits"""
57 57 def __difftree(repo, node1, node2, files=[]):
58 58 assert node2 is not None
59 59 mmap = repo[node1].manifest()
60 60 mmap2 = repo[node2].manifest()
61 61 m = scmutil.match(repo[node1], files)
62 62 modified, added, removed = repo.status(node1, node2, m)[:3]
63 63 empty = short(nullid)
64 64
65 65 for f in modified:
66 66 # TODO get file permissions
67 67 ui.write(":100664 100664 %s %s M\t%s\t%s\n" %
68 68 (short(mmap[f]), short(mmap2[f]), f, f))
69 69 for f in added:
70 70 ui.write(":000000 100664 %s %s N\t%s\t%s\n" %
71 71 (empty, short(mmap2[f]), f, f))
72 72 for f in removed:
73 73 ui.write(":100664 000000 %s %s D\t%s\t%s\n" %
74 74 (short(mmap[f]), empty, f, f))
75 75 ##
76 76
77 77 while True:
78 78 if opts['stdin']:
79 79 try:
80 80 line = raw_input().split(' ')
81 81 node1 = line[0]
82 82 if len(line) > 1:
83 83 node2 = line[1]
84 84 else:
85 85 node2 = None
86 86 except EOFError:
87 87 break
88 88 node1 = repo.lookup(node1)
89 89 if node2:
90 90 node2 = repo.lookup(node2)
91 91 else:
92 92 node2 = node1
93 93 node1 = repo.changelog.parents(node1)[0]
94 94 if opts['patch']:
95 95 if opts['pretty']:
96 96 catcommit(ui, repo, node2, "")
97 97 m = scmutil.match(repo[node1], files)
98 98 diffopts = patch.difffeatureopts(ui)
99 99 diffopts.git = True
100 100 chunks = patch.diff(repo, node1, node2, match=m,
101 101 opts=diffopts)
102 102 for chunk in chunks:
103 103 ui.write(chunk)
104 104 else:
105 105 __difftree(repo, node1, node2, files=files)
106 106 if not opts['stdin']:
107 107 break
108 108
109 109 def catcommit(ui, repo, n, prefix, ctx=None):
110 110 nlprefix = '\n' + prefix
111 111 if ctx is None:
112 112 ctx = repo[n]
113 113 # use ctx.node() instead ??
114 114 ui.write(("tree %s\n" % short(ctx.changeset()[0])))
115 115 for p in ctx.parents():
116 116 ui.write(("parent %s\n" % p))
117 117
118 118 date = ctx.date()
119 119 description = ctx.description().replace("\0", "")
120 120 lines = description.splitlines()
121 121 if lines and lines[-1].startswith('committer:'):
122 122 committer = lines[-1].split(': ')[1].rstrip()
123 123 else:
124 124 committer = ""
125 125
126 126 ui.write(("author %s %s %s\n" % (ctx.user(), int(date[0]), date[1])))
127 127 if committer != '':
128 128 ui.write(("committer %s %s %s\n" % (committer, int(date[0]), date[1])))
129 129 ui.write(("revision %d\n" % ctx.rev()))
130 130 ui.write(("branch %s\n" % ctx.branch()))
131 131 if obsolete.isenabled(repo, obsolete.createmarkersopt):
132 132 if ctx.obsolete():
133 133 ui.write(("obsolete\n"))
134 134 ui.write(("phase %s\n\n" % ctx.phasestr()))
135 135
136 136 if prefix != "":
137 137 ui.write("%s%s\n" % (prefix,
138 138 description.replace('\n', nlprefix).strip()))
139 139 else:
140 140 ui.write(description + "\n")
141 141 if prefix:
142 142 ui.write('\0')
143 143
144 144 @command('debug-merge-base', [], _('REV REV'))
145 145 def base(ui, repo, node1, node2):
146 146 """output common ancestor information"""
147 147 node1 = repo.lookup(node1)
148 148 node2 = repo.lookup(node2)
149 149 n = repo.changelog.ancestor(node1, node2)
150 150 ui.write(short(n) + "\n")
151 151
152 152 @command('debug-cat-file',
153 153 [('s', 'stdin', None, _('stdin'))],
154 154 _('[OPTION]... TYPE FILE'),
155 155 inferrepo=True)
156 156 def catfile(ui, repo, type=None, r=None, **opts):
157 157 """cat a specific revision"""
158 158 # in stdin mode, every line except the commit is prefixed with two
159 159 # spaces. This way the our caller can find the commit without magic
160 160 # strings
161 161 #
162 162 prefix = ""
163 163 if opts['stdin']:
164 164 try:
165 165 (type, r) = raw_input().split(' ')
166 166 prefix = " "
167 167 except EOFError:
168 168 return
169 169
170 170 else:
171 171 if not type or not r:
172 172 ui.warn(_("cat-file: type or revision not supplied\n"))
173 173 commands.help_(ui, 'cat-file')
174 174
175 175 while r:
176 176 if type != "commit":
177 177 ui.warn(_("aborting hg cat-file only understands commits\n"))
178 178 return 1
179 179 n = repo.lookup(r)
180 180 catcommit(ui, repo, n, prefix)
181 181 if opts['stdin']:
182 182 try:
183 183 (type, r) = raw_input().split(' ')
184 184 except EOFError:
185 185 break
186 186 else:
187 187 break
188 188
189 189 # git rev-tree is a confusing thing. You can supply a number of
190 190 # commit sha1s on the command line, and it walks the commit history
191 191 # telling you which commits are reachable from the supplied ones via
192 192 # a bitmask based on arg position.
193 193 # you can specify a commit to stop at by starting the sha1 with ^
194 194 def revtree(ui, args, repo, full="tree", maxnr=0, parents=False):
195 195 def chlogwalk():
196 196 count = len(repo)
197 197 i = count
198 198 l = [0] * 100
199 199 chunk = 100
200 200 while True:
201 201 if chunk > i:
202 202 chunk = i
203 203 i = 0
204 204 else:
205 205 i -= chunk
206 206
207 207 for x in xrange(chunk):
208 208 if i + x >= count:
209 209 l[chunk - x:] = [0] * (chunk - x)
210 210 break
211 211 if full is not None:
212 212 if (i + x) in repo:
213 213 l[x] = repo[i + x]
214 214 l[x].changeset() # force reading
215 215 else:
216 216 if (i + x) in repo:
217 217 l[x] = 1
218 218 for x in xrange(chunk - 1, -1, -1):
219 219 if l[x] != 0:
220 220 yield (i + x, full is not None and l[x] or None)
221 221 if i == 0:
222 222 break
223 223
224 224 # calculate and return the reachability bitmask for sha
225 225 def is_reachable(ar, reachable, sha):
226 226 if len(ar) == 0:
227 227 return 1
228 228 mask = 0
229 229 for i in xrange(len(ar)):
230 230 if sha in reachable[i]:
231 231 mask |= 1 << i
232 232
233 233 return mask
234 234
235 235 reachable = []
236 236 stop_sha1 = []
237 237 want_sha1 = []
238 238 count = 0
239 239
240 240 # figure out which commits they are asking for and which ones they
241 241 # want us to stop on
242 242 for i, arg in enumerate(args):
243 243 if arg.startswith('^'):
244 244 s = repo.lookup(arg[1:])
245 245 stop_sha1.append(s)
246 246 want_sha1.append(s)
247 247 elif arg != 'HEAD':
248 248 want_sha1.append(repo.lookup(arg))
249 249
250 250 # calculate the graph for the supplied commits
251 251 for i, n in enumerate(want_sha1):
252 252 reachable.append(set())
253 253 visit = [n]
254 254 reachable[i].add(n)
255 255 while visit:
256 256 n = visit.pop(0)
257 257 if n in stop_sha1:
258 258 continue
259 259 for p in repo.changelog.parents(n):
260 260 if p not in reachable[i]:
261 261 reachable[i].add(p)
262 262 visit.append(p)
263 263 if p in stop_sha1:
264 264 continue
265 265
266 266 # walk the repository looking for commits that are in our
267 267 # reachability graph
268 268 for i, ctx in chlogwalk():
269 269 if i not in repo:
270 270 continue
271 271 n = repo.changelog.node(i)
272 272 mask = is_reachable(want_sha1, reachable, n)
273 273 if mask:
274 274 parentstr = ""
275 275 if parents:
276 276 pp = repo.changelog.parents(n)
277 277 if pp[0] != nullid:
278 278 parentstr += " " + short(pp[0])
279 279 if pp[1] != nullid:
280 280 parentstr += " " + short(pp[1])
281 281 if not full:
282 282 ui.write("%s%s\n" % (short(n), parentstr))
283 283 elif full == "commit":
284 284 ui.write("%s%s\n" % (short(n), parentstr))
285 285 catcommit(ui, repo, n, ' ', ctx)
286 286 else:
287 287 (p1, p2) = repo.changelog.parents(n)
288 288 (h, h1, h2) = map(short, (n, p1, p2))
289 289 (i1, i2) = map(repo.changelog.rev, (p1, p2))
290 290
291 291 date = ctx.date()[0]
292 292 ui.write("%s %s:%s" % (date, h, mask))
293 293 mask = is_reachable(want_sha1, reachable, p1)
294 294 if i1 != nullrev and mask > 0:
295 295 ui.write("%s:%s " % (h1, mask)),
296 296 mask = is_reachable(want_sha1, reachable, p2)
297 297 if i2 != nullrev and mask > 0:
298 298 ui.write("%s:%s " % (h2, mask))
299 299 ui.write("\n")
300 300 if maxnr and count >= maxnr:
301 301 break
302 302 count += 1
303 303
304 304 # git rev-list tries to order things by date, and has the ability to stop
305 305 # at a given commit without walking the whole repo. TODO add the stop
306 306 # parameter
307 307 @command('debug-rev-list',
308 308 [('H', 'header', None, _('header')),
309 309 ('t', 'topo-order', None, _('topo-order')),
310 310 ('p', 'parents', None, _('parents')),
311 311 ('n', 'max-count', 0, _('max-count'))],
312 312 ('[OPTION]... REV...'))
313 313 def revlist(ui, repo, *revs, **opts):
314 314 """print revisions"""
315 315 if opts['header']:
316 316 full = "commit"
317 317 else:
318 318 full = None
319 319 copy = [x for x in revs]
320 320 revtree(ui, copy, repo, full, opts['max_count'], opts['parents'])
321 321
322 322 @command('view',
323 323 [('l', 'limit', '',
324 324 _('limit number of changes displayed'), _('NUM'))],
325 325 _('[-l LIMIT] [REVRANGE]'))
326 326 def view(ui, repo, *etc, **opts):
327 327 "start interactive history viewer"
328 328 os.chdir(repo.root)
329 329 optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems() if v])
330 330 if repo.filtername is None:
331 331 optstr += '--hidden'
332 332
333 333 cmd = ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc))
334 334 ui.debug("running %s\n" % cmd)
335 335 ui.system(cmd)
General Comments 0
You need to be logged in to leave comments. Login now