comparison mercurial/commands.py @ 245:fef0f8e041aa

big heap of command clean-up work -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 big heap of command clean-up work Migrate add, forget, remove, commit, diff, addremove, tip, log, recover, and serve. Fix up filterfiles, relfilter, and relpath to be a bit more bulletproof Alphabetize functions and the command table Make everything in commands.py relative-path aware manifest hash: f0856031a7be4e49289677b467f29bcf24ebce4a -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.0 (GNU/Linux) iD8DBQFCof6gywK+sNU5EO8RAoW1AJsHu8vchPSjls7wVbvsq/UKlGhqtgCgtnnl xSBxyf/TEVWjHIk3uTa8WSE= =YPMl -----END PGP SIGNATURE-----
author mpm@selenic.com
date Sat, 04 Jun 2005 11:18:56 -0800
parents afe895fcc0d0
children 96cde50a746f
comparison
equal deleted inserted replaced
244:43105253cf5e 245:fef0f8e041aa
1 import os, re, traceback, sys, signal, time 1 import os, re, traceback, sys, signal, time, mdiff
2 from mercurial import fancyopts, ui, hg 2 from mercurial import fancyopts, ui, hg
3 3
4 class UnknownCommand(Exception): pass 4 class UnknownCommand(Exception): pass
5 5
6 def filterfiles(list, files): 6 def filterfiles(filters, files):
7 l = [ x for x in list if x in files ] 7 l = [ x for x in files if x in filters ]
8 8
9 for f in files: 9 for t in filters:
10 if f[-1] != os.sep: f += os.sep 10 if t and t[-1] != os.sep: t += os.sep
11 l += [ x for x in list if x.startswith(f) ] 11 l += [ x for x in files if x.startswith(t) ]
12 return l 12 return l
13 13
14 def relfilter(repo, args): 14 def relfilter(repo, files):
15 if os.getcwd() != repo.root: 15 if os.getcwd() != repo.root:
16 p = os.getcwd()[len(repo.root) + 1: ] 16 p = os.getcwd()[len(repo.root) + 1: ]
17 return filterfiles(p, args) 17 return filterfiles(p, files)
18 return args 18 return files
19 19
20 def relpath(repo, args): 20 def relpath(repo, args):
21 if os.getcwd() != repo.root: 21 if os.getcwd() != repo.root:
22 p = os.getcwd()[len(repo.root) + 1: ] 22 p = os.getcwd()[len(repo.root) + 1: ]
23 return [ os.path.join(p, x) for x in args ] 23 return [ os.path.normpath(os.path.join(p, x)) for x in args ]
24 return args 24 return args
25
26 def dodiff(repo, files = None, node1 = None, node2 = None):
27 def date(c):
28 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
29
30 if node2:
31 change = repo.changelog.read(node2)
32 mmap2 = repo.manifest.read(change[0])
33 (c, a, d) = repo.diffrevs(node1, node2)
34 def read(f): return repo.file(f).read(mmap2[f])
35 date2 = date(change)
36 else:
37 date2 = time.asctime()
38 (c, a, d, u) = repo.diffdir(repo.root, node1)
39 if not node1:
40 node1 = repo.dirstate.parents()[0]
41 def read(f): return file(os.path.join(repo.root, f)).read()
42
43 change = repo.changelog.read(node1)
44 mmap = repo.manifest.read(change[0])
45 date1 = date(change)
46
47 if files:
48 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
49
50 for f in c:
51 to = repo.file(f).read(mmap[f])
52 tn = read(f)
53 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
54 for f in a:
55 to = ""
56 tn = read(f)
57 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
58 for f in d:
59 to = repo.file(f).read(mmap[f])
60 tn = ""
61 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
25 62
26 def help(ui, cmd=None): 63 def help(ui, cmd=None):
27 '''show help''' 64 '''show help'''
28 if cmd: 65 if cmd:
29 try: 66 try:
57 status show new, missing, and changed files in working dir 94 status show new, missing, and changed files in working dir
58 tags show current changeset tags 95 tags show current changeset tags
59 undo undo the last transaction 96 undo undo the last transaction
60 """) 97 """)
61 98
62 def init(ui): 99 def add(ui, repo, file, *files):
63 """create a repository""" 100 '''add the specified files on the next commit'''
64 hg.repository(ui, ".", create=1) 101 repo.add(relpath(repo, (file,) + files))
65 102
66 def branch(ui, path): 103 def addremove(ui, repo):
67 '''branch from a local repository'''
68 # this should eventually support remote repos
69 os.system("cp -al %s/.hg .hg" % path)
70
71 def checkout(ui, repo, changeset=None):
72 '''checkout a given changeset or the current tip'''
73 (c, a, d, u) = repo.diffdir(repo.root) 104 (c, a, d, u) = repo.diffdir(repo.root)
74 if c or a or d: 105 repo.add(a)
75 ui.warn("aborting (outstanding changes in working directory)\n") 106 repo.remove(d)
76 sys.exit(1) 107
77 108 def annotate(u, repo, file, *files, **ops):
78 node = repo.changelog.tip()
79 if changeset:
80 node = repo.lookup(changeset)
81 repo.checkout(node)
82
83 def annotate(u, repo, *args, **ops):
84 def getnode(rev): 109 def getnode(rev):
85 return hg.short(repo.changelog.node(rev)) 110 return hg.short(repo.changelog.node(rev))
86 111
87 def getname(rev): 112 def getname(rev):
88 try: 113 try:
99 bcache = {} 124 bcache = {}
100 opmap = [['user', getname], ['number', str], ['changeset', getnode]] 125 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
101 if not ops['user'] and not ops['changeset']: 126 if not ops['user'] and not ops['changeset']:
102 ops['number'] = 1 127 ops['number'] = 1
103 128
104 args = relpath(repo, args)
105 node = repo.dirstate.parents()[0] 129 node = repo.dirstate.parents()[0]
106 if ops['revision']: 130 if ops['revision']:
107 node = repo.changelog.lookup(ops['revision']) 131 node = repo.changelog.lookup(ops['revision'])
108 change = repo.changelog.read(node) 132 change = repo.changelog.read(node)
109 mmap = repo.manifest.read(change[0]) 133 mmap = repo.manifest.read(change[0])
110 maxuserlen = 0 134 maxuserlen = 0
111 maxchangelen = 0 135 maxchangelen = 0
112 for f in args: 136 for f in relpath(repo, (file,) + files):
113 lines = repo.file(f).annotate(mmap[f]) 137 lines = repo.file(f).annotate(mmap[f])
114 pieces = [] 138 pieces = []
115 139
116 for o, f in opmap: 140 for o, f in opmap:
117 if ops[o]: 141 if ops[o]:
119 m = max(map(len, l)) 143 m = max(map(len, l))
120 pieces.append([ "%*s" % (m, x) for x in l]) 144 pieces.append([ "%*s" % (m, x) for x in l])
121 145
122 for p,l in zip(zip(*pieces), lines): 146 for p,l in zip(zip(*pieces), lines):
123 u.write(" ".join(p) + ": " + l[1]) 147 u.write(" ".join(p) + ": " + l[1])
148
149 def branch(ui, path):
150 '''branch from a local repository'''
151 # this should eventually support remote repos
152 os.system("cp -al %s/.hg .hg" % path)
153
154 def checkout(ui, repo, changeset=None):
155 '''checkout a given changeset or the current tip'''
156 (c, a, d, u) = repo.diffdir(repo.root)
157 if c or a or d:
158 ui.warn("aborting (outstanding changes in working directory)\n")
159 sys.exit(1)
160
161 node = repo.changelog.tip()
162 if changeset:
163 node = repo.lookup(changeset)
164 repo.checkout(node)
165
166 def commit(ui, repo, *files):
167 """commit the specified files or all outstanding changes"""
168 repo.commit(relpath(repo, files))
169
170 def diff(ui, repo, *files, **opts):
171 revs = []
172 if opts['rev']:
173 revs = map(lambda x: repo.lookup(x), opts['rev'])
174
175 if len(revs) > 2:
176 self.ui.warn("too many revisions to diff\n")
177 sys.exit(1)
178
179 if files:
180 files = relpath(repo, files)
181 else:
182 files = relpath(repo, [""])
183
184 dodiff(repo, files, *revs)
185
186 def forget(ui, repo, file, *files):
187 """don't add the specified files on the next commit"""
188 repo.forget(relpath(repo, (file,) + files))
124 189
125 def heads(ui, repo): 190 def heads(ui, repo):
126 '''show current repository heads''' 191 '''show current repository heads'''
127 for n in repo.changelog.heads(): 192 for n in repo.changelog.heads():
128 i = repo.changelog.rev(n) 193 i = repo.changelog.rev(n)
140 time.localtime(float(changes[2].split(' ')[0]))) 205 time.localtime(float(changes[2].split(' ')[0])))
141 if ui.verbose: print "files:", " ".join(changes[3]) 206 if ui.verbose: print "files:", " ".join(changes[3])
142 print "description:" 207 print "description:"
143 print changes[4] 208 print changes[4]
144 209
210 def init(ui):
211 """create a repository"""
212 hg.repository(ui, ".", create=1)
213
214 def log(ui, repo, f):
215 f = relpath(repo, [f])[0]
216
217 r = repo.file(f)
218 for i in range(r.count()):
219 n = r.node(i)
220 (p1, p2) = r.parents(n)
221 (h, h1, h2) = map(hg.hex, (n, p1, p2))
222 (i1, i2) = map(r.rev, (p1, p2))
223 cr = r.linkrev(n)
224 cn = hg.hex(repo.changelog.node(cr))
225 print "rev: %4d:%s" % (i, h)
226 print "changeset: %4d:%s" % (cr, cn)
227 print "parents: %4d:%s" % (i1, h1)
228 if i2: print " %4d:%s" % (i2, h2)
229 changes = repo.changelog.read(repo.changelog.node(cr))
230 print "user: %s" % changes[1]
231 print "date: %s" % time.asctime(
232 time.localtime(float(changes[2].split(' ')[0])))
233 print "description:"
234 print changes[4].rstrip()
235 print
236
145 def parents(ui, repo, node = None): 237 def parents(ui, repo, node = None):
146 '''show the parents of the current working dir''' 238 '''show the parents of the current working dir'''
147 if node: 239 if node:
148 p = repo.changelog.parents(repo.lookup(hg.bin(node))) 240 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
149 else: 241 else:
151 243
152 for n in p: 244 for n in p:
153 if n != hg.nullid: 245 if n != hg.nullid:
154 ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n))) 246 ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n)))
155 247
156 def resolve(ui, repo, node = None): 248 def recover(ui, repo):
249 repo.recover()
250
251 def remove(ui, repo, file, *files):
252 """remove the specified files on the next commit"""
253 repo.remove(relpath(repo, (file,) + files))
254
255 def resolve(ui, repo, node=None):
157 '''merge a given node or the current tip into the working dir''' 256 '''merge a given node or the current tip into the working dir'''
158 if not node: 257 if not node:
159 node = repo.changelog.tip() 258 node = repo.changelog.tip()
160 else: 259 else:
161 node = repo.lookup(node) 260 node = repo.lookup(node)
162 repo.resolve(node) 261 repo.resolve(node)
163 262
263 def serve(ui, repo, **opts):
264 from mercurial import hgweb
265 hgweb.server(repo.root, opts["name"], opts["templates"],
266 opts["address"], opts["port"])
267
164 def status(ui, repo): 268 def status(ui, repo):
165 '''show changed files in the working directory 269 '''show changed files in the working directory
166 270
167 C = changed 271 C = changed
168 A = added 272 A = added
169 R = removed 273 R = removed
170 ? = not tracked''' 274 ? = not tracked'''
275
171 (c, a, d, u) = repo.diffdir(repo.root) 276 (c, a, d, u) = repo.diffdir(repo.root)
172 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) 277 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
173 278
174 for f in c: print "C", f 279 for f in c: print "C", f
175 for f in a: print "A", f 280 for f in a: print "A", f
176 for f in d: print "R", f 281 for f in d: print "R", f
177 for f in u: print "?", f 282 for f in u: print "?", f
178 283
284 def tip(ui, repo):
285 n = repo.changelog.tip()
286 t = repo.changelog.rev(n)
287 ui.status("%d:%s\n" % (t, hg.hex(n)))
288
179 def undo(ui, repo): 289 def undo(ui, repo):
180 repo.undo() 290 repo.undo()
181 291
182 table = { 292 table = {
183 "init": (init, [], 'hg init'), 293 "add": (add, [], "hg add [files]"),
184 "branch|clone": (branch, [], 'hg branch [path]'), 294 "addremove": (addremove, [], "hg addremove"),
185 "heads": (heads, [], 'hg heads'),
186 "help": (help, [], 'hg help [command]'),
187 "checkout|co": (checkout, [], 'hg checkout [changeset]'),
188 "ann|annotate": (annotate, 295 "ann|annotate": (annotate,
189 [('r', 'revision', '', 'revision'), 296 [('r', 'revision', '', 'revision'),
190 ('u', 'user', None, 'show user'), 297 ('u', 'user', None, 'show user'),
191 ('n', 'number', None, 'show revision number'), 298 ('n', 'number', None, 'show revision number'),
192 ('c', 'changeset', None, 'show changeset')], 299 ('c', 'changeset', None, 'show changeset')],
193 'hg annotate [-u] [-c] [-n] [-r id] [files]'), 300 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
301 "branch|clone": (branch, [], 'hg branch [path]'),
302 "checkout|co": (checkout, [], 'hg checkout [changeset]'),
303 "commit|ci": (commit, [], 'hg commit [files]'),
304 "diff": (diff, [('r', 'rev', [], 'revision')],
305 'hg diff [-r A] [-r B] [files]'),
306 "forget": (forget, [], "hg forget [files]"),
307 "heads": (heads, [], 'hg heads'),
308 "help": (help, [], 'hg help [command]'),
309 "init": (init, [], 'hg init'),
310 "log": (log, [], 'hg log <file>'),
194 "parents": (parents, [], 'hg parents [node]'), 311 "parents": (parents, [], 'hg parents [node]'),
312 "recover": (recover, [], "hg recover"),
313 "remove": (remove, [], "hg remove [files]"),
195 "resolve": (resolve, [], 'hg resolve [node]'), 314 "resolve": (resolve, [], 'hg resolve [node]'),
315 "serve": (serve, [('p', 'port', 8000, 'listen port'),
316 ('a', 'address', '', 'interface address'),
317 ('n', 'name', os.getcwd(), 'repository name'),
318 ('t', 'templates', "", 'template map')],
319 "hg serve [options]"),
196 "status": (status, [], 'hg status'), 320 "status": (status, [], 'hg status'),
321 "tip": (tip, [], 'hg tip'),
197 "undo": (undo, [], 'hg undo'), 322 "undo": (undo, [], 'hg undo'),
198 } 323 }
199 324
200 norepo = "init branch help" 325 norepo = "init branch help"
201 326