comparison hgext/hgk.py @ 3098:fe9b13e35e46

Merge with crew
author Matt Mackall <mpm@selenic.com>
date Fri, 15 Sep 2006 15:22:45 -0500
parents edefbb3a3b08
children eb0906ebba81
comparison
equal deleted inserted replaced
3097:1b738357bba9 3098:fe9b13e35e46
5 # This software may be used and distributed according to the terms 5 # This software may be used and distributed according to the terms
6 # of the GNU General Public License, incorporated herein by reference. 6 # of the GNU General Public License, incorporated herein by reference.
7 7
8 from mercurial.demandload import * 8 from mercurial.demandload import *
9 demandload(globals(), 'time sys signal os') 9 demandload(globals(), 'time sys signal os')
10 demandload(globals(), 'mercurial:hg,mdiff,fancyopts,commands,ui,util') 10 demandload(globals(), 'mercurial:hg,fancyopts,commands,ui,util,patch,revlog')
11 11
12 def dodiff(fp, ui, repo, node1, node2, files=None, match=util.always, 12 def difftree(ui, repo, node1=None, node2=None, *files, **opts):
13 changes=None, text=False):
14 def date(c):
15 return time.asctime(time.gmtime(c[2][0]))
16
17 if not changes:
18 changes = repo.status(node1, node2, files, match=match)[:5]
19 modified, added, removed, deleted, unknown = changes
20 if files:
21 modified, added, removed = map(lambda x: filterfiles(files, x),
22 (modified, added, removed))
23
24 if not modified and not added and not removed:
25 return
26
27 if node2:
28 change = repo.changelog.read(node2)
29 mmap2 = repo.manifest.read(change[0])
30 date2 = date(change)
31 def read(f):
32 return repo.file(f).read(mmap2[f])
33 else:
34 date2 = time.asctime()
35 if not node1:
36 node1 = repo.dirstate.parents()[0]
37 def read(f):
38 return repo.wfile(f).read()
39
40 change = repo.changelog.read(node1)
41 mmap = repo.manifest.read(change[0])
42 date1 = date(change)
43
44 for f in modified:
45 to = None
46 if f in mmap:
47 to = repo.file(f).read(mmap[f])
48 tn = read(f)
49 fp.write("diff --git a/%s b/%s\n" % (f, f))
50 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
51 for f in added:
52 to = None
53 tn = read(f)
54 fp.write("diff --git /dev/null b/%s\n" % (f))
55 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
56 for f in removed:
57 to = repo.file(f).read(mmap[f])
58 tn = None
59 fp.write("diff --git a/%s /dev/null\n" % (f))
60 fp.write(mdiff.unidiff(to, date1, tn, date2, f, None, text=text))
61
62 def difftree(ui, repo, node1=None, node2=None, **opts):
63 """diff trees from two commits""" 13 """diff trees from two commits"""
64 def __difftree(repo, node1, node2): 14 def __difftree(repo, node1, node2, files=[]):
65 def date(c):
66 return time.asctime(time.gmtime(c[2][0]))
67
68 if node2: 15 if node2:
69 change = repo.changelog.read(node2) 16 change = repo.changelog.read(node2)
70 mmap2 = repo.manifest.read(change[0]) 17 mmap2 = repo.manifest.read(change[0])
71 modified, added, removed, deleted, unknown = repo.status(node1, node2)[:5] 18 status = repo.status(node1, node2, files=files)[:5]
72 def read(f): return repo.file(f).read(mmap2[f]) 19 modified, added, removed, deleted, unknown = status
73 date2 = date(change)
74 else: 20 else:
75 date2 = time.asctime() 21 status = repo.status(node1, files=files)[:5]
76 modified, added, removed, deleted, unknown = repo.status(node1)[:5] 22 modified, added, removed, deleted, unknown = status
77 if not node1: 23 if not node1:
78 node1 = repo.dirstate.parents()[0] 24 node1 = repo.dirstate.parents()[0]
79 def read(f): return file(os.path.join(repo.root, f)).read()
80 25
81 change = repo.changelog.read(node1) 26 change = repo.changelog.read(node1)
82 mmap = repo.manifest.read(change[0]) 27 mmap = repo.manifest.read(change[0])
83 date1 = date(change) 28 empty = hg.short(hg.nullid)
84 empty = "0" * 40;
85 29
86 for f in modified: 30 for f in modified:
87 # TODO get file permissions 31 # TODO get file permissions
88 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]), 32 print ":100664 100664 %s %s M\t%s\t%s" % (hg.short(mmap[f]),
89 hg.hex(mmap2[f]), f, f) 33 hg.short(mmap2[f]),
34 f, f)
90 for f in added: 35 for f in added:
91 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f) 36 print ":000000 100664 %s %s N\t%s\t%s" % (empty,
37 hg.short(mmap2[f]),
38 f, f)
92 for f in removed: 39 for f in removed:
93 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f) 40 print ":100664 000000 %s %s D\t%s\t%s" % (hg.short(mmap[f]),
41 empty,
42 f, f)
94 ## 43 ##
95 44
96 while True: 45 while True:
97 if opts['stdin']: 46 if opts['stdin']:
98 try: 47 try:
111 node2 = node1 60 node2 = node1
112 node1 = repo.changelog.parents(node1)[0] 61 node1 = repo.changelog.parents(node1)[0]
113 if opts['patch']: 62 if opts['patch']:
114 if opts['pretty']: 63 if opts['pretty']:
115 catcommit(repo, node2, "") 64 catcommit(repo, node2, "")
116 dodiff(sys.stdout, ui, repo, node1, node2) 65 patch.diff(repo, node1, node2,
66 files=files,
67 opts=patch.diffopts(ui, {'git': True}))
117 else: 68 else:
118 __difftree(repo, node1, node2) 69 __difftree(repo, node1, node2, files=files)
119 if not opts['stdin']: 70 if not opts['stdin']:
120 break 71 break
121 72
122 def catcommit(repo, n, prefix, changes=None): 73 def catcommit(repo, n, prefix, changes=None):
123 nlprefix = '\n' + prefix; 74 nlprefix = '\n' + prefix;
124 (p1, p2) = repo.changelog.parents(n) 75 (p1, p2) = repo.changelog.parents(n)
125 (h, h1, h2) = map(hg.hex, (n, p1, p2)) 76 (h, h1, h2) = map(hg.short, (n, p1, p2))
126 (i1, i2) = map(repo.changelog.rev, (p1, p2)) 77 (i1, i2) = map(repo.changelog.rev, (p1, p2))
127 if not changes: 78 if not changes:
128 changes = repo.changelog.read(n) 79 changes = repo.changelog.read(n)
129 print "tree %s" % (hg.hex(changes[0])) 80 print "tree %s" % (hg.short(changes[0]))
130 if i1 != -1: print "parent %s" % (h1) 81 if i1 != -1: print "parent %s" % (h1)
131 if i2 != -1: print "parent %s" % (h2) 82 if i2 != -1: print "parent %s" % (h2)
132 date_ar = changes[2] 83 date_ar = changes[2]
133 date = int(float(date_ar[0])) 84 date = int(float(date_ar[0]))
134 lines = changes[4].splitlines() 85 lines = changes[4].splitlines()
137 else: 88 else:
138 committer = changes[1] 89 committer = changes[1]
139 90
140 print "author %s %s %s" % (changes[1], date, date_ar[1]) 91 print "author %s %s %s" % (changes[1], date, date_ar[1])
141 print "committer %s %s %s" % (committer, date, date_ar[1]) 92 print "committer %s %s %s" % (committer, date, date_ar[1])
93 print "revision %d" % repo.changelog.rev(n)
142 print "" 94 print ""
143 if prefix != "": 95 if prefix != "":
144 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip()) 96 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip())
145 else: 97 else:
146 print changes[4] 98 print changes[4]
150 def base(ui, repo, node1, node2): 102 def base(ui, repo, node1, node2):
151 """Output common ancestor information""" 103 """Output common ancestor information"""
152 node1 = repo.lookup(node1) 104 node1 = repo.lookup(node1)
153 node2 = repo.lookup(node2) 105 node2 = repo.lookup(node2)
154 n = repo.changelog.ancestor(node1, node2) 106 n = repo.changelog.ancestor(node1, node2)
155 print hg.hex(n) 107 print hg.short(n)
156 108
157 def catfile(ui, repo, type=None, r=None, **opts): 109 def catfile(ui, repo, type=None, r=None, **opts):
158 """cat a specific revision""" 110 """cat a specific revision"""
159 # in stdin mode, every line except the commit is prefixed with two 111 # in stdin mode, every line except the commit is prefixed with two
160 # spaces. This way the our caller can find the commit without magic 112 # spaces. This way the our caller can find the commit without magic
263 if p in stop_sha1: 215 if p in stop_sha1:
264 continue 216 continue
265 217
266 # walk the repository looking for commits that are in our 218 # walk the repository looking for commits that are in our
267 # reachability graph 219 # reachability graph
268 #for i in range(repo.changelog.count()-1, -1, -1):
269 for i, changes in chlogwalk(): 220 for i, changes in chlogwalk():
270 n = repo.changelog.node(i) 221 n = repo.changelog.node(i)
271 mask = is_reachable(want_sha1, reachable, n) 222 mask = is_reachable(want_sha1, reachable, n)
272 if mask: 223 if mask:
273 parentstr = "" 224 parentstr = ""
274 if parents: 225 if parents:
275 pp = repo.changelog.parents(n) 226 pp = repo.changelog.parents(n)
276 if pp[0] != hg.nullid: 227 if pp[0] != hg.nullid:
277 parentstr += " " + hg.hex(pp[0]) 228 parentstr += " " + hg.short(pp[0])
278 if pp[1] != hg.nullid: 229 if pp[1] != hg.nullid:
279 parentstr += " " + hg.hex(pp[1]) 230 parentstr += " " + hg.short(pp[1])
280 if not full: 231 if not full:
281 print hg.hex(n) + parentstr 232 print hg.short(n) + parentstr
282 elif full is "commit": 233 elif full == "commit":
283 print hg.hex(n) + parentstr 234 print hg.short(n) + parentstr
284 catcommit(repo, n, ' ', changes) 235 catcommit(repo, n, ' ', changes)
285 else: 236 else:
286 (p1, p2) = repo.changelog.parents(n) 237 (p1, p2) = repo.changelog.parents(n)
287 (h, h1, h2) = map(hg.hex, (n, p1, p2)) 238 (h, h1, h2) = map(hg.short, (n, p1, p2))
288 (i1, i2) = map(repo.changelog.rev, (p1, p2)) 239 (i1, i2) = map(repo.changelog.rev, (p1, p2))
289 240
290 date = changes[2][0] 241 date = changes[2][0]
291 print "%s %s:%s" % (date, h, mask), 242 print "%s %s:%s" % (date, h, mask),
292 mask = is_reachable(want_sha1, reachable, p1) 243 mask = is_reachable(want_sha1, reachable, p1)
298 print "" 249 print ""
299 if maxnr and count >= maxnr: 250 if maxnr and count >= maxnr:
300 break 251 break
301 count += 1 252 count += 1
302 253
254 def revparse(ui, repo, *revs, **opts):
255 """Parse given revisions"""
256 def revstr(rev):
257 if rev == 'HEAD':
258 rev = 'tip'
259 return revlog.hex(repo.lookup(rev))
260
261 for r in revs:
262 revrange = r.split(':', 1)
263 ui.write('%s\n' % revstr(revrange[0]))
264 if len(revrange) == 2:
265 ui.write('^%s\n' % revstr(revrange[1]))
266
303 # git rev-list tries to order things by date, and has the ability to stop 267 # git rev-list tries to order things by date, and has the ability to stop
304 # at a given commit without walking the whole repo. TODO add the stop 268 # at a given commit without walking the whole repo. TODO add the stop
305 # parameter 269 # parameter
306 def revlist(ui, repo, *revs, **opts): 270 def revlist(ui, repo, *revs, **opts):
307 """print revisions""" 271 """print revisions"""
310 else: 274 else:
311 full = None 275 full = None
312 copy = [x for x in revs] 276 copy = [x for x in revs]
313 revtree(copy, repo, full, opts['max_count'], opts['parents']) 277 revtree(copy, repo, full, opts['max_count'], opts['parents'])
314 278
315 def view(ui, repo, *etc): 279 def view(ui, repo, *etc, **opts):
316 "start interactive history viewer" 280 "start interactive history viewer"
317 os.chdir(repo.root) 281 os.chdir(repo.root)
318 os.system(ui.config("hgk", "path", "hgk") + " " + " ".join(etc)) 282 optstr = ' '.join(['--%s %s' % (k, v) for k, v in opts.iteritems()])
283 os.system(ui.config("hgk", "path", "hgk") + " %s %s" % (optstr, " ".join(etc)))
319 284
320 cmdtable = { 285 cmdtable = {
321 "view": (view, [], 'hg view'), 286 "view": (view,
287 [('l', 'limit', '', 'limit number of changes displayed')],
288 'hg view [-l LIMIT] [REVRANGE]'),
322 "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'), 289 "debug-diff-tree": (difftree, [('p', 'patch', None, 'generate patch'),
323 ('r', 'recursive', None, 'recursive'), 290 ('r', 'recursive', None, 'recursive'),
324 ('P', 'pretty', None, 'pretty'), 291 ('P', 'pretty', None, 'pretty'),
325 ('s', 'stdin', None, 'stdin'), 292 ('s', 'stdin', None, 'stdin'),
326 ('C', 'copy', None, 'detect copies'), 293 ('C', 'copy', None, 'detect copies'),
327 ('S', 'search', "", 'search')], 294 ('S', 'search', "", 'search')],
328 "hg git-diff-tree [options] node1 node2"), 295 "hg git-diff-tree [options] node1 node2 [files...]"),
329 "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')], 296 "debug-cat-file": (catfile, [('s', 'stdin', None, 'stdin')],
330 "hg debug-cat-file [options] type file"), 297 "hg debug-cat-file [options] type file"),
331 "debug-merge-base": (base, [], "hg debug-merge-base node node"), 298 "debug-merge-base": (base, [], "hg debug-merge-base node node"),
299 'debug-rev-parse': (revparse,
300 [('', 'default', '', 'ignored')],
301 "hg debug-rev-parse rev"),
332 "debug-rev-list": (revlist, [('H', 'header', None, 'header'), 302 "debug-rev-list": (revlist, [('H', 'header', None, 'header'),
333 ('t', 'topo-order', None, 'topo-order'), 303 ('t', 'topo-order', None, 'topo-order'),
334 ('p', 'parents', None, 'parents'), 304 ('p', 'parents', None, 'parents'),
335 ('n', 'max-count', 0, 'max-count')], 305 ('n', 'max-count', 0, 'max-count')],
336 "hg debug-rev-list [options] revs"), 306 "hg debug-rev-list [options] revs"),