##// END OF EJS Templates
hg merge: abort if there are outstanding changes in the working directory...
mpm@selenic.com -
r174:23057dc5 default
parent child Browse files
Show More
@@ -1,580 +1,585 b''
1 #!/usr/bin/env python
1 #!/usr/bin/env python
2 #
2 #
3 # mercurial - a minimal scalable distributed SCM
3 # mercurial - a minimal scalable distributed SCM
4 # v0.4f "jane dark"
4 # v0.4f "jane dark"
5 #
5 #
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
6 # Copyright 2005 Matt Mackall <mpm@selenic.com>
7 #
7 #
8 # This software may be used and distributed according to the terms
8 # This software may be used and distributed according to the terms
9 # of the GNU General Public License, incorporated herein by reference.
9 # of the GNU General Public License, incorporated herein by reference.
10
10
11 # the psyco compiler makes commits a bit faster
11 # the psyco compiler makes commits a bit faster
12 # and makes changegroup merge about 20 times slower!
12 # and makes changegroup merge about 20 times slower!
13 # try:
13 # try:
14 # import psyco
14 # import psyco
15 # psyco.full()
15 # psyco.full()
16 # except:
16 # except:
17 # pass
17 # pass
18
18
19 import sys, os, time
19 import sys, os, time
20 from mercurial import hg, mdiff, fancyopts
20 from mercurial import hg, mdiff, fancyopts
21
21
22 def help():
22 def help():
23 print """\
23 print """\
24 commands:
24 commands:
25
25
26 add [files...] add the given files in the next commit
26 add [files...] add the given files in the next commit
27 addremove add all new files, delete all missing files
27 addremove add all new files, delete all missing files
28 annotate [files...] show changeset number per file line
28 annotate [files...] show changeset number per file line
29 branch <path> create a branch of <path> in this directory
29 branch <path> create a branch of <path> in this directory
30 checkout [changeset] checkout the latest or given changeset
30 checkout [changeset] checkout the latest or given changeset
31 commit commit all changes to the repository
31 commit commit all changes to the repository
32 diff [files...] diff working directory (or selected files)
32 diff [files...] diff working directory (or selected files)
33 dump <file> [rev] dump the latest or given revision of a file
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
34 dumpmanifest [rev] dump the latest or given revision of the manifest
35 history show changeset history
35 history show changeset history
36 init create a new repository in this directory
36 init create a new repository in this directory
37 log <file> show revision history of a single file
37 log <file> show revision history of a single file
38 merge <path> merge changes from <path> into local repository
38 merge <path> merge changes from <path> into local repository
39 recover rollback an interrupted transaction
39 recover rollback an interrupted transaction
40 remove [files...] remove the given files in the next commit
40 remove [files...] remove the given files in the next commit
41 serve export the repository via HTTP
41 serve export the repository via HTTP
42 status show new, missing, and changed files in working dir
42 status show new, missing, and changed files in working dir
43 tags show current changeset tags
43 tags show current changeset tags
44 undo undo the last transaction
44 undo undo the last transaction
45 """
45 """
46
46
47 def filterfiles(list, files):
47 def filterfiles(list, files):
48 l = [ x for x in list if x in files ]
48 l = [ x for x in list if x in files ]
49
49
50 for f in files:
50 for f in files:
51 if f[-1] != os.sep: f += os.sep
51 if f[-1] != os.sep: f += os.sep
52 l += [ x for x in list if x.startswith(f) ]
52 l += [ x for x in list if x.startswith(f) ]
53 return l
53 return l
54
54
55 def diff(files = None, node1 = None, node2 = None):
55 def diff(files = None, node1 = None, node2 = None):
56 def date(c):
56 def date(c):
57 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
57 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
58
58
59 if node2:
59 if node2:
60 change = repo.changelog.read(node2)
60 change = repo.changelog.read(node2)
61 mmap2 = repo.manifest.read(change[0])
61 mmap2 = repo.manifest.read(change[0])
62 (c, a, d) = repo.diffrevs(node1, node2)
62 (c, a, d) = repo.diffrevs(node1, node2)
63 def read(f): return repo.file(f).read(mmap2[f])
63 def read(f): return repo.file(f).read(mmap2[f])
64 date2 = date(change)
64 date2 = date(change)
65 else:
65 else:
66 date2 = time.asctime()
66 date2 = time.asctime()
67 if not node1:
67 if not node1:
68 node1 = repo.current
68 node1 = repo.current
69 (c, a, d) = repo.diffdir(repo.root, node1)
69 (c, a, d) = repo.diffdir(repo.root, node1)
70 a = [] # ignore unknown files in repo, by popular request
70 a = [] # ignore unknown files in repo, by popular request
71 def read(f): return file(os.path.join(repo.root, f)).read()
71 def read(f): return file(os.path.join(repo.root, f)).read()
72
72
73 change = repo.changelog.read(node1)
73 change = repo.changelog.read(node1)
74 mmap = repo.manifest.read(change[0])
74 mmap = repo.manifest.read(change[0])
75 date1 = date(change)
75 date1 = date(change)
76
76
77 if files:
77 if files:
78 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
78 c, a, d = map(lambda x: filterfiles(x, files), (c, a, d))
79
79
80 for f in c:
80 for f in c:
81 to = ""
81 to = ""
82 if mmap.has_key(f):
82 if mmap.has_key(f):
83 to = repo.file(f).read(mmap[f])
83 to = repo.file(f).read(mmap[f])
84 tn = read(f)
84 tn = read(f)
85 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
85 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
86 for f in a:
86 for f in a:
87 to = ""
87 to = ""
88 tn = read(f)
88 tn = read(f)
89 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
89 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
90 for f in d:
90 for f in d:
91 to = repo.file(f).read(mmap[f])
91 to = repo.file(f).read(mmap[f])
92 tn = ""
92 tn = ""
93 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
93 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f))
94
94
95 options = {}
95 options = {}
96 opts = [('v', 'verbose', None, 'verbose'),
96 opts = [('v', 'verbose', None, 'verbose'),
97 ('d', 'debug', None, 'debug'),
97 ('d', 'debug', None, 'debug'),
98 ('q', 'quiet', None, 'quiet'),
98 ('q', 'quiet', None, 'quiet'),
99 ('y', 'noninteractive', None, 'run non-interactively'),
99 ('y', 'noninteractive', None, 'run non-interactively'),
100 ]
100 ]
101
101
102 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
102 args = fancyopts.fancyopts(sys.argv[1:], opts, options,
103 'hg [options] <command> [command options] [files]')
103 'hg [options] <command> [command options] [files]')
104
104
105 try:
105 try:
106 cmd = args[0]
106 cmd = args[0]
107 args = args[1:]
107 args = args[1:]
108 except:
108 except:
109 cmd = ""
109 cmd = ""
110
110
111 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
111 ui = hg.ui(options["verbose"], options["debug"], options["quiet"],
112 not options["noninteractive"])
112 not options["noninteractive"])
113
113
114 if cmd == "init":
114 if cmd == "init":
115 repo = hg.repository(ui, ".", create=1)
115 repo = hg.repository(ui, ".", create=1)
116 sys.exit(0)
116 sys.exit(0)
117 elif cmd == "branch" or cmd == "clone":
117 elif cmd == "branch" or cmd == "clone":
118 os.system("cp -al %s/.hg .hg" % args[0])
118 os.system("cp -al %s/.hg .hg" % args[0])
119 sys.exit(0)
119 sys.exit(0)
120 elif cmd == "help":
120 elif cmd == "help":
121 help()
121 help()
122 sys.exit(0)
122 sys.exit(0)
123 else:
123 else:
124 try:
124 try:
125 repo = hg.repository(ui=ui)
125 repo = hg.repository(ui=ui)
126 except IOError:
126 except IOError:
127 ui.warn("Unable to open repository\n")
127 ui.warn("Unable to open repository\n")
128 sys.exit(0)
128 sys.exit(0)
129
129
130 relpath = None
130 relpath = None
131 if os.getcwd() != repo.root:
131 if os.getcwd() != repo.root:
132 relpath = os.getcwd()[len(repo.root) + 1: ]
132 relpath = os.getcwd()[len(repo.root) + 1: ]
133
133
134 if cmd == "checkout" or cmd == "co":
134 if cmd == "checkout" or cmd == "co":
135 node = repo.changelog.tip()
135 node = repo.changelog.tip()
136 if args:
136 if args:
137 node = repo.lookup(args[0])
137 node = repo.lookup(args[0])
138 repo.checkout(node)
138 repo.checkout(node)
139
139
140 elif cmd == "add":
140 elif cmd == "add":
141 repo.add(args)
141 repo.add(args)
142
142
143 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
143 elif cmd == "remove" or cmd == "rm" or cmd == "del" or cmd == "delete":
144 repo.remove(args)
144 repo.remove(args)
145
145
146 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
146 elif cmd == "commit" or cmd == "checkin" or cmd == "ci":
147 if 1:
147 if 1:
148 if len(args) > 0:
148 if len(args) > 0:
149 repo.commit(repo.current, args)
149 repo.commit(repo.current, args)
150 else:
150 else:
151 repo.commit(repo.current)
151 repo.commit(repo.current)
152
152
153 elif cmd == "import" or cmd == "patch":
153 elif cmd == "import" or cmd == "patch":
154 try:
154 try:
155 import psyco
155 import psyco
156 psyco.full()
156 psyco.full()
157 except:
157 except:
158 pass
158 pass
159
159
160 ioptions = {}
160 ioptions = {}
161 opts = [('p', 'strip', 1, 'path strip'),
161 opts = [('p', 'strip', 1, 'path strip'),
162 ('b', 'base', "", 'base path'),
162 ('b', 'base', "", 'base path'),
163 ('q', 'quiet', "", 'silence diff')
163 ('q', 'quiet', "", 'silence diff')
164 ]
164 ]
165
165
166 args = fancyopts.fancyopts(args, opts, ioptions,
166 args = fancyopts.fancyopts(args, opts, ioptions,
167 'hg import [options] <patch names>')
167 'hg import [options] <patch names>')
168 d = ioptions["base"]
168 d = ioptions["base"]
169 strip = ioptions["strip"]
169 strip = ioptions["strip"]
170 quiet = ioptions["quiet"] and "> /dev/null" or ""
170 quiet = ioptions["quiet"] and "> /dev/null" or ""
171
171
172 for patch in args:
172 for patch in args:
173 ui.status("applying %s\n" % patch)
173 ui.status("applying %s\n" % patch)
174 pf = os.path.join(d, patch)
174 pf = os.path.join(d, patch)
175
175
176 text = ""
176 text = ""
177 for l in file(pf):
177 for l in file(pf):
178 if l[:4] == "--- ": break
178 if l[:4] == "--- ": break
179 text += l
179 text += l
180
180
181 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
181 f = os.popen("lsdiff --strip %d %s" % (strip, pf))
182 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
182 files = filter(None, map(lambda x: x.rstrip(), f.read().splitlines()))
183 f.close()
183 f.close()
184
184
185 if files:
185 if files:
186 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
186 if os.system("patch -p%d < %s %s" % (strip, pf, quiet)):
187 raise "patch failed!"
187 raise "patch failed!"
188 repo.commit(repo.current, files, text)
188 repo.commit(repo.current, files, text)
189
189
190 elif cmd == "status":
190 elif cmd == "status":
191 (c, a, d) = repo.diffdir(repo.root, repo.current)
191 (c, a, d) = repo.diffdir(repo.root, repo.current)
192 if relpath:
192 if relpath:
193 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
193 (c, a, d) = map(lambda x: filterfiles(x, [ relpath ]), (c, a, d))
194
194
195 for f in c: print "C", f
195 for f in c: print "C", f
196 for f in a: print "?", f
196 for f in a: print "?", f
197 for f in d: print "R", f
197 for f in d: print "R", f
198
198
199 elif cmd == "diff":
199 elif cmd == "diff":
200 revs = []
200 revs = []
201
201
202 if args:
202 if args:
203 doptions = {}
203 doptions = {}
204 opts = [('r', 'revision', [], 'revision')]
204 opts = [('r', 'revision', [], 'revision')]
205 args = fancyopts.fancyopts(args, opts, doptions,
205 args = fancyopts.fancyopts(args, opts, doptions,
206 'hg diff [options] [files]')
206 'hg diff [options] [files]')
207 revs = map(lambda x: repo.lookup(x), doptions['revision'])
207 revs = map(lambda x: repo.lookup(x), doptions['revision'])
208
208
209 if len(revs) > 2:
209 if len(revs) > 2:
210 self.ui.warn("too many revisions to diff\n")
210 self.ui.warn("too many revisions to diff\n")
211 sys.exit(1)
211 sys.exit(1)
212
212
213 if relpath:
213 if relpath:
214 if not args: args = [ relpath ]
214 if not args: args = [ relpath ]
215 else: args = [ os.path.join(relpath, x) for x in args ]
215 else: args = [ os.path.join(relpath, x) for x in args ]
216
216
217 diff(args, *revs)
217 diff(args, *revs)
218
218
219 elif cmd == "annotate":
219 elif cmd == "annotate":
220 bcache = {}
220 bcache = {}
221
221
222 def getnode(rev):
222 def getnode(rev):
223 return hg.short(repo.changelog.node(rev))
223 return hg.short(repo.changelog.node(rev))
224
224
225 def getname(rev):
225 def getname(rev):
226 try:
226 try:
227 return bcache[rev]
227 return bcache[rev]
228 except KeyError:
228 except KeyError:
229 cl = repo.changelog.read(repo.changelog.node(rev))
229 cl = repo.changelog.read(repo.changelog.node(rev))
230 name = cl[1]
230 name = cl[1]
231 f = name.find('@')
231 f = name.find('@')
232 if f >= 0:
232 if f >= 0:
233 name = name[:f]
233 name = name[:f]
234 bcache[rev] = name
234 bcache[rev] = name
235 return name
235 return name
236
236
237 aoptions = {}
237 aoptions = {}
238 opts = [('r', 'revision', '', 'revision'),
238 opts = [('r', 'revision', '', 'revision'),
239 ('u', 'user', None, 'show user'),
239 ('u', 'user', None, 'show user'),
240 ('n', 'number', None, 'show revision number'),
240 ('n', 'number', None, 'show revision number'),
241 ('c', 'changeset', None, 'show changeset')]
241 ('c', 'changeset', None, 'show changeset')]
242
242
243 args = fancyopts.fancyopts(args, opts, aoptions,
243 args = fancyopts.fancyopts(args, opts, aoptions,
244 'hg annotate [-u] [-c] [-n] [-r id] [files]')
244 'hg annotate [-u] [-c] [-n] [-r id] [files]')
245
245
246 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
246 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
247 if not aoptions['user'] and not aoptions['changeset']:
247 if not aoptions['user'] and not aoptions['changeset']:
248 aoptions['number'] = 1
248 aoptions['number'] = 1
249
249
250 if args:
250 if args:
251 if relpath: args = [ os.path.join(relpath, x) for x in args ]
251 if relpath: args = [ os.path.join(relpath, x) for x in args ]
252 node = repo.current
252 node = repo.current
253 if aoptions['revision']:
253 if aoptions['revision']:
254 node = repo.changelog.lookup(aoptions['revision'])
254 node = repo.changelog.lookup(aoptions['revision'])
255 change = repo.changelog.read(node)
255 change = repo.changelog.read(node)
256 mmap = repo.manifest.read(change[0])
256 mmap = repo.manifest.read(change[0])
257 maxuserlen = 0
257 maxuserlen = 0
258 maxchangelen = 0
258 maxchangelen = 0
259 for f in args:
259 for f in args:
260 lines = repo.file(f).annotate(mmap[f])
260 lines = repo.file(f).annotate(mmap[f])
261 pieces = []
261 pieces = []
262
262
263 for o, f in opmap:
263 for o, f in opmap:
264 if aoptions[o]:
264 if aoptions[o]:
265 l = [ f(n) for n,t in lines ]
265 l = [ f(n) for n,t in lines ]
266 m = max(map(len, l))
266 m = max(map(len, l))
267 pieces.append([ "%*s" % (m, x) for x in l])
267 pieces.append([ "%*s" % (m, x) for x in l])
268
268
269 for p,l in zip(zip(*pieces), lines):
269 for p,l in zip(zip(*pieces), lines):
270 sys.stdout.write(" ".join(p) + ": " + l[1])
270 sys.stdout.write(" ".join(p) + ": " + l[1])
271
271
272 elif cmd == "export":
272 elif cmd == "export":
273 node = repo.lookup(args[0])
273 node = repo.lookup(args[0])
274 prev, other = repo.changelog.parents(node)
274 prev, other = repo.changelog.parents(node)
275 change = repo.changelog.read(node)
275 change = repo.changelog.read(node)
276 print "# HG changeset patch"
276 print "# HG changeset patch"
277 print "# User %s" % change[1]
277 print "# User %s" % change[1]
278 print "# Node ID %s" % hg.hex(node)
278 print "# Node ID %s" % hg.hex(node)
279 print "# Parent %s" % hg.hex(prev)
279 print "# Parent %s" % hg.hex(prev)
280 print
280 print
281 if other != hg.nullid:
281 if other != hg.nullid:
282 print "# Parent %s" % hg.hex(other)
282 print "# Parent %s" % hg.hex(other)
283 print change[4]
283 print change[4]
284
284
285 diff(None, prev, node)
285 diff(None, prev, node)
286
286
287 elif cmd == "debugchangegroup":
287 elif cmd == "debugchangegroup":
288 newer = repo.newer(map(repo.lookup, args))
288 newer = repo.newer(map(repo.lookup, args))
289 for chunk in repo.changegroup(newer):
289 for chunk in repo.changegroup(newer):
290 sys.stdout.write(chunk)
290 sys.stdout.write(chunk)
291
291
292 elif cmd == "debugaddchangegroup":
292 elif cmd == "debugaddchangegroup":
293 data = sys.stdin.read()
293 data = sys.stdin.read()
294 repo.addchangegroup(data)
294 repo.addchangegroup(data)
295
295
296 elif cmd == "addremove":
296 elif cmd == "addremove":
297 (c, a, d) = repo.diffdir(repo.root, repo.current)
297 (c, a, d) = repo.diffdir(repo.root, repo.current)
298 repo.add(a)
298 repo.add(a)
299 repo.remove(d)
299 repo.remove(d)
300
300
301 elif cmd == "history":
301 elif cmd == "history":
302 for i in range(repo.changelog.count()):
302 for i in range(repo.changelog.count()):
303 n = repo.changelog.node(i)
303 n = repo.changelog.node(i)
304 changes = repo.changelog.read(n)
304 changes = repo.changelog.read(n)
305 (p1, p2) = repo.changelog.parents(n)
305 (p1, p2) = repo.changelog.parents(n)
306 (h, h1, h2) = map(hg.hex, (n, p1, p2))
306 (h, h1, h2) = map(hg.hex, (n, p1, p2))
307 (i1, i2) = map(repo.changelog.rev, (p1, p2))
307 (i1, i2) = map(repo.changelog.rev, (p1, p2))
308 print "rev: %4d:%s" % (i, h)
308 print "rev: %4d:%s" % (i, h)
309 print "parents: %4d:%s" % (i1, h1)
309 print "parents: %4d:%s" % (i1, h1)
310 if i2: print " %4d:%s" % (i2, h2)
310 if i2: print " %4d:%s" % (i2, h2)
311 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
311 print "manifest: %4d:%s" % (repo.manifest.rev(changes[0]),
312 hg.hex(changes[0]))
312 hg.hex(changes[0]))
313 print "user:", changes[1]
313 print "user:", changes[1]
314 print "date:", time.asctime(
314 print "date:", time.asctime(
315 time.localtime(float(changes[2].split(' ')[0])))
315 time.localtime(float(changes[2].split(' ')[0])))
316 if ui.verbose: print "files:", " ".join(changes[3])
316 if ui.verbose: print "files:", " ".join(changes[3])
317 print "description:"
317 print "description:"
318 print changes[4]
318 print changes[4]
319
319
320 elif cmd == "tip":
320 elif cmd == "tip":
321 n = repo.changelog.tip()
321 n = repo.changelog.tip()
322 t = repo.changelog.rev(n)
322 t = repo.changelog.rev(n)
323 ui.status("%d:%s\n" % (t, hg.hex(n)))
323 ui.status("%d:%s\n" % (t, hg.hex(n)))
324
324
325 elif cmd == "log":
325 elif cmd == "log":
326
326
327 if len(args) == 1:
327 if len(args) == 1:
328 if relpath:
328 if relpath:
329 args[0] = os.path.join(relpath, args[0])
329 args[0] = os.path.join(relpath, args[0])
330
330
331 r = repo.file(args[0])
331 r = repo.file(args[0])
332 for i in range(r.count()):
332 for i in range(r.count()):
333 n = r.node(i)
333 n = r.node(i)
334 (p1, p2) = r.parents(n)
334 (p1, p2) = r.parents(n)
335 (h, h1, h2) = map(hg.hex, (n, p1, p2))
335 (h, h1, h2) = map(hg.hex, (n, p1, p2))
336 (i1, i2) = map(r.rev, (p1, p2))
336 (i1, i2) = map(r.rev, (p1, p2))
337 cr = r.linkrev(n)
337 cr = r.linkrev(n)
338 cn = hg.hex(repo.changelog.node(cr))
338 cn = hg.hex(repo.changelog.node(cr))
339 print "rev: %4d:%s" % (i, h)
339 print "rev: %4d:%s" % (i, h)
340 print "changeset: %4d:%s" % (cr, cn)
340 print "changeset: %4d:%s" % (cr, cn)
341 print "parents: %4d:%s" % (i1, h1)
341 print "parents: %4d:%s" % (i1, h1)
342 if i2: print " %4d:%s" % (i2, h2)
342 if i2: print " %4d:%s" % (i2, h2)
343 changes = repo.changelog.read(repo.changelog.node(cr))
343 changes = repo.changelog.read(repo.changelog.node(cr))
344 print "user: %s" % changes[1]
344 print "user: %s" % changes[1]
345 print "date: %s" % time.asctime(
345 print "date: %s" % time.asctime(
346 time.localtime(float(changes[2].split(' ')[0])))
346 time.localtime(float(changes[2].split(' ')[0])))
347 print "description:"
347 print "description:"
348 print changes[4]
348 print changes[4]
349 print
349 print
350 elif len(args) > 1:
350 elif len(args) > 1:
351 print "too many args"
351 print "too many args"
352 else:
352 else:
353 print "missing filename"
353 print "missing filename"
354
354
355 elif cmd == "dump":
355 elif cmd == "dump":
356 if args:
356 if args:
357 r = repo.file(args[0])
357 r = repo.file(args[0])
358 n = r.tip()
358 n = r.tip()
359 if len(args) > 1: n = r.lookup(args[1])
359 if len(args) > 1: n = r.lookup(args[1])
360 sys.stdout.write(r.read(n))
360 sys.stdout.write(r.read(n))
361 else:
361 else:
362 print "missing filename"
362 print "missing filename"
363
363
364 elif cmd == "dumpmanifest":
364 elif cmd == "dumpmanifest":
365 n = repo.manifest.tip()
365 n = repo.manifest.tip()
366 if len(args) > 0:
366 if len(args) > 0:
367 n = repo.manifest.lookup(args[0])
367 n = repo.manifest.lookup(args[0])
368 m = repo.manifest.read(n)
368 m = repo.manifest.read(n)
369 files = m.keys()
369 files = m.keys()
370 files.sort()
370 files.sort()
371
371
372 for f in files:
372 for f in files:
373 print hg.hex(m[f]), f
373 print hg.hex(m[f]), f
374
374
375 elif cmd == "debugprompt":
375 elif cmd == "debugprompt":
376 print ui.prompt(args[0], args[1], args[2])
376 print ui.prompt(args[0], args[1], args[2])
377
377
378 elif cmd == "debughash":
378 elif cmd == "debughash":
379 f = repo.file(args[0])
379 f = repo.file(args[0])
380 print f.encodepath(args[0])
380 print f.encodepath(args[0])
381
381
382 elif cmd == "debugindex":
382 elif cmd == "debugindex":
383 if ".hg" not in args[0]:
383 if ".hg" not in args[0]:
384 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
384 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
385
385
386 r = hg.revlog(open, args[0], "")
386 r = hg.revlog(open, args[0], "")
387 print " rev offset length base linkrev"+\
387 print " rev offset length base linkrev"+\
388 " p1 p2 nodeid"
388 " p1 p2 nodeid"
389 for i in range(r.count()):
389 for i in range(r.count()):
390 e = r.index[i]
390 e = r.index[i]
391 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
391 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
392 i, e[0], e[1], e[2], e[3],
392 i, e[0], e[1], e[2], e[3],
393 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
393 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
394
394
395 elif cmd == "debugindexdot":
395 elif cmd == "debugindexdot":
396 if ".hg" not in args[0]:
396 if ".hg" not in args[0]:
397 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
397 args[0] = ".hg/data/" + repo.file(args[0]).encodepath(args[0]) + "i"
398
398
399 r = hg.revlog(open, args[0], "")
399 r = hg.revlog(open, args[0], "")
400 print "digraph G {"
400 print "digraph G {"
401 for i in range(r.count()):
401 for i in range(r.count()):
402 e = r.index[i]
402 e = r.index[i]
403 print "\t%d -> %d" % (r.rev(e[4]), i)
403 print "\t%d -> %d" % (r.rev(e[4]), i)
404 if e[5] != hg.nullid:
404 if e[5] != hg.nullid:
405 print "\t%d -> %d" % (r.rev(e[5]), i)
405 print "\t%d -> %d" % (r.rev(e[5]), i)
406 print "}"
406 print "}"
407
407
408 elif cmd == "merge":
408 elif cmd == "merge":
409 (c, a, d) = repo.diffdir(repo.root, repo.current)
410 if c:
411 ui.warn("aborting (outstanding changes in working directory)\n")
412 sys.exit(1)
413
409 if args:
414 if args:
410 other = hg.repository(ui, args[0])
415 other = hg.repository(ui, args[0])
411 ui.status("requesting changegroup\n")
416 ui.status("requesting changegroup\n")
412 cg = repo.getchangegroup(other)
417 cg = repo.getchangegroup(other)
413 repo.addchangegroup(cg)
418 repo.addchangegroup(cg)
414 else:
419 else:
415 print "missing source repository"
420 print "missing source repository"
416
421
417 elif cmd == "tags":
422 elif cmd == "tags":
418 repo.lookup(0) # prime the cache
423 repo.lookup(0) # prime the cache
419 i = repo.tags.items()
424 i = repo.tags.items()
420 i.sort()
425 i.sort()
421 for k, n in i:
426 for k, n in i:
422 try:
427 try:
423 r = repo.changelog.rev(n)
428 r = repo.changelog.rev(n)
424 except KeyError:
429 except KeyError:
425 r = "?"
430 r = "?"
426 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
431 print "%-30s %5d:%s" % (k, repo.changelog.rev(n), hg.hex(n))
427
432
428 elif cmd == "recover":
433 elif cmd == "recover":
429 repo.recover()
434 repo.recover()
430
435
431 elif cmd == "undo":
436 elif cmd == "undo":
432 repo.recover("undo")
437 repo.recover("undo")
433
438
434 elif cmd == "verify":
439 elif cmd == "verify":
435 filelinkrevs = {}
440 filelinkrevs = {}
436 filenodes = {}
441 filenodes = {}
437 manifestchangeset = {}
442 manifestchangeset = {}
438 changesets = revisions = files = 0
443 changesets = revisions = files = 0
439 errors = 0
444 errors = 0
440
445
441 ui.status("checking changesets\n")
446 ui.status("checking changesets\n")
442 for i in range(repo.changelog.count()):
447 for i in range(repo.changelog.count()):
443 changesets += 1
448 changesets += 1
444 n = repo.changelog.node(i)
449 n = repo.changelog.node(i)
445 for p in repo.changelog.parents(n):
450 for p in repo.changelog.parents(n):
446 if p not in repo.changelog.nodemap:
451 if p not in repo.changelog.nodemap:
447 ui.warn("changeset %s has unknown parent %s\n" %
452 ui.warn("changeset %s has unknown parent %s\n" %
448 (hg.short(n), hg.short(p)))
453 (hg.short(n), hg.short(p)))
449 errors += 1
454 errors += 1
450 try:
455 try:
451 changes = repo.changelog.read(n)
456 changes = repo.changelog.read(n)
452 except Exception, inst:
457 except Exception, inst:
453 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
458 ui.warn("unpacking changeset %s: %s\n" % (short(n), inst))
454 errors += 1
459 errors += 1
455
460
456 manifestchangeset[changes[0]] = n
461 manifestchangeset[changes[0]] = n
457 for f in changes[3]:
462 for f in changes[3]:
458 revisions += 1
463 revisions += 1
459 filelinkrevs.setdefault(f, []).append(i)
464 filelinkrevs.setdefault(f, []).append(i)
460
465
461 ui.status("checking manifests\n")
466 ui.status("checking manifests\n")
462 for i in range(repo.manifest.count()):
467 for i in range(repo.manifest.count()):
463 n = repo.manifest.node(i)
468 n = repo.manifest.node(i)
464 for p in repo.manifest.parents(n):
469 for p in repo.manifest.parents(n):
465 if p not in repo.manifest.nodemap:
470 if p not in repo.manifest.nodemap:
466 ui.warn("manifest %s has unknown parent %s\n" %
471 ui.warn("manifest %s has unknown parent %s\n" %
467 (hg.short(n), hg.short(p)))
472 (hg.short(n), hg.short(p)))
468 errors += 1
473 errors += 1
469 ca = repo.changelog.node(repo.manifest.linkrev(n))
474 ca = repo.changelog.node(repo.manifest.linkrev(n))
470 cc = manifestchangeset[n]
475 cc = manifestchangeset[n]
471 if ca != cc:
476 if ca != cc:
472 ui.warn("manifest %s points to %s, not %s\n" %
477 ui.warn("manifest %s points to %s, not %s\n" %
473 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
478 (hg.hex(n), hg.hex(ca), hg.hex(cc)))
474 errors += 1
479 errors += 1
475
480
476 try:
481 try:
477 delta = mdiff.patchtext(repo.manifest.delta(n))
482 delta = mdiff.patchtext(repo.manifest.delta(n))
478 except KeyboardInterrupt:
483 except KeyboardInterrupt:
479 print "aborted"
484 print "aborted"
480 sys.exit(0)
485 sys.exit(0)
481 except Exception, inst:
486 except Exception, inst:
482 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
487 ui.warn("unpacking manifest %s: %s\n" % (hg.short(n), inst))
483 errors += 1
488 errors += 1
484
489
485 ff = [ l.split('\0') for l in delta.splitlines() ]
490 ff = [ l.split('\0') for l in delta.splitlines() ]
486 for f, fn in ff:
491 for f, fn in ff:
487 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
492 filenodes.setdefault(f, {})[hg.bin(fn)] = 1
488
493
489 ui.status("crosschecking files in changesets and manifests\n")
494 ui.status("crosschecking files in changesets and manifests\n")
490 for f in filenodes:
495 for f in filenodes:
491 if f not in filelinkrevs:
496 if f not in filelinkrevs:
492 ui.warn("file %s in manifest but not in changesets\n" % f)
497 ui.warn("file %s in manifest but not in changesets\n" % f)
493 errors += 1
498 errors += 1
494
499
495 for f in filelinkrevs:
500 for f in filelinkrevs:
496 if f not in filenodes:
501 if f not in filenodes:
497 ui.warn("file %s in changeset but not in manifest\n" % f)
502 ui.warn("file %s in changeset but not in manifest\n" % f)
498 errors += 1
503 errors += 1
499
504
500 ui.status("checking files\n")
505 ui.status("checking files\n")
501 ff = filenodes.keys()
506 ff = filenodes.keys()
502 ff.sort()
507 ff.sort()
503 for f in ff:
508 for f in ff:
504 if f == "/dev/null": continue
509 if f == "/dev/null": continue
505 files += 1
510 files += 1
506 fl = repo.file(f)
511 fl = repo.file(f)
507 nodes = { hg.nullid: 1 }
512 nodes = { hg.nullid: 1 }
508 for i in range(fl.count()):
513 for i in range(fl.count()):
509 n = fl.node(i)
514 n = fl.node(i)
510
515
511 if n not in filenodes[f]:
516 if n not in filenodes[f]:
512 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
517 ui.warn("%s: %d:%s not in manifests\n" % (f, i, hg.short(n)))
513 print len(filenodes[f].keys()), fl.count(), f
518 print len(filenodes[f].keys()), fl.count(), f
514 errors += 1
519 errors += 1
515 else:
520 else:
516 del filenodes[f][n]
521 del filenodes[f][n]
517
522
518 flr = fl.linkrev(n)
523 flr = fl.linkrev(n)
519 if flr not in filelinkrevs[f]:
524 if flr not in filelinkrevs[f]:
520 ui.warn("%s:%s points to unexpected changeset rev %d\n"
525 ui.warn("%s:%s points to unexpected changeset rev %d\n"
521 % (f, hg.short(n), fl.linkrev(n)))
526 % (f, hg.short(n), fl.linkrev(n)))
522 errors += 1
527 errors += 1
523 else:
528 else:
524 filelinkrevs[f].remove(flr)
529 filelinkrevs[f].remove(flr)
525
530
526 # verify contents
531 # verify contents
527 try:
532 try:
528 t = fl.read(n)
533 t = fl.read(n)
529 except Exception, inst:
534 except Exception, inst:
530 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
535 ui.warn("unpacking file %s %s: %s\n" % (f, hg.short(n), inst))
531 errors += 1
536 errors += 1
532
537
533 # verify parents
538 # verify parents
534 (p1, p2) = fl.parents(n)
539 (p1, p2) = fl.parents(n)
535 if p1 not in nodes:
540 if p1 not in nodes:
536 ui.warn("file %s:%s unknown parent 1 %s" %
541 ui.warn("file %s:%s unknown parent 1 %s" %
537 (f, hg.short(n), hg.short(p1)))
542 (f, hg.short(n), hg.short(p1)))
538 errors += 1
543 errors += 1
539 if p2 not in nodes:
544 if p2 not in nodes:
540 ui.warn("file %s:%s unknown parent 2 %s" %
545 ui.warn("file %s:%s unknown parent 2 %s" %
541 (f, hg.short(n), hg.short(p1)))
546 (f, hg.short(n), hg.short(p1)))
542 errors += 1
547 errors += 1
543 nodes[n] = 1
548 nodes[n] = 1
544
549
545 # cross-check
550 # cross-check
546 for flr in filelinkrevs[f]:
551 for flr in filelinkrevs[f]:
547 ui.warn("changeset rev %d not in %s\n" % (flr, f))
552 ui.warn("changeset rev %d not in %s\n" % (flr, f))
548 errors += 1
553 errors += 1
549
554
550 for node in filenodes[f]:
555 for node in filenodes[f]:
551 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
556 ui.warn("node %s in manifests not in %s\n" % (hg.hex(n), f))
552 errors += 1
557 errors += 1
553
558
554 ui.status("%d files, %d changesets, %d total revisions\n" %
559 ui.status("%d files, %d changesets, %d total revisions\n" %
555 (files, changesets, revisions))
560 (files, changesets, revisions))
556
561
557 if errors:
562 if errors:
558 ui.warn("%d integrity errors encountered!\n" % errors)
563 ui.warn("%d integrity errors encountered!\n" % errors)
559 sys.exit(1)
564 sys.exit(1)
560
565
561 elif cmd == "serve":
566 elif cmd == "serve":
562 from mercurial import hgweb
567 from mercurial import hgweb
563
568
564 soptions = {}
569 soptions = {}
565 opts = [('p', 'port', 8000, 'listen port'),
570 opts = [('p', 'port', 8000, 'listen port'),
566 ('a', 'address', '', 'interface address'),
571 ('a', 'address', '', 'interface address'),
567 ('n', 'name', os.getcwd(), 'repository name'),
572 ('n', 'name', os.getcwd(), 'repository name'),
568 ('t', 'templates', "", 'template map')
573 ('t', 'templates', "", 'template map')
569 ]
574 ]
570
575
571 args = fancyopts.fancyopts(args, opts, soptions,
576 args = fancyopts.fancyopts(args, opts, soptions,
572 'hg serve [options]')
577 'hg serve [options]')
573
578
574 hgweb.server(repo.root, soptions["name"], soptions["templates"],
579 hgweb.server(repo.root, soptions["name"], soptions["templates"],
575 soptions["address"], soptions["port"])
580 soptions["address"], soptions["port"])
576
581
577 else:
582 else:
578 print "unknown command\n"
583 print "unknown command\n"
579 help()
584 help()
580 sys.exit(1)
585 sys.exit(1)
General Comments 0
You need to be logged in to leave comments. Login now