Mercurial > hg > mercurial-crew-with-dirclash
annotate contrib/hgit @ 596:9a8daeff0ffa
A bunch of parsing/help updates
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
A bunch of parsing/help updates
more explanation of how to get non-basic commands
shorten names of debug functions and add docstrings
add undo long docstring
promote anotate, export, and revert
make the global opts array global
refactor parsing
kill two unused arguments to fancyopts
update test-help
manifest hash: 459ae2273aaf54f71b4576677a681dc53ab2908c
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.0 (GNU/Linux)
iD8DBQFCyEDhywK+sNU5EO8RAr0DAJ9LTu8Fc2quLRtuwLPTQzWqlOJWKwCbBpZk
pnMkYnshsutVYljcil1P46I=
=Sleg
-----END PGP SIGNATURE-----
author | mpm@selenic.com |
---|---|
date | Sun, 03 Jul 2005 11:47:45 -0800 |
parents | 688d03d6997a |
children | dda258572847 8db4d406b3d3 |
rev | line source |
---|---|
267 | 1 #!/usr/bin/env python |
2 # | |
3 # Minimal support for git commands on an hg repository | |
4 # | |
5 # Copyright 2005 Chris Mason <mason@suse.com> | |
6 # | |
7 # This software may be used and distributed according to the terms | |
8 # of the GNU General Public License, incorporated herein by reference. | |
9 | |
10 import time, sys, signal | |
11 from mercurial import hg, mdiff, fancyopts, commands, ui | |
12 | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
357
diff
changeset
|
13 def difftree(args, ui, repo): |
267 | 14 def __difftree(repo, files = None, node1 = None, node2 = None): |
334 | 15 def date(c): |
16 return time.asctime(time.gmtime(float(c[2].split(' ')[0]))) | |
267 | 17 |
334 | 18 if node2: |
19 change = repo.changelog.read(node2) | |
20 mmap2 = repo.manifest.read(change[0]) | |
21 (c, a, d) = repo.diffrevs(node1, node2) | |
22 def read(f): return repo.file(f).read(mmap2[f]) | |
23 date2 = date(change) | |
24 else: | |
25 date2 = time.asctime() | |
26 (c, a, d, u) = repo.diffdir(repo.root, node1) | |
27 if not node1: | |
28 node1 = repo.dirstate.parents()[0] | |
29 def read(f): return file(os.path.join(repo.root, f)).read() | |
267 | 30 |
334 | 31 change = repo.changelog.read(node1) |
32 mmap = repo.manifest.read(change[0]) | |
33 date1 = date(change) | |
34 empty = "0" * 40; | |
267 | 35 |
334 | 36 if files: |
37 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d)) | |
267 | 38 |
334 | 39 for f in c: |
40 # TODO get file permissions | |
406
d8abb687d501
[PATCH] Using monotone-viz/git-viz with mercurial
mpm@selenic.com
parents:
396
diff
changeset
|
41 print ":100664 100664 %s %s M\t%s\t%s" % (hg.hex(mmap[f]), |
334 | 42 hg.hex(mmap2[f]), f, f) |
43 for f in a: | |
406
d8abb687d501
[PATCH] Using monotone-viz/git-viz with mercurial
mpm@selenic.com
parents:
396
diff
changeset
|
44 print ":000000 100664 %s %s N\t%s\t%s" % (empty, hg.hex(mmap2[f]), f, f) |
334 | 45 for f in d: |
406
d8abb687d501
[PATCH] Using monotone-viz/git-viz with mercurial
mpm@selenic.com
parents:
396
diff
changeset
|
46 print ":100664 000000 %s %s D\t%s\t%s" % (hg.hex(mmap[f]), empty, f, f) |
267 | 47 ## |
48 | |
49 revs = [] | |
50 if args: | |
334 | 51 doptions = {} |
52 opts = [('p', 'patch', None, 'patch'), | |
53 ('r', 'recursive', None, 'recursive')] | |
54 args = fancyopts.fancyopts(args, opts, doptions, | |
267 | 55 'hg diff-tree [options] sha1 sha1') |
56 | |
57 if len(args) < 2: | |
334 | 58 help() |
267 | 59 sys.exit(1) |
60 revs.append(repo.lookup(args[0])) | |
61 revs.append(repo.lookup(args[1])) | |
62 args = args[2:] | |
63 if doptions['patch']: | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
357
diff
changeset
|
64 commands.dodiff(ui, repo, "", args, *revs) |
267 | 65 else: |
334 | 66 __difftree(repo, args, *revs) |
267 | 67 |
68 def catcommit(repo, n, prefix): | |
69 nlprefix = '\n' + prefix; | |
70 changes = repo.changelog.read(n) | |
71 (p1, p2) = repo.changelog.parents(n) | |
72 (h, h1, h2) = map(hg.hex, (n, p1, p2)) | |
73 (i1, i2) = map(repo.changelog.rev, (p1, p2)) | |
74 print "tree %s" % (h) | |
75 if i1 != -1: print "%sparent %s" % (prefix, h1) | |
76 if i2 != -1: print "%sparent %s" % (prefix, h2) | |
77 date_ar = changes[2].split(' ') | |
78 date = int(float(date_ar[0])) | |
79 print "%sauthor <%s> %s %s" % (prefix, changes[1], date, date_ar[1]) | |
80 print "%scommitter <%s> %s %s" % (prefix, changes[1], date, date_ar[1]) | |
81 print prefix | |
82 if prefix != "": | |
334 | 83 print "%s%s" % (prefix, changes[4].replace('\n', nlprefix).strip()) |
267 | 84 else: |
334 | 85 print changes[4] |
267 | 86 |
87 def catfile(args, ui, repo): | |
88 doptions = {} | |
89 opts = [('s', 'stdin', None, 'stdin')] | |
90 args = fancyopts.fancyopts(args, opts, doptions, | |
334 | 91 'hg cat-file type sha1') |
267 | 92 |
93 # in stdin mode, every line except the commit is prefixed with two | |
94 # spaces. This way the our caller can find the commit without magic | |
95 # strings | |
96 # | |
97 prefix = "" | |
98 if doptions['stdin']: | |
334 | 99 try: |
100 (type, r) = raw_input().split(' '); | |
101 prefix = " " | |
102 except EOFError: | |
103 return | |
267 | 104 |
105 else: | |
334 | 106 if len(args) < 2: |
107 help() | |
108 sys.exit(1) | |
267 | 109 type = args[0] |
334 | 110 r = args[1] |
267 | 111 |
112 while r: | |
334 | 113 if type != "commit": |
114 sys.stderr.write("aborting hg cat-file only understands commits\n") | |
115 sys.exit(1); | |
116 n = repo.changelog.lookup(r) | |
117 catcommit(repo, n, prefix) | |
118 if doptions['stdin']: | |
119 try: | |
120 (type, r) = raw_input().split(' '); | |
121 except EOFError: | |
122 break | |
123 else: | |
124 break | |
267 | 125 |
126 # git rev-tree is a confusing thing. You can supply a number of | |
127 # commit sha1s on the command line, and it walks the commit history | |
128 # telling you which commits are reachable from the supplied ones via | |
129 # a bitmask based on arg position. | |
130 # you can specify a commit to stop at by starting the sha1 with ^ | |
356 | 131 def revtree(args, repo, full="tree", maxnr=0): |
267 | 132 # calculate and return the reachability bitmask for sha |
133 def is_reachable(ar, reachable, sha): | |
334 | 134 if len(ar) == 0: |
135 return 1 | |
136 mask = 0 | |
137 for i in range(len(ar)): | |
138 if sha in reachable[i]: | |
139 mask |= 1 << i | |
267 | 140 |
334 | 141 return mask |
267 | 142 |
143 reachable = [] | |
144 stop_sha1 = [] | |
145 want_sha1 = [] | |
356 | 146 count = 0 |
267 | 147 |
148 # figure out which commits they are asking for and which ones they | |
149 # want us to stop on | |
150 for i in range(len(args)): | |
151 if args[i].count('^'): | |
334 | 152 s = args[i].split('^')[1] |
153 stop_sha1.append(repo.changelog.lookup(s)) | |
154 want_sha1.append(s) | |
155 elif args[i] != 'HEAD': | |
156 want_sha1.append(args[i]) | |
356 | 157 |
267 | 158 # calculate the graph for the supplied commits |
159 for i in range(len(want_sha1)): | |
334 | 160 reachable.append({}); |
161 n = repo.changelog.lookup(want_sha1[i]); | |
162 visit = [n]; | |
163 reachable[i][n] = 1 | |
164 while visit: | |
165 n = visit.pop(0) | |
166 if n in stop_sha1: | |
167 break | |
168 for p in repo.changelog.parents(n): | |
169 if p not in reachable[i]: | |
170 reachable[i][p] = 1 | |
171 visit.append(p) | |
172 if p in stop_sha1: | |
173 break | |
356 | 174 |
267 | 175 # walk the repository looking for commits that are in our |
176 # reachability graph | |
356 | 177 for i in range(repo.changelog.count()-1, -1, -1): |
334 | 178 n = repo.changelog.node(i) |
179 mask = is_reachable(want_sha1, reachable, n) | |
180 if mask: | |
356 | 181 if not full: |
182 print hg.hex(n) | |
183 elif full is "commit": | |
184 print hg.hex(n) | |
185 catcommit(repo, n, ' ') | |
186 else: | |
187 changes = repo.changelog.read(n) | |
188 (p1, p2) = repo.changelog.parents(n) | |
189 (h, h1, h2) = map(hg.hex, (n, p1, p2)) | |
190 (i1, i2) = map(repo.changelog.rev, (p1, p2)) | |
267 | 191 |
356 | 192 date = changes[2].split(' ')[0] |
193 print "%s %s:%s" % (date, h, mask), | |
194 mask = is_reachable(want_sha1, reachable, p1) | |
195 if i1 != -1 and mask > 0: | |
196 print "%s:%s " % (h1, mask), | |
197 mask = is_reachable(want_sha1, reachable, p2) | |
198 if i2 != -1 and mask > 0: | |
199 print "%s:%s " % (h2, mask), | |
200 print "" | |
201 if maxnr and count >= maxnr: | |
202 break | |
203 count += 1 | |
267 | 204 |
205 # git rev-list tries to order things by date, and has the ability to stop | |
206 # at a given commit without walking the whole repo. TODO add the stop | |
207 # parameter | |
208 def revlist(args, repo): | |
209 doptions = {} | |
356 | 210 opts = [('c', 'commit', None, 'commit'), |
211 ('n', 'max-nr', 0, 'max-nr')] | |
267 | 212 args = fancyopts.fancyopts(args, opts, doptions, |
334 | 213 'hg rev-list') |
356 | 214 if doptions['commit']: |
215 full = "commit" | |
216 else: | |
217 full = None | |
218 for i in range(1, len(args)): | |
219 args[i] = '^' + args[i] | |
220 revtree(args, repo, full, doptions['max-nr']) | |
267 | 221 |
222 def catchterm(*args): | |
223 raise SignalInterrupt | |
224 | |
225 def help(): | |
226 sys.stderr.write("commands:\n") | |
227 sys.stderr.write(" hgit cat-file [type] sha1\n") | |
228 sys.stderr.write(" hgit diff-tree [-p] [-r] sha1 sha1\n") | |
229 sys.stderr.write(" hgit rev-tree [sha1 ... [^stop sha1]]\n") | |
230 sys.stderr.write(" hgit rev-list [-c]\n") | |
231 | |
232 cmd = sys.argv[1] | |
233 args = sys.argv[2:] | |
234 u = ui.ui() | |
235 signal.signal(signal.SIGTERM, catchterm) | |
236 repo = hg.repository(ui = u) | |
237 | |
238 if cmd == "diff-tree": | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
357
diff
changeset
|
239 difftree(args, u, repo) |
267 | 240 |
241 elif cmd == "cat-file": | |
396
8f8bb77d560e
Show revisions in diffs like CVS, based on a patch from Goffredo Baroncelli.
Thomas Arendsen Hein <thomas@intevation.de>
parents:
357
diff
changeset
|
242 catfile(args, u, repo) |
267 | 243 |
244 elif cmd == "rev-tree": | |
245 revtree(args, repo) | |
246 | |
247 elif cmd == "rev-list": | |
248 revlist(args, repo) | |
249 | |
250 elif cmd == "help": | |
251 help() | |
252 | |
253 else: | |
254 if cmd: sys.stderr.write("unknown command\n\n") | |
255 help() | |
256 sys.exit(1) | |
257 | |
258 sys.exit(0) |