Show More
@@ -19,32 +19,6 b'' | |||
|
19 | 19 | import sys, os, time |
|
20 | 20 | from mercurial import hg, mdiff, fancyopts, ui, commands |
|
21 | 21 | |
|
22 | def help(): | |
|
23 | ui.status("""\ | |
|
24 | commands: | |
|
25 | ||
|
26 | add [files...] add the given files in the next commit | |
|
27 | addremove add all new files, delete all missing files | |
|
28 | annotate [files...] show changeset number per file line | |
|
29 | branch <path> create a branch of <path> in this directory | |
|
30 | checkout [changeset] checkout the latest or given changeset | |
|
31 | commit commit all changes to the repository | |
|
32 | diff [files...] diff working directory (or selected files) | |
|
33 | dump <file> [rev] dump the latest or given revision of a file | |
|
34 | dumpmanifest [rev] dump the latest or given revision of the manifest | |
|
35 | export <rev> dump the changeset header and diffs for a revision | |
|
36 | history show changeset history | |
|
37 | init create a new repository in this directory | |
|
38 | log <file> show revision history of a single file | |
|
39 | merge <path> merge changes from <path> into local repository | |
|
40 | recover rollback an interrupted transaction | |
|
41 | remove [files...] remove the given files in the next commit | |
|
42 | serve export the repository via HTTP | |
|
43 | status show new, missing, and changed files in working dir | |
|
44 | tags show current changeset tags | |
|
45 | undo undo the last transaction | |
|
46 | """) | |
|
47 | ||
|
48 | 22 | def filterfiles(list, files): |
|
49 | 23 | l = [ x for x in list if x in files ] |
|
50 | 24 | |
@@ -126,21 +100,6 b' relpath = None' | |||
|
126 | 100 | if os.getcwd() != repo.root: |
|
127 | 101 | relpath = os.getcwd()[len(repo.root) + 1: ] |
|
128 | 102 | |
|
129 | elif cmd == "add": | |
|
130 | repo.add(args) | |
|
131 | ||
|
132 | elif cmd == "forget": | |
|
133 | repo.forget(args) | |
|
134 | ||
|
135 | elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete": | |
|
136 | repo.remove(args) | |
|
137 | ||
|
138 | elif cmd == "commit" or cmd == "checkin" or cmd == "ci": | |
|
139 | if 1: | |
|
140 | if len(args) > 0: | |
|
141 | repo.commit(args) | |
|
142 | else: | |
|
143 | repo.commit() | |
|
144 | 103 | elif cmd == "rawcommit": |
|
145 | 104 | "raw commit interface" |
|
146 | 105 | rc = {} |
@@ -205,26 +164,6 b' elif cmd == "import" or cmd == "patch":' | |||
|
205 | 164 | raise "patch failed!" |
|
206 | 165 | repo.commit(files, text) |
|
207 | 166 | |
|
208 | elif cmd == "diff": | |
|
209 | revs = [] | |
|
210 | ||
|
211 | if args: | |
|
212 | doptions = {} | |
|
213 | opts = [('r', 'revision', [], 'revision')] | |
|
214 | args = fancyopts.fancyopts(args, opts, doptions, | |
|
215 | 'hg diff [options] [files]') | |
|
216 | revs = map(lambda x: repo.lookup(x), doptions['revision']) | |
|
217 | ||
|
218 | if len(revs) > 2: | |
|
219 | self.ui.warn("too many revisions to diff\n") | |
|
220 | sys.exit(1) | |
|
221 | ||
|
222 | if relpath: | |
|
223 | if not args: args = [ relpath ] | |
|
224 | else: args = [ os.path.join(relpath, x) for x in args ] | |
|
225 | ||
|
226 | diff(args, *revs) | |
|
227 | ||
|
228 | 167 | elif cmd == "export": |
|
229 | 168 | node = repo.lookup(args[0]) |
|
230 | 169 | prev, other = repo.changelog.parents(node) |
@@ -249,11 +188,6 b' elif cmd == "debugaddchangegroup":' | |||
|
249 | 188 | data = sys.stdin.read() |
|
250 | 189 | repo.addchangegroup(data) |
|
251 | 190 | |
|
252 | elif cmd == "addremove": | |
|
253 | (c, a, d, u) = repo.diffdir(repo.root) | |
|
254 | repo.add(a) | |
|
255 | repo.remove(d) | |
|
256 | ||
|
257 | 191 | elif cmd == "history": |
|
258 | 192 | for i in range(repo.changelog.count()): |
|
259 | 193 | n = repo.changelog.node(i) |
@@ -273,41 +207,6 b' elif cmd == "history":' | |||
|
273 | 207 | print "description:" |
|
274 | 208 | print changes[4] |
|
275 | 209 | |
|
276 | elif cmd == "tip": | |
|
277 | n = repo.changelog.tip() | |
|
278 | t = repo.changelog.rev(n) | |
|
279 | ui.status("%d:%s\n" % (t, hg.hex(n))) | |
|
280 | ||
|
281 | elif cmd == "log": | |
|
282 | ||
|
283 | if len(args) == 1: | |
|
284 | if relpath: | |
|
285 | args[0] = os.path.join(relpath, args[0]) | |
|
286 | ||
|
287 | r = repo.file(args[0]) | |
|
288 | for i in range(r.count()): | |
|
289 | n = r.node(i) | |
|
290 | (p1, p2) = r.parents(n) | |
|
291 | (h, h1, h2) = map(hg.hex, (n, p1, p2)) | |
|
292 | (i1, i2) = map(r.rev, (p1, p2)) | |
|
293 | cr = r.linkrev(n) | |
|
294 | cn = hg.hex(repo.changelog.node(cr)) | |
|
295 | print "rev: %4d:%s" % (i, h) | |
|
296 | print "changeset: %4d:%s" % (cr, cn) | |
|
297 | print "parents: %4d:%s" % (i1, h1) | |
|
298 | if i2: print " %4d:%s" % (i2, h2) | |
|
299 | changes = repo.changelog.read(repo.changelog.node(cr)) | |
|
300 | print "user: %s" % changes[1] | |
|
301 | print "date: %s" % time.asctime( | |
|
302 | time.localtime(float(changes[2].split(' ')[0]))) | |
|
303 | print "description:" | |
|
304 | print changes[4] | |
|
305 | ||
|
306 | elif len(args) > 1: | |
|
307 | print "too many args" | |
|
308 | else: | |
|
309 | print "missing filename" | |
|
310 | ||
|
311 | 210 | elif cmd == "dump": |
|
312 | 211 | if args: |
|
313 | 212 | r = repo.file(args[0]) |
@@ -384,9 +283,6 b' elif cmd == "tags":' | |||
|
384 | 283 | r = "?" |
|
385 | 284 | print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n)) |
|
386 | 285 | |
|
387 | elif cmd == "recover": | |
|
388 | repo.recover() | |
|
389 | ||
|
390 | 286 | elif cmd == "verify": |
|
391 | 287 | filelinkrevs = {} |
|
392 | 288 | filenodes = {} |
@@ -510,23 +406,6 b' elif cmd == "verify":' | |||
|
510 | 406 | ui.warn("%d integrity errors encountered!\n" % errors) |
|
511 | 407 | sys.exit(1) |
|
512 | 408 | |
|
513 | elif cmd == "serve": | |
|
514 | from mercurial import hgweb | |
|
515 | ||
|
516 | soptions = {} | |
|
517 | opts = [('p', 'port', 8000, 'listen port'), | |
|
518 | ('a', 'address', '', 'interface address'), | |
|
519 | ('n', 'name', os.getcwd(), 'repository name'), | |
|
520 | ('t', 'templates', "", 'template map') | |
|
521 | ] | |
|
522 | ||
|
523 | args = fancyopts.fancyopts(args, opts, soptions, | |
|
524 | 'hg serve [options]') | |
|
525 | ||
|
526 | hgweb.server(repo.root, soptions["name"], soptions["templates"], | |
|
527 | soptions["address"], soptions["port"]) | |
|
528 | ||
|
529 | 409 | else: |
|
530 | 410 | if cmd: ui.warn("unknown command\n\n") |
|
531 | help() | |
|
532 | 411 | sys.exit(1) |
@@ -1,27 +1,64 b'' | |||
|
1 | import os, re, traceback, sys, signal, time | |
|
1 | import os, re, traceback, sys, signal, time, mdiff | |
|
2 | 2 | from mercurial import fancyopts, ui, hg |
|
3 | 3 | |
|
4 | 4 | class UnknownCommand(Exception): pass |
|
5 | 5 | |
|
6 |
def filterfiles( |
|
|
7 |
l = [ x for x in |
|
|
6 | def filterfiles(filters, files): | |
|
7 | l = [ x for x in files if x in filters ] | |
|
8 | 8 | |
|
9 |
for |
|
|
10 |
if |
|
|
11 |
l += [ x for x in |
|
|
9 | for t in filters: | |
|
10 | if t and t[-1] != os.sep: t += os.sep | |
|
11 | l += [ x for x in files if x.startswith(t) ] | |
|
12 | 12 | return l |
|
13 | 13 | |
|
14 |
def relfilter(repo, |
|
|
14 | def relfilter(repo, files): | |
|
15 | 15 | if os.getcwd() != repo.root: |
|
16 | 16 | p = os.getcwd()[len(repo.root) + 1: ] |
|
17 |
return filterfiles(p, |
|
|
18 |
return |
|
|
17 | return filterfiles(p, files) | |
|
18 | return files | |
|
19 | 19 | |
|
20 | 20 | def relpath(repo, args): |
|
21 | 21 | if os.getcwd() != repo.root: |
|
22 | 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 | 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 | 63 | def help(ui, cmd=None): |
|
27 | 64 | '''show help''' |
@@ -59,28 +96,16 b' def help(ui, cmd=None):' | |||
|
59 | 96 | undo undo the last transaction |
|
60 | 97 | """) |
|
61 | 98 | |
|
62 | def init(ui): | |
|
63 | """create a repository""" | |
|
64 | hg.repository(ui, ".", create=1) | |
|
65 | ||
|
66 | def branch(ui, path): | |
|
67 | '''branch from a local repository''' | |
|
68 | # this should eventually support remote repos | |
|
69 | os.system("cp -al %s/.hg .hg" % path) | |
|
99 | def add(ui, repo, file, *files): | |
|
100 | '''add the specified files on the next commit''' | |
|
101 | repo.add(relpath(repo, (file,) + files)) | |
|
70 | 102 | |
|
71 | def checkout(ui, repo, changeset=None): | |
|
72 | '''checkout a given changeset or the current tip''' | |
|
103 | def addremove(ui, repo): | |
|
73 | 104 | (c, a, d, u) = repo.diffdir(repo.root) |
|
74 | if c or a or d: | |
|
75 | ui.warn("aborting (outstanding changes in working directory)\n") | |
|
76 | sys.exit(1) | |
|
105 | repo.add(a) | |
|
106 | repo.remove(d) | |
|
77 | 107 | |
|
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): | |
|
108 | def annotate(u, repo, file, *files, **ops): | |
|
84 | 109 | def getnode(rev): |
|
85 | 110 | return hg.short(repo.changelog.node(rev)) |
|
86 | 111 | |
@@ -101,7 +126,6 b' def annotate(u, repo, *args, **ops):' | |||
|
101 | 126 | if not ops['user'] and not ops['changeset']: |
|
102 | 127 | ops['number'] = 1 |
|
103 | 128 | |
|
104 | args = relpath(repo, args) | |
|
105 | 129 | node = repo.dirstate.parents()[0] |
|
106 | 130 | if ops['revision']: |
|
107 | 131 | node = repo.changelog.lookup(ops['revision']) |
@@ -109,7 +133,7 b' def annotate(u, repo, *args, **ops):' | |||
|
109 | 133 | mmap = repo.manifest.read(change[0]) |
|
110 | 134 | maxuserlen = 0 |
|
111 | 135 | maxchangelen = 0 |
|
112 | for f in args: | |
|
136 | for f in relpath(repo, (file,) + files): | |
|
113 | 137 | lines = repo.file(f).annotate(mmap[f]) |
|
114 | 138 | pieces = [] |
|
115 | 139 | |
@@ -122,6 +146,47 b' def annotate(u, repo, *args, **ops):' | |||
|
122 | 146 | for p,l in zip(zip(*pieces), lines): |
|
123 | 147 | u.write(" ".join(p) + ": " + l[1]) |
|
124 | 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)) | |
|
189 | ||
|
125 | 190 | def heads(ui, repo): |
|
126 | 191 | '''show current repository heads''' |
|
127 | 192 | for n in repo.changelog.heads(): |
@@ -142,6 +207,33 b' def heads(ui, repo):' | |||
|
142 | 207 | print "description:" |
|
143 | 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 | ||
|
236 | ||
|
145 | 237 | def parents(ui, repo, node = None): |
|
146 | 238 | '''show the parents of the current working dir''' |
|
147 | 239 | if node: |
@@ -153,7 +245,14 b' def parents(ui, repo, node = None):' | |||
|
153 | 245 | if n != hg.nullid: |
|
154 | 246 | ui.write("%d:%s\n" % (repo.changelog.rev(n), hg.hex(n))) |
|
155 | 247 | |
|
156 |
def re |
|
|
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 | 256 | '''merge a given node or the current tip into the working dir''' |
|
158 | 257 | if not node: |
|
159 | 258 | node = repo.changelog.tip() |
@@ -161,13 +260,19 b' def resolve(ui, repo, node = None):' | |||
|
161 | 260 | node = repo.lookup(node) |
|
162 | 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 | 268 | def status(ui, repo): |
|
165 | 269 | '''show changed files in the working directory |
|
166 | 270 | |
|
167 | C = changed | |
|
168 | A = added | |
|
169 | R = removed | |
|
170 | ? = not tracked''' | |
|
271 | C = changed | |
|
272 | A = added | |
|
273 | R = removed | |
|
274 | ? = not tracked''' | |
|
275 | ||
|
171 | 276 | (c, a, d, u) = repo.diffdir(repo.root) |
|
172 | 277 | (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u)) |
|
173 | 278 | |
@@ -176,24 +281,44 b' R = removed' | |||
|
176 | 281 | for f in d: print "R", f |
|
177 | 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 | 289 | def undo(ui, repo): |
|
180 | 290 | repo.undo() |
|
181 | 291 | |
|
182 | 292 | table = { |
|
183 | "init": (init, [], 'hg init'), | |
|
184 | "branch|clone": (branch, [], 'hg branch [path]'), | |
|
185 | "heads": (heads, [], 'hg heads'), | |
|
186 | "help": (help, [], 'hg help [command]'), | |
|
187 | "checkout|co": (checkout, [], 'hg checkout [changeset]'), | |
|
293 | "add": (add, [], "hg add [files]"), | |
|
294 | "addremove": (addremove, [], "hg addremove"), | |
|
188 | 295 | "ann|annotate": (annotate, |
|
189 | 296 | [('r', 'revision', '', 'revision'), |
|
190 | 297 | ('u', 'user', None, 'show user'), |
|
191 | 298 | ('n', 'number', None, 'show revision number'), |
|
192 | 299 | ('c', 'changeset', None, 'show changeset')], |
|
193 | 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 | 311 | "parents": (parents, [], 'hg parents [node]'), |
|
312 | "recover": (recover, [], "hg recover"), | |
|
313 | "remove": (remove, [], "hg remove [files]"), | |
|
195 | 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 | 320 | "status": (status, [], 'hg status'), |
|
321 | "tip": (tip, [], 'hg tip'), | |
|
197 | 322 | "undo": (undo, [], 'hg undo'), |
|
198 | 323 | } |
|
199 | 324 |
General Comments 0
You need to be logged in to leave comments.
Login now