##// END OF EJS Templates
Add an empty line after description in verbose mode of show_changeset....
Thomas Arendsen Hein -
r546:c8ae9641 default
parent child Browse files
Show More
@@ -1,919 +1,919 b''
1 # commands.py - command processing for mercurial
1 # commands.py - command processing for mercurial
2 #
2 #
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005 Matt Mackall <mpm@selenic.com>
4 #
4 #
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 import os, re, sys, signal
8 import os, re, sys, signal
9 import fancyopts, ui, hg, util
9 import fancyopts, ui, hg, util
10 from demandload import *
10 from demandload import *
11 demandload(globals(), "mdiff time hgweb traceback random signal errno version")
11 demandload(globals(), "mdiff time hgweb traceback random signal errno version")
12
12
13 class UnknownCommand(Exception): pass
13 class UnknownCommand(Exception): pass
14
14
15 def filterfiles(filters, files):
15 def filterfiles(filters, files):
16 l = [ x for x in files if x in filters ]
16 l = [ x for x in files if x in filters ]
17
17
18 for t in filters:
18 for t in filters:
19 if t and t[-1] != "/": t += "/"
19 if t and t[-1] != "/": t += "/"
20 l += [ x for x in files if x.startswith(t) ]
20 l += [ x for x in files if x.startswith(t) ]
21 return l
21 return l
22
22
23 def relfilter(repo, files):
23 def relfilter(repo, files):
24 if os.getcwd() != repo.root:
24 if os.getcwd() != repo.root:
25 p = os.getcwd()[len(repo.root) + 1: ]
25 p = os.getcwd()[len(repo.root) + 1: ]
26 return filterfiles([util.pconvert(p)], files)
26 return filterfiles([util.pconvert(p)], files)
27 return files
27 return files
28
28
29 def relpath(repo, args):
29 def relpath(repo, args):
30 if os.getcwd() != repo.root:
30 if os.getcwd() != repo.root:
31 p = os.getcwd()[len(repo.root) + 1: ]
31 p = os.getcwd()[len(repo.root) + 1: ]
32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) for x in args ]
32 return [ util.pconvert(os.path.normpath(os.path.join(p, x))) for x in args ]
33 return args
33 return args
34
34
35 def dodiff(ui, repo, path, files = None, node1 = None, node2 = None):
35 def dodiff(ui, repo, path, files = None, node1 = None, node2 = None):
36 def date(c):
36 def date(c):
37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
37 return time.asctime(time.gmtime(float(c[2].split(' ')[0])))
38
38
39 if node2:
39 if node2:
40 change = repo.changelog.read(node2)
40 change = repo.changelog.read(node2)
41 mmap2 = repo.manifest.read(change[0])
41 mmap2 = repo.manifest.read(change[0])
42 (c, a, d) = repo.diffrevs(node1, node2)
42 (c, a, d) = repo.diffrevs(node1, node2)
43 def read(f): return repo.file(f).read(mmap2[f])
43 def read(f): return repo.file(f).read(mmap2[f])
44 date2 = date(change)
44 date2 = date(change)
45 else:
45 else:
46 date2 = time.asctime()
46 date2 = time.asctime()
47 (c, a, d, u) = repo.diffdir(path, node1)
47 (c, a, d, u) = repo.diffdir(path, node1)
48 if not node1:
48 if not node1:
49 node1 = repo.dirstate.parents()[0]
49 node1 = repo.dirstate.parents()[0]
50 def read(f): return repo.wfile(f).read()
50 def read(f): return repo.wfile(f).read()
51
51
52 if ui.quiet:
52 if ui.quiet:
53 r = None
53 r = None
54 else:
54 else:
55 hexfunc = ui.verbose and hg.hex or hg.short
55 hexfunc = ui.verbose and hg.hex or hg.short
56 r = [hexfunc(node) for node in [node1, node2] if node]
56 r = [hexfunc(node) for node in [node1, node2] if node]
57
57
58 change = repo.changelog.read(node1)
58 change = repo.changelog.read(node1)
59 mmap = repo.manifest.read(change[0])
59 mmap = repo.manifest.read(change[0])
60 date1 = date(change)
60 date1 = date(change)
61
61
62 if files:
62 if files:
63 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
63 c, a, d = map(lambda x: filterfiles(files, x), (c, a, d))
64
64
65 for f in c:
65 for f in c:
66 to = None
66 to = None
67 if f in mmap:
67 if f in mmap:
68 to = repo.file(f).read(mmap[f])
68 to = repo.file(f).read(mmap[f])
69 tn = read(f)
69 tn = read(f)
70 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
70 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
71 for f in a:
71 for f in a:
72 to = None
72 to = None
73 tn = read(f)
73 tn = read(f)
74 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
74 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
75 for f in d:
75 for f in d:
76 to = repo.file(f).read(mmap[f])
76 to = repo.file(f).read(mmap[f])
77 tn = None
77 tn = None
78 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
78 sys.stdout.write(mdiff.unidiff(to, date1, tn, date2, f, r))
79
79
80 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
80 def show_changeset(ui, repo, rev=0, changenode=None, filelog=None):
81 """show a single changeset or file revision"""
81 """show a single changeset or file revision"""
82 changelog = repo.changelog
82 changelog = repo.changelog
83 if filelog:
83 if filelog:
84 log = filelog
84 log = filelog
85 filerev = rev
85 filerev = rev
86 node = filenode = filelog.node(filerev)
86 node = filenode = filelog.node(filerev)
87 changerev = filelog.linkrev(filenode)
87 changerev = filelog.linkrev(filenode)
88 changenode = changenode or changelog.node(changerev)
88 changenode = changenode or changelog.node(changerev)
89 else:
89 else:
90 log = changelog
90 log = changelog
91 changerev = rev
91 changerev = rev
92 if changenode is None:
92 if changenode is None:
93 changenode = changelog.node(changerev)
93 changenode = changelog.node(changerev)
94 elif not changerev:
94 elif not changerev:
95 rev = changerev = changelog.rev(changenode)
95 rev = changerev = changelog.rev(changenode)
96 node = changenode
96 node = changenode
97
97
98 if ui.quiet:
98 if ui.quiet:
99 ui.write("%d:%s\n" % (rev, hg.hex(node)))
99 ui.write("%d:%s\n" % (rev, hg.hex(node)))
100 return
100 return
101
101
102 changes = changelog.read(changenode)
102 changes = changelog.read(changenode)
103
103
104 parents = [(log.rev(parent), hg.hex(parent))
104 parents = [(log.rev(parent), hg.hex(parent))
105 for parent in log.parents(node)
105 for parent in log.parents(node)
106 if ui.debugflag or parent != hg.nullid]
106 if ui.debugflag or parent != hg.nullid]
107 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
107 if not ui.debugflag and len(parents) == 1 and parents[0][0] == rev-1:
108 parents = []
108 parents = []
109
109
110 if filelog:
110 if filelog:
111 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
111 ui.write("revision: %d:%s\n" % (filerev, hg.hex(filenode)))
112 for parent in parents:
112 for parent in parents:
113 ui.write("parent: %d:%s\n" % parent)
113 ui.write("parent: %d:%s\n" % parent)
114 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
114 ui.status("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
115 else:
115 else:
116 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
116 ui.write("changeset: %d:%s\n" % (changerev, hg.hex(changenode)))
117 for tag in repo.nodetags(changenode):
117 for tag in repo.nodetags(changenode):
118 ui.status("tag: %s\n" % tag)
118 ui.status("tag: %s\n" % tag)
119 for parent in parents:
119 for parent in parents:
120 ui.write("parent: %d:%s\n" % parent)
120 ui.write("parent: %d:%s\n" % parent)
121 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
121 ui.note("manifest: %d:%s\n" % (repo.manifest.rev(changes[0]),
122 hg.hex(changes[0])))
122 hg.hex(changes[0])))
123 ui.status("user: %s\n" % changes[1])
123 ui.status("user: %s\n" % changes[1])
124 ui.status("date: %s\n" % time.asctime(
124 ui.status("date: %s\n" % time.asctime(
125 time.localtime(float(changes[2].split(' ')[0]))))
125 time.localtime(float(changes[2].split(' ')[0]))))
126 if ui.debugflag:
126 if ui.debugflag:
127 files = repo.diffrevs(changelog.parents(changenode)[0], changenode)
127 files = repo.diffrevs(changelog.parents(changenode)[0], changenode)
128 for key, value in zip(["files:", "files+:", "files-:"], files):
128 for key, value in zip(["files:", "files+:", "files-:"], files):
129 if value:
129 if value:
130 ui.note("%-12s %s\n" % (key, " ".join(value)))
130 ui.note("%-12s %s\n" % (key, " ".join(value)))
131 else:
131 else:
132 ui.note("files: %s\n" % " ".join(changes[3]))
132 ui.note("files: %s\n" % " ".join(changes[3]))
133 description = changes[4].strip()
133 description = changes[4].strip()
134 if description:
134 if description:
135 if ui.verbose:
135 if ui.verbose:
136 ui.status("description:\n")
136 ui.status("description:\n")
137 ui.status(description)
137 ui.status(description)
138 ui.status("\n")
138 ui.status("\n\n")
139 else:
139 else:
140 ui.status("summary: %s\n" % description.splitlines()[0])
140 ui.status("summary: %s\n" % description.splitlines()[0])
141 ui.status("\n")
141 ui.status("\n")
142
142
143 def show_version(ui):
143 def show_version(ui):
144 """output version and copyright information"""
144 """output version and copyright information"""
145 ui.write("Mercurial version %s\n" % version.get_version())
145 ui.write("Mercurial version %s\n" % version.get_version())
146 ui.status(
146 ui.status(
147 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
147 "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
148 "This is free software; see the source for copying conditions. "
148 "This is free software; see the source for copying conditions. "
149 "There is NO\nwarranty; "
149 "There is NO\nwarranty; "
150 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
150 "not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
151 )
151 )
152
152
153 def help(ui, cmd=None):
153 def help(ui, cmd=None):
154 '''show help for a given command or all commands'''
154 '''show help for a given command or all commands'''
155 if cmd:
155 if cmd:
156 try:
156 try:
157 i = find(cmd)
157 i = find(cmd)
158 ui.write("%s\n\n" % i[2])
158 ui.write("%s\n\n" % i[2])
159
159
160 if i[1]:
160 if i[1]:
161 for s, l, d, c in i[1]:
161 for s, l, d, c in i[1]:
162 opt=' '
162 opt=' '
163 if s: opt = opt + '-' + s + ' '
163 if s: opt = opt + '-' + s + ' '
164 if l: opt = opt + '--' + l + ' '
164 if l: opt = opt + '--' + l + ' '
165 if d: opt = opt + '(' + str(d) + ')'
165 if d: opt = opt + '(' + str(d) + ')'
166 ui.write(opt, "\n")
166 ui.write(opt, "\n")
167 if c: ui.write(' %s\n' % c)
167 if c: ui.write(' %s\n' % c)
168 ui.write("\n")
168 ui.write("\n")
169
169
170 ui.write(i[0].__doc__, "\n")
170 ui.write(i[0].__doc__, "\n")
171 except UnknownCommand:
171 except UnknownCommand:
172 ui.warn("hg: unknown command %s\n" % cmd)
172 ui.warn("hg: unknown command %s\n" % cmd)
173 sys.exit(0)
173 sys.exit(0)
174 else:
174 else:
175 if not ui.quiet:
175 if not ui.quiet:
176 show_version(ui)
176 show_version(ui)
177 ui.write('\n')
177 ui.write('\n')
178 ui.write('hg commands:\n\n')
178 ui.write('hg commands:\n\n')
179
179
180 h = {}
180 h = {}
181 for c, e in table.items():
181 for c, e in table.items():
182 f = c.split("|")[0]
182 f = c.split("|")[0]
183 if f.startswith("debug"):
183 if f.startswith("debug"):
184 continue
184 continue
185 d = ""
185 d = ""
186 if e[0].__doc__:
186 if e[0].__doc__:
187 d = e[0].__doc__.splitlines(0)[0].rstrip()
187 d = e[0].__doc__.splitlines(0)[0].rstrip()
188 h[f] = d
188 h[f] = d
189
189
190 fns = h.keys()
190 fns = h.keys()
191 fns.sort()
191 fns.sort()
192 m = max(map(len, fns))
192 m = max(map(len, fns))
193 for f in fns:
193 for f in fns:
194 ui.write(' %-*s %s\n' % (m, f, h[f]))
194 ui.write(' %-*s %s\n' % (m, f, h[f]))
195
195
196 # Commands start here, listed alphabetically
196 # Commands start here, listed alphabetically
197
197
198 def add(ui, repo, file, *files):
198 def add(ui, repo, file, *files):
199 '''add the specified files on the next commit'''
199 '''add the specified files on the next commit'''
200 repo.add(relpath(repo, (file,) + files))
200 repo.add(relpath(repo, (file,) + files))
201
201
202 def addremove(ui, repo, *files):
202 def addremove(ui, repo, *files):
203 """add all new files, delete all missing files"""
203 """add all new files, delete all missing files"""
204 if files:
204 if files:
205 files = relpath(repo, files)
205 files = relpath(repo, files)
206 d = []
206 d = []
207 u = []
207 u = []
208 for f in files:
208 for f in files:
209 p = repo.wjoin(f)
209 p = repo.wjoin(f)
210 s = repo.dirstate.state(f)
210 s = repo.dirstate.state(f)
211 isfile = os.path.isfile(p)
211 isfile = os.path.isfile(p)
212 if s != 'r' and not isfile:
212 if s != 'r' and not isfile:
213 d.append(f)
213 d.append(f)
214 elif s not in 'nmai' and isfile:
214 elif s not in 'nmai' and isfile:
215 u.append(f)
215 u.append(f)
216 else:
216 else:
217 (c, a, d, u) = repo.diffdir(repo.root)
217 (c, a, d, u) = repo.diffdir(repo.root)
218 repo.add(u)
218 repo.add(u)
219 repo.remove(d)
219 repo.remove(d)
220
220
221 def annotate(u, repo, file, *files, **ops):
221 def annotate(u, repo, file, *files, **ops):
222 """show changeset information per file line"""
222 """show changeset information per file line"""
223 def getnode(rev):
223 def getnode(rev):
224 return hg.short(repo.changelog.node(rev))
224 return hg.short(repo.changelog.node(rev))
225
225
226 def getname(rev):
226 def getname(rev):
227 try:
227 try:
228 return bcache[rev]
228 return bcache[rev]
229 except KeyError:
229 except KeyError:
230 cl = repo.changelog.read(repo.changelog.node(rev))
230 cl = repo.changelog.read(repo.changelog.node(rev))
231 name = cl[1]
231 name = cl[1]
232 f = name.find('@')
232 f = name.find('@')
233 if f >= 0:
233 if f >= 0:
234 name = name[:f]
234 name = name[:f]
235 f = name.find('<')
235 f = name.find('<')
236 if f >= 0:
236 if f >= 0:
237 name = name[f+1:]
237 name = name[f+1:]
238 bcache[rev] = name
238 bcache[rev] = name
239 return name
239 return name
240
240
241 bcache = {}
241 bcache = {}
242 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
242 opmap = [['user', getname], ['number', str], ['changeset', getnode]]
243 if not ops['user'] and not ops['changeset']:
243 if not ops['user'] and not ops['changeset']:
244 ops['number'] = 1
244 ops['number'] = 1
245
245
246 node = repo.dirstate.parents()[0]
246 node = repo.dirstate.parents()[0]
247 if ops['revision']:
247 if ops['revision']:
248 node = repo.changelog.lookup(ops['revision'])
248 node = repo.changelog.lookup(ops['revision'])
249 change = repo.changelog.read(node)
249 change = repo.changelog.read(node)
250 mmap = repo.manifest.read(change[0])
250 mmap = repo.manifest.read(change[0])
251 for f in relpath(repo, (file,) + files):
251 for f in relpath(repo, (file,) + files):
252 lines = repo.file(f).annotate(mmap[f])
252 lines = repo.file(f).annotate(mmap[f])
253 pieces = []
253 pieces = []
254
254
255 for o, f in opmap:
255 for o, f in opmap:
256 if ops[o]:
256 if ops[o]:
257 l = [ f(n) for n,t in lines ]
257 l = [ f(n) for n,t in lines ]
258 m = max(map(len, l))
258 m = max(map(len, l))
259 pieces.append([ "%*s" % (m, x) for x in l])
259 pieces.append([ "%*s" % (m, x) for x in l])
260
260
261 for p,l in zip(zip(*pieces), lines):
261 for p,l in zip(zip(*pieces), lines):
262 u.write(" ".join(p) + ": " + l[1])
262 u.write(" ".join(p) + ": " + l[1])
263
263
264 def cat(ui, repo, file, rev = []):
264 def cat(ui, repo, file, rev = []):
265 """output the latest or given revision of a file"""
265 """output the latest or given revision of a file"""
266 r = repo.file(relpath(repo, [file])[0])
266 r = repo.file(relpath(repo, [file])[0])
267 n = r.tip()
267 n = r.tip()
268 if rev: n = r.lookup(rev)
268 if rev: n = r.lookup(rev)
269 sys.stdout.write(r.read(n))
269 sys.stdout.write(r.read(n))
270
270
271 def clone(ui, source, dest = None, **opts):
271 def clone(ui, source, dest = None, **opts):
272 """make a copy of an existing repository"""
272 """make a copy of an existing repository"""
273 source = ui.expandpath(source)
273 source = ui.expandpath(source)
274
274
275 if dest is None:
275 if dest is None:
276 dest = os.path.basename(os.path.normpath(source))
276 dest = os.path.basename(os.path.normpath(source))
277
277
278 if os.path.exists(dest):
278 if os.path.exists(dest):
279 ui.warn("abort: destination '%s' already exists\n" % dest)
279 ui.warn("abort: destination '%s' already exists\n" % dest)
280 return 1
280 return 1
281
281
282 class dircleanup:
282 class dircleanup:
283 def __init__(self, dir):
283 def __init__(self, dir):
284 self.dir = dir
284 self.dir = dir
285 os.mkdir(dir)
285 os.mkdir(dir)
286 def close(self):
286 def close(self):
287 self.dir = None
287 self.dir = None
288 def __del__(self):
288 def __del__(self):
289 if self.dir:
289 if self.dir:
290 import shutil
290 import shutil
291 shutil.rmtree(self.dir, True)
291 shutil.rmtree(self.dir, True)
292
292
293 d = dircleanup(dest)
293 d = dircleanup(dest)
294
294
295 link = 0
295 link = 0
296 if not (source.startswith("http://") or
296 if not (source.startswith("http://") or
297 source.startswith("hg://") or
297 source.startswith("hg://") or
298 source.startswith("old-http://")):
298 source.startswith("old-http://")):
299 d1 = os.stat(dest).st_dev
299 d1 = os.stat(dest).st_dev
300 d2 = os.stat(source).st_dev
300 d2 = os.stat(source).st_dev
301 if d1 == d2: link = 1
301 if d1 == d2: link = 1
302
302
303 if link:
303 if link:
304 ui.note("copying by hardlink\n")
304 ui.note("copying by hardlink\n")
305 util.system("cp -al '%s'/.hg '%s'/.hg" % (source, dest))
305 util.system("cp -al '%s'/.hg '%s'/.hg" % (source, dest))
306 try:
306 try:
307 os.remove(os.path.join(dest, ".hg", "dirstate"))
307 os.remove(os.path.join(dest, ".hg", "dirstate"))
308 except: pass
308 except: pass
309
309
310 repo = hg.repository(ui, dest)
310 repo = hg.repository(ui, dest)
311
311
312 else:
312 else:
313 repo = hg.repository(ui, dest, create=1)
313 repo = hg.repository(ui, dest, create=1)
314 other = hg.repository(ui, source)
314 other = hg.repository(ui, source)
315 fetch = repo.findincoming(other)
315 fetch = repo.findincoming(other)
316 if fetch:
316 if fetch:
317 cg = other.changegroup(fetch)
317 cg = other.changegroup(fetch)
318 repo.addchangegroup(cg)
318 repo.addchangegroup(cg)
319
319
320 f = repo.opener("hgrc", "w")
320 f = repo.opener("hgrc", "w")
321 f.write("[paths]\n")
321 f.write("[paths]\n")
322 f.write("default = %s\n" % source)
322 f.write("default = %s\n" % source)
323
323
324 if not opts['noupdate']:
324 if not opts['noupdate']:
325 update(ui, repo)
325 update(ui, repo)
326
326
327 d.close()
327 d.close()
328
328
329 def commit(ui, repo, *files, **opts):
329 def commit(ui, repo, *files, **opts):
330 """commit the specified files or all outstanding changes"""
330 """commit the specified files or all outstanding changes"""
331 text = opts['text']
331 text = opts['text']
332 if not text and opts['logfile']:
332 if not text and opts['logfile']:
333 try: text = open(opts['logfile']).read()
333 try: text = open(opts['logfile']).read()
334 except IOError: pass
334 except IOError: pass
335
335
336 if opts['addremove']:
336 if opts['addremove']:
337 addremove(ui, repo, *files)
337 addremove(ui, repo, *files)
338 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
338 repo.commit(relpath(repo, files), text, opts['user'], opts['date'])
339
339
340 def copy(ui, repo, source, dest):
340 def copy(ui, repo, source, dest):
341 """mark a file as copied or renamed for the next commit"""
341 """mark a file as copied or renamed for the next commit"""
342 return repo.copy(*relpath(repo, (source, dest)))
342 return repo.copy(*relpath(repo, (source, dest)))
343
343
344 def debugcheckdirstate(ui, repo):
344 def debugcheckdirstate(ui, repo):
345 parent1, parent2 = repo.dirstate.parents()
345 parent1, parent2 = repo.dirstate.parents()
346 dc = repo.dirstate.dup()
346 dc = repo.dirstate.dup()
347 keys = dc.keys()
347 keys = dc.keys()
348 keys.sort()
348 keys.sort()
349 m1n = repo.changelog.read(parent1)[0]
349 m1n = repo.changelog.read(parent1)[0]
350 m2n = repo.changelog.read(parent2)[0]
350 m2n = repo.changelog.read(parent2)[0]
351 m1 = repo.manifest.read(m1n)
351 m1 = repo.manifest.read(m1n)
352 m2 = repo.manifest.read(m2n)
352 m2 = repo.manifest.read(m2n)
353 errors = 0
353 errors = 0
354 for f in dc:
354 for f in dc:
355 state = repo.dirstate.state(f)
355 state = repo.dirstate.state(f)
356 if state in "nr" and f not in m1:
356 if state in "nr" and f not in m1:
357 print "%s in state %s, but not listed in manifest1" % (f, state)
357 print "%s in state %s, but not listed in manifest1" % (f, state)
358 errors += 1
358 errors += 1
359 if state in "a" and f in m1:
359 if state in "a" and f in m1:
360 print "%s in state %s, but also listed in manifest1" % (f, state)
360 print "%s in state %s, but also listed in manifest1" % (f, state)
361 errors += 1
361 errors += 1
362 if state in "m" and f not in m1 and f not in m2:
362 if state in "m" and f not in m1 and f not in m2:
363 print "%s in state %s, but not listed in either manifest" % (f, state)
363 print "%s in state %s, but not listed in either manifest" % (f, state)
364 errors += 1
364 errors += 1
365 for f in m1:
365 for f in m1:
366 state = repo.dirstate.state(f)
366 state = repo.dirstate.state(f)
367 if state not in "nrm":
367 if state not in "nrm":
368 print "%s in manifest1, but listed as state %s" % (f, state)
368 print "%s in manifest1, but listed as state %s" % (f, state)
369 errors += 1
369 errors += 1
370 if errors:
370 if errors:
371 print ".hg/dirstate inconsistent with current parent's manifest, aborting"
371 print ".hg/dirstate inconsistent with current parent's manifest, aborting"
372 sys.exit(1)
372 sys.exit(1)
373
373
374 def debugdumpdirstate(ui, repo):
374 def debugdumpdirstate(ui, repo):
375 dc = repo.dirstate.dup()
375 dc = repo.dirstate.dup()
376 keys = dc.keys()
376 keys = dc.keys()
377 keys.sort()
377 keys.sort()
378 for file in keys:
378 for file in keys:
379 print "%s => %c" % (file, dc[file][0])
379 print "%s => %c" % (file, dc[file][0])
380
380
381 def debugindex(ui, file):
381 def debugindex(ui, file):
382 r = hg.revlog(hg.opener(""), file, "")
382 r = hg.revlog(hg.opener(""), file, "")
383 print " rev offset length base linkrev"+\
383 print " rev offset length base linkrev"+\
384 " p1 p2 nodeid"
384 " p1 p2 nodeid"
385 for i in range(r.count()):
385 for i in range(r.count()):
386 e = r.index[i]
386 e = r.index[i]
387 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
387 print "% 6d % 9d % 7d % 6d % 7d %s.. %s.. %s.." % (
388 i, e[0], e[1], e[2], e[3],
388 i, e[0], e[1], e[2], e[3],
389 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
389 hg.hex(e[4][:5]), hg.hex(e[5][:5]), hg.hex(e[6][:5]))
390
390
391 def debugindexdot(ui, file):
391 def debugindexdot(ui, file):
392 r = hg.revlog(hg.opener(""), file, "")
392 r = hg.revlog(hg.opener(""), file, "")
393 print "digraph G {"
393 print "digraph G {"
394 for i in range(r.count()):
394 for i in range(r.count()):
395 e = r.index[i]
395 e = r.index[i]
396 print "\t%d -> %d" % (r.rev(e[4]), i)
396 print "\t%d -> %d" % (r.rev(e[4]), i)
397 if e[5] != hg.nullid:
397 if e[5] != hg.nullid:
398 print "\t%d -> %d" % (r.rev(e[5]), i)
398 print "\t%d -> %d" % (r.rev(e[5]), i)
399 print "}"
399 print "}"
400
400
401 def diff(ui, repo, *files, **opts):
401 def diff(ui, repo, *files, **opts):
402 """diff working directory (or selected files)"""
402 """diff working directory (or selected files)"""
403 revs = []
403 revs = []
404 if opts['rev']:
404 if opts['rev']:
405 revs = map(lambda x: repo.lookup(x), opts['rev'])
405 revs = map(lambda x: repo.lookup(x), opts['rev'])
406
406
407 if len(revs) > 2:
407 if len(revs) > 2:
408 ui.warn("too many revisions to diff\n")
408 ui.warn("too many revisions to diff\n")
409 sys.exit(1)
409 sys.exit(1)
410
410
411 if files:
411 if files:
412 files = relpath(repo, files)
412 files = relpath(repo, files)
413 else:
413 else:
414 files = relpath(repo, [""])
414 files = relpath(repo, [""])
415
415
416 dodiff(ui, repo, os.getcwd(), files, *revs)
416 dodiff(ui, repo, os.getcwd(), files, *revs)
417
417
418 def export(ui, repo, changeset):
418 def export(ui, repo, changeset):
419 """dump the changeset header and diffs for a revision"""
419 """dump the changeset header and diffs for a revision"""
420 node = repo.lookup(changeset)
420 node = repo.lookup(changeset)
421 prev, other = repo.changelog.parents(node)
421 prev, other = repo.changelog.parents(node)
422 change = repo.changelog.read(node)
422 change = repo.changelog.read(node)
423 print "# HG changeset patch"
423 print "# HG changeset patch"
424 print "# User %s" % change[1]
424 print "# User %s" % change[1]
425 print "# Node ID %s" % hg.hex(node)
425 print "# Node ID %s" % hg.hex(node)
426 print "# Parent %s" % hg.hex(prev)
426 print "# Parent %s" % hg.hex(prev)
427 print
427 print
428 if other != hg.nullid:
428 if other != hg.nullid:
429 print "# Parent %s" % hg.hex(other)
429 print "# Parent %s" % hg.hex(other)
430 print change[4].rstrip()
430 print change[4].rstrip()
431 print
431 print
432
432
433 dodiff(ui, repo, "", None, prev, node)
433 dodiff(ui, repo, "", None, prev, node)
434
434
435 def forget(ui, repo, file, *files):
435 def forget(ui, repo, file, *files):
436 """don't add the specified files on the next commit"""
436 """don't add the specified files on the next commit"""
437 repo.forget(relpath(repo, (file,) + files))
437 repo.forget(relpath(repo, (file,) + files))
438
438
439 def heads(ui, repo):
439 def heads(ui, repo):
440 """show current repository heads"""
440 """show current repository heads"""
441 for n in repo.changelog.heads():
441 for n in repo.changelog.heads():
442 show_changeset(ui, repo, changenode=n)
442 show_changeset(ui, repo, changenode=n)
443
443
444 def identify(ui, repo):
444 def identify(ui, repo):
445 """print information about the working copy"""
445 """print information about the working copy"""
446 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
446 parents = [p for p in repo.dirstate.parents() if p != hg.nullid]
447 if not parents:
447 if not parents:
448 ui.write("unknown\n")
448 ui.write("unknown\n")
449 return
449 return
450
450
451 hexfunc = ui.verbose and hg.hex or hg.short
451 hexfunc = ui.verbose and hg.hex or hg.short
452 (c, a, d, u) = repo.diffdir(repo.root)
452 (c, a, d, u) = repo.diffdir(repo.root)
453 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
453 output = ["%s%s" % ('+'.join([hexfunc(parent) for parent in parents]),
454 (c or a or d) and "+" or "")]
454 (c or a or d) and "+" or "")]
455
455
456 if not ui.quiet:
456 if not ui.quiet:
457 # multiple tags for a single parent separated by '/'
457 # multiple tags for a single parent separated by '/'
458 parenttags = ['/'.join(tags)
458 parenttags = ['/'.join(tags)
459 for tags in map(repo.nodetags, parents) if tags]
459 for tags in map(repo.nodetags, parents) if tags]
460 # tags for multiple parents separated by ' + '
460 # tags for multiple parents separated by ' + '
461 output.append(' + '.join(parenttags))
461 output.append(' + '.join(parenttags))
462
462
463 ui.write("%s\n" % ' '.join(output))
463 ui.write("%s\n" % ' '.join(output))
464
464
465 def import_(ui, repo, patch1, *patches, **opts):
465 def import_(ui, repo, patch1, *patches, **opts):
466 """import an ordered set of patches"""
466 """import an ordered set of patches"""
467 try:
467 try:
468 import psyco
468 import psyco
469 psyco.full()
469 psyco.full()
470 except:
470 except:
471 pass
471 pass
472
472
473 patches = (patch1,) + patches
473 patches = (patch1,) + patches
474
474
475 d = opts["base"]
475 d = opts["base"]
476 strip = opts["strip"]
476 strip = opts["strip"]
477
477
478 for patch in patches:
478 for patch in patches:
479 ui.status("applying %s\n" % patch)
479 ui.status("applying %s\n" % patch)
480 pf = os.path.join(d, patch)
480 pf = os.path.join(d, patch)
481
481
482 text = ""
482 text = ""
483 for l in file(pf):
483 for l in file(pf):
484 if l[:4] == "--- ": break
484 if l[:4] == "--- ": break
485 text += l
485 text += l
486
486
487 # make sure text isn't empty
487 # make sure text isn't empty
488 if not text: text = "imported patch %s\n" % patch
488 if not text: text = "imported patch %s\n" % patch
489
489
490 f = os.popen("patch -p%d < %s" % (strip, pf))
490 f = os.popen("patch -p%d < %s" % (strip, pf))
491 files = []
491 files = []
492 for l in f.read().splitlines():
492 for l in f.read().splitlines():
493 l.rstrip('\r\n');
493 l.rstrip('\r\n');
494 ui.status("%s\n" % l)
494 ui.status("%s\n" % l)
495 if l[:14] == 'patching file ':
495 if l[:14] == 'patching file ':
496 pf = l[14:]
496 pf = l[14:]
497 if pf not in files:
497 if pf not in files:
498 files.append(pf)
498 files.append(pf)
499 patcherr = f.close()
499 patcherr = f.close()
500 if patcherr:
500 if patcherr:
501 sys.stderr.write("patch failed")
501 sys.stderr.write("patch failed")
502 sys.exit(1)
502 sys.exit(1)
503
503
504 if len(files) > 0:
504 if len(files) > 0:
505 addremove(ui, repo, *files)
505 addremove(ui, repo, *files)
506 repo.commit(files, text)
506 repo.commit(files, text)
507
507
508 def init(ui, source=None):
508 def init(ui, source=None):
509 """create a new repository in the current directory"""
509 """create a new repository in the current directory"""
510
510
511 if source:
511 if source:
512 ui.warn("no longer supported: use \"hg clone\" instead\n")
512 ui.warn("no longer supported: use \"hg clone\" instead\n")
513 sys.exit(1)
513 sys.exit(1)
514 repo = hg.repository(ui, ".", create=1)
514 repo = hg.repository(ui, ".", create=1)
515
515
516 def log(ui, repo, f = None):
516 def log(ui, repo, f = None):
517 """show the revision history of the repository or a single file"""
517 """show the revision history of the repository or a single file"""
518 if f:
518 if f:
519 f = relpath(repo, [f])[0]
519 f = relpath(repo, [f])[0]
520 r = repo.file(f)
520 r = repo.file(f)
521 for i in range(r.count() - 1, -1, -1):
521 for i in range(r.count() - 1, -1, -1):
522 show_changeset(ui, repo, filelog=r, rev=i)
522 show_changeset(ui, repo, filelog=r, rev=i)
523 else:
523 else:
524 for i in range(repo.changelog.count() - 1, -1, -1):
524 for i in range(repo.changelog.count() - 1, -1, -1):
525 show_changeset(ui, repo, rev=i)
525 show_changeset(ui, repo, rev=i)
526
526
527 def manifest(ui, repo, rev = []):
527 def manifest(ui, repo, rev = []):
528 """output the latest or given revision of the project manifest"""
528 """output the latest or given revision of the project manifest"""
529 n = repo.manifest.tip()
529 n = repo.manifest.tip()
530 if rev:
530 if rev:
531 n = repo.manifest.lookup(rev)
531 n = repo.manifest.lookup(rev)
532 m = repo.manifest.read(n)
532 m = repo.manifest.read(n)
533 mf = repo.manifest.readflags(n)
533 mf = repo.manifest.readflags(n)
534 files = m.keys()
534 files = m.keys()
535 files.sort()
535 files.sort()
536
536
537 for f in files:
537 for f in files:
538 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
538 ui.write("%40s %3s %s\n" % (hg.hex(m[f]), mf[f] and "755" or "644", f))
539
539
540 def parents(ui, repo, node = None):
540 def parents(ui, repo, node = None):
541 '''show the parents of the current working dir'''
541 '''show the parents of the current working dir'''
542 if node:
542 if node:
543 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
543 p = repo.changelog.parents(repo.lookup(hg.bin(node)))
544 else:
544 else:
545 p = repo.dirstate.parents()
545 p = repo.dirstate.parents()
546
546
547 for n in p:
547 for n in p:
548 if n != hg.nullid:
548 if n != hg.nullid:
549 show_changeset(ui, repo, changenode=n)
549 show_changeset(ui, repo, changenode=n)
550
550
551 def pull(ui, repo, source="default", **opts):
551 def pull(ui, repo, source="default", **opts):
552 """pull changes from the specified source"""
552 """pull changes from the specified source"""
553 source = ui.expandpath(source)
553 source = ui.expandpath(source)
554
554
555 ui.status('pulling from %s\n' % (source))
555 ui.status('pulling from %s\n' % (source))
556
556
557 other = hg.repository(ui, source)
557 other = hg.repository(ui, source)
558 fetch = repo.findincoming(other)
558 fetch = repo.findincoming(other)
559 if not fetch:
559 if not fetch:
560 ui.status("no changes found\n")
560 ui.status("no changes found\n")
561 return
561 return
562
562
563 cg = other.changegroup(fetch)
563 cg = other.changegroup(fetch)
564 r = repo.addchangegroup(cg)
564 r = repo.addchangegroup(cg)
565 if cg and not r:
565 if cg and not r:
566 if opts['update']:
566 if opts['update']:
567 return update(ui, repo)
567 return update(ui, repo)
568 else:
568 else:
569 ui.status("(run 'hg update' to get a working copy)\n")
569 ui.status("(run 'hg update' to get a working copy)\n")
570
570
571 return r
571 return r
572
572
573 def push(ui, repo, dest="default-push"):
573 def push(ui, repo, dest="default-push"):
574 """push changes to the specified destination"""
574 """push changes to the specified destination"""
575 dest = ui.expandpath(dest)
575 dest = ui.expandpath(dest)
576
576
577 if not dest.startswith("ssh://"):
577 if not dest.startswith("ssh://"):
578 ui.warn("abort: can only push to ssh:// destinations currently\n")
578 ui.warn("abort: can only push to ssh:// destinations currently\n")
579 return 1
579 return 1
580
580
581 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
581 m = re.match(r'ssh://(([^@]+)@)?([^:/]+)(:(\d+))?(/(.*))?', dest)
582 if not m:
582 if not m:
583 ui.warn("abort: couldn't parse destination %s\n" % dest)
583 ui.warn("abort: couldn't parse destination %s\n" % dest)
584 return 1
584 return 1
585
585
586 user, host, port, path = map(m.group, (2, 3, 5, 7))
586 user, host, port, path = map(m.group, (2, 3, 5, 7))
587 uhost = user and ("%s@%s" % (user, host)) or host
587 uhost = user and ("%s@%s" % (user, host)) or host
588 port = port and (" -p %s") % port or ""
588 port = port and (" -p %s") % port or ""
589 path = path or ""
589 path = path or ""
590
590
591 sport = random.randrange(30000, 60000)
591 sport = random.randrange(30000, 60000)
592 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
592 cmd = "ssh %s%s -R %d:localhost:%d 'cd %s; hg pull http://localhost:%d/'"
593 cmd = cmd % (uhost, port, sport+1, sport, path, sport+1)
593 cmd = cmd % (uhost, port, sport+1, sport, path, sport+1)
594
594
595 child = os.fork()
595 child = os.fork()
596 if not child:
596 if not child:
597 sys.stdout = file("/dev/null", "w")
597 sys.stdout = file("/dev/null", "w")
598 sys.stderr = sys.stdout
598 sys.stderr = sys.stdout
599 hgweb.server(repo.root, "pull", "", "localhost", sport)
599 hgweb.server(repo.root, "pull", "", "localhost", sport)
600 else:
600 else:
601 ui.status("connecting to %s\n" % host)
601 ui.status("connecting to %s\n" % host)
602 r = os.system(cmd)
602 r = os.system(cmd)
603 os.kill(child, signal.SIGTERM)
603 os.kill(child, signal.SIGTERM)
604 return r
604 return r
605
605
606 def rawcommit(ui, repo, *flist, **rc):
606 def rawcommit(ui, repo, *flist, **rc):
607 "raw commit interface"
607 "raw commit interface"
608
608
609 text = rc['text']
609 text = rc['text']
610 if not text and rc['logfile']:
610 if not text and rc['logfile']:
611 try: text = open(rc['logfile']).read()
611 try: text = open(rc['logfile']).read()
612 except IOError: pass
612 except IOError: pass
613 if not text and not rc['logfile']:
613 if not text and not rc['logfile']:
614 print "missing commit text"
614 print "missing commit text"
615 return 1
615 return 1
616
616
617 files = relpath(repo, list(flist))
617 files = relpath(repo, list(flist))
618 if rc['files']:
618 if rc['files']:
619 files += open(rc['files']).read().splitlines()
619 files += open(rc['files']).read().splitlines()
620
620
621 rc['parent'] = map(repo.lookup, rc['parent'])
621 rc['parent'] = map(repo.lookup, rc['parent'])
622
622
623 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
623 repo.rawcommit(files, text, rc['user'], rc['date'], *rc['parent'])
624
624
625 def recover(ui, repo):
625 def recover(ui, repo):
626 """roll back an interrupted transaction"""
626 """roll back an interrupted transaction"""
627 repo.recover()
627 repo.recover()
628
628
629 def remove(ui, repo, file, *files):
629 def remove(ui, repo, file, *files):
630 """remove the specified files on the next commit"""
630 """remove the specified files on the next commit"""
631 repo.remove(relpath(repo, (file,) + files))
631 repo.remove(relpath(repo, (file,) + files))
632
632
633 def root(ui, repo):
633 def root(ui, repo):
634 """print the root (top) of the current working dir"""
634 """print the root (top) of the current working dir"""
635 ui.write(repo.root + "\n")
635 ui.write(repo.root + "\n")
636
636
637 def serve(ui, repo, **opts):
637 def serve(ui, repo, **opts):
638 """export the repository via HTTP"""
638 """export the repository via HTTP"""
639 hgweb.server(repo.root, opts["name"], opts["templates"],
639 hgweb.server(repo.root, opts["name"], opts["templates"],
640 opts["address"], opts["port"])
640 opts["address"], opts["port"])
641
641
642 def status(ui, repo):
642 def status(ui, repo):
643 '''show changed files in the working directory
643 '''show changed files in the working directory
644
644
645 C = changed
645 C = changed
646 A = added
646 A = added
647 R = removed
647 R = removed
648 ? = not tracked'''
648 ? = not tracked'''
649
649
650 (c, a, d, u) = repo.diffdir(os.getcwd())
650 (c, a, d, u) = repo.diffdir(os.getcwd())
651 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
651 (c, a, d, u) = map(lambda x: relfilter(repo, x), (c, a, d, u))
652
652
653 for f in c: print "C", f
653 for f in c: print "C", f
654 for f in a: print "A", f
654 for f in a: print "A", f
655 for f in d: print "R", f
655 for f in d: print "R", f
656 for f in u: print "?", f
656 for f in u: print "?", f
657
657
658 def tag(ui, repo, name, rev = None, **opts):
658 def tag(ui, repo, name, rev = None, **opts):
659 """add a tag for the current tip or a given revision"""
659 """add a tag for the current tip or a given revision"""
660
660
661 if name == "tip":
661 if name == "tip":
662 ui.warn("abort: 'tip' is a reserved name!\n")
662 ui.warn("abort: 'tip' is a reserved name!\n")
663 return -1
663 return -1
664
664
665 (c, a, d, u) = repo.diffdir(repo.root)
665 (c, a, d, u) = repo.diffdir(repo.root)
666 for x in (c, a, d, u):
666 for x in (c, a, d, u):
667 if ".hgtags" in x:
667 if ".hgtags" in x:
668 ui.warn("abort: working copy of .hgtags is changed!\n")
668 ui.warn("abort: working copy of .hgtags is changed!\n")
669 ui.status("(please commit .hgtags manually)\n")
669 ui.status("(please commit .hgtags manually)\n")
670 return -1
670 return -1
671
671
672 if rev:
672 if rev:
673 r = hg.hex(repo.lookup(rev))
673 r = hg.hex(repo.lookup(rev))
674 else:
674 else:
675 r = hg.hex(repo.changelog.tip())
675 r = hg.hex(repo.changelog.tip())
676
676
677 add = 0
677 add = 0
678 if not os.path.exists(repo.wjoin(".hgtags")): add = 1
678 if not os.path.exists(repo.wjoin(".hgtags")): add = 1
679 repo.wfile(".hgtags", "a").write("%s %s\n" % (r, name))
679 repo.wfile(".hgtags", "a").write("%s %s\n" % (r, name))
680 if add: repo.add([".hgtags"])
680 if add: repo.add([".hgtags"])
681
681
682 if not opts['text']:
682 if not opts['text']:
683 opts['text'] = "Added tag %s for changeset %s" % (name, r)
683 opts['text'] = "Added tag %s for changeset %s" % (name, r)
684
684
685 repo.commit([".hgtags"], opts['text'], opts['user'], opts['date'])
685 repo.commit([".hgtags"], opts['text'], opts['user'], opts['date'])
686
686
687 def tags(ui, repo):
687 def tags(ui, repo):
688 """list repository tags"""
688 """list repository tags"""
689
689
690 l = repo.tagslist()
690 l = repo.tagslist()
691 l.reverse()
691 l.reverse()
692 for t, n in l:
692 for t, n in l:
693 try:
693 try:
694 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
694 r = "%5d:%s" % (repo.changelog.rev(n), hg.hex(n))
695 except KeyError:
695 except KeyError:
696 r = " ?:?"
696 r = " ?:?"
697 ui.write("%-30s %s\n" % (t, r))
697 ui.write("%-30s %s\n" % (t, r))
698
698
699 def tip(ui, repo):
699 def tip(ui, repo):
700 """show the tip revision"""
700 """show the tip revision"""
701 n = repo.changelog.tip()
701 n = repo.changelog.tip()
702 show_changeset(ui, repo, changenode=n)
702 show_changeset(ui, repo, changenode=n)
703
703
704 def undo(ui, repo):
704 def undo(ui, repo):
705 """undo the last transaction"""
705 """undo the last transaction"""
706 repo.undo()
706 repo.undo()
707
707
708 def update(ui, repo, node=None, merge=False, clean=False):
708 def update(ui, repo, node=None, merge=False, clean=False):
709 '''update or merge working directory
709 '''update or merge working directory
710
710
711 If there are no outstanding changes in the working directory and
711 If there are no outstanding changes in the working directory and
712 there is a linear relationship between the current version and the
712 there is a linear relationship between the current version and the
713 requested version, the result is the requested version.
713 requested version, the result is the requested version.
714
714
715 Otherwise the result is a merge between the contents of the
715 Otherwise the result is a merge between the contents of the
716 current working directory and the requested version. Files that
716 current working directory and the requested version. Files that
717 changed between either parent are marked as changed for the next
717 changed between either parent are marked as changed for the next
718 commit and a commit must be performed before any further updates
718 commit and a commit must be performed before any further updates
719 are allowed.
719 are allowed.
720 '''
720 '''
721 node = node and repo.lookup(node) or repo.changelog.tip()
721 node = node and repo.lookup(node) or repo.changelog.tip()
722 return repo.update(node, allow=merge, force=clean)
722 return repo.update(node, allow=merge, force=clean)
723
723
724 def verify(ui, repo):
724 def verify(ui, repo):
725 """verify the integrity of the repository"""
725 """verify the integrity of the repository"""
726 return repo.verify()
726 return repo.verify()
727
727
728 # Command options and aliases are listed here, alphabetically
728 # Command options and aliases are listed here, alphabetically
729
729
730 table = {
730 table = {
731 "add": (add, [], "hg add [files]"),
731 "add": (add, [], "hg add [files]"),
732 "addremove": (addremove, [], "hg addremove [files]"),
732 "addremove": (addremove, [], "hg addremove [files]"),
733 "annotate": (annotate,
733 "annotate": (annotate,
734 [('r', 'revision', '', 'revision'),
734 [('r', 'revision', '', 'revision'),
735 ('u', 'user', None, 'show user'),
735 ('u', 'user', None, 'show user'),
736 ('n', 'number', None, 'show revision number'),
736 ('n', 'number', None, 'show revision number'),
737 ('c', 'changeset', None, 'show changeset')],
737 ('c', 'changeset', None, 'show changeset')],
738 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
738 'hg annotate [-u] [-c] [-n] [-r id] [files]'),
739 "cat": (cat, [], 'hg cat <file> [rev]'),
739 "cat": (cat, [], 'hg cat <file> [rev]'),
740 "clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')],
740 "clone": (clone, [('U', 'noupdate', None, 'skip update after cloning')],
741 'hg clone [options] <source> [dest]'),
741 'hg clone [options] <source> [dest]'),
742 "commit|ci": (commit,
742 "commit|ci": (commit,
743 [('t', 'text', "", 'commit text'),
743 [('t', 'text', "", 'commit text'),
744 ('A', 'addremove', None, 'run add/remove during commit'),
744 ('A', 'addremove', None, 'run add/remove during commit'),
745 ('l', 'logfile', "", 'commit text file'),
745 ('l', 'logfile', "", 'commit text file'),
746 ('d', 'date', "", 'data'),
746 ('d', 'date', "", 'data'),
747 ('u', 'user', "", 'user')],
747 ('u', 'user', "", 'user')],
748 'hg commit [files]'),
748 'hg commit [files]'),
749 "copy": (copy, [], 'hg copy <source> <dest>'),
749 "copy": (copy, [], 'hg copy <source> <dest>'),
750 "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'),
750 "debugcheckdirstate": (debugcheckdirstate, [], 'debugcheckdirstate'),
751 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'),
751 "debugdumpdirstate": (debugdumpdirstate, [], 'debugdumpdirstate'),
752 "debugindex": (debugindex, [], 'debugindex <file>'),
752 "debugindex": (debugindex, [], 'debugindex <file>'),
753 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
753 "debugindexdot": (debugindexdot, [], 'debugindexdot <file>'),
754 "diff": (diff, [('r', 'rev', [], 'revision')],
754 "diff": (diff, [('r', 'rev', [], 'revision')],
755 'hg diff [-r A] [-r B] [files]'),
755 'hg diff [-r A] [-r B] [files]'),
756 "export": (export, [], "hg export <changeset>"),
756 "export": (export, [], "hg export <changeset>"),
757 "forget": (forget, [], "hg forget [files]"),
757 "forget": (forget, [], "hg forget [files]"),
758 "heads": (heads, [], 'hg heads'),
758 "heads": (heads, [], 'hg heads'),
759 "help": (help, [], 'hg help [command]'),
759 "help": (help, [], 'hg help [command]'),
760 "identify|id": (identify, [], 'hg identify'),
760 "identify|id": (identify, [], 'hg identify'),
761 "import|patch": (import_,
761 "import|patch": (import_,
762 [('p', 'strip', 1, 'path strip'),
762 [('p', 'strip', 1, 'path strip'),
763 ('b', 'base', "", 'base path')],
763 ('b', 'base', "", 'base path')],
764 "hg import [options] <patches>"),
764 "hg import [options] <patches>"),
765 "init": (init, [], 'hg init'),
765 "init": (init, [], 'hg init'),
766 "log|history": (log, [], 'hg log [file]'),
766 "log|history": (log, [], 'hg log [file]'),
767 "manifest": (manifest, [], 'hg manifest [rev]'),
767 "manifest": (manifest, [], 'hg manifest [rev]'),
768 "parents": (parents, [], 'hg parents [node]'),
768 "parents": (parents, [], 'hg parents [node]'),
769 "pull": (pull,
769 "pull": (pull,
770 [('u', 'update', None, 'update working directory')],
770 [('u', 'update', None, 'update working directory')],
771 'hg pull [options] [source]'),
771 'hg pull [options] [source]'),
772 "push": (push, [], 'hg push <destination>'),
772 "push": (push, [], 'hg push <destination>'),
773 "rawcommit": (rawcommit,
773 "rawcommit": (rawcommit,
774 [('p', 'parent', [], 'parent'),
774 [('p', 'parent', [], 'parent'),
775 ('d', 'date', "", 'data'),
775 ('d', 'date', "", 'data'),
776 ('u', 'user', "", 'user'),
776 ('u', 'user', "", 'user'),
777 ('F', 'files', "", 'file list'),
777 ('F', 'files', "", 'file list'),
778 ('t', 'text', "", 'commit text'),
778 ('t', 'text', "", 'commit text'),
779 ('l', 'logfile', "", 'commit text file')],
779 ('l', 'logfile', "", 'commit text file')],
780 'hg rawcommit [options] [files]'),
780 'hg rawcommit [options] [files]'),
781 "recover": (recover, [], "hg recover"),
781 "recover": (recover, [], "hg recover"),
782 "remove|rm": (remove, [], "hg remove [files]"),
782 "remove|rm": (remove, [], "hg remove [files]"),
783 "root": (root, [], "hg root"),
783 "root": (root, [], "hg root"),
784 "serve": (serve, [('p', 'port', 8000, 'listen port'),
784 "serve": (serve, [('p', 'port', 8000, 'listen port'),
785 ('a', 'address', '', 'interface address'),
785 ('a', 'address', '', 'interface address'),
786 ('n', 'name', os.getcwd(), 'repository name'),
786 ('n', 'name', os.getcwd(), 'repository name'),
787 ('t', 'templates', "", 'template map')],
787 ('t', 'templates', "", 'template map')],
788 "hg serve [options]"),
788 "hg serve [options]"),
789 "status": (status, [], 'hg status'),
789 "status": (status, [], 'hg status'),
790 "tag": (tag, [('t', 'text', "", 'commit text'),
790 "tag": (tag, [('t', 'text', "", 'commit text'),
791 ('d', 'date', "", 'date'),
791 ('d', 'date', "", 'date'),
792 ('u', 'user', "", 'user')],
792 ('u', 'user', "", 'user')],
793 'hg tag [options] <name> [rev]'),
793 'hg tag [options] <name> [rev]'),
794 "tags": (tags, [], 'hg tags'),
794 "tags": (tags, [], 'hg tags'),
795 "tip": (tip, [], 'hg tip'),
795 "tip": (tip, [], 'hg tip'),
796 "undo": (undo, [], 'hg undo'),
796 "undo": (undo, [], 'hg undo'),
797 "update|up|checkout|co":
797 "update|up|checkout|co":
798 (update,
798 (update,
799 [('m', 'merge', None, 'allow merging of conflicts'),
799 [('m', 'merge', None, 'allow merging of conflicts'),
800 ('C', 'clean', None, 'overwrite locally modified files')],
800 ('C', 'clean', None, 'overwrite locally modified files')],
801 'hg update [options] [node]'),
801 'hg update [options] [node]'),
802 "verify": (verify, [], 'hg verify'),
802 "verify": (verify, [], 'hg verify'),
803 "version": (show_version, [], 'hg version'),
803 "version": (show_version, [], 'hg version'),
804 }
804 }
805
805
806 norepo = "clone init version help debugindex debugindexdot"
806 norepo = "clone init version help debugindex debugindexdot"
807
807
808 def find(cmd):
808 def find(cmd):
809 for e in table.keys():
809 for e in table.keys():
810 if re.match("(%s)$" % e, cmd):
810 if re.match("(%s)$" % e, cmd):
811 return table[e]
811 return table[e]
812
812
813 raise UnknownCommand(cmd)
813 raise UnknownCommand(cmd)
814
814
815 class SignalInterrupt(Exception): pass
815 class SignalInterrupt(Exception): pass
816
816
817 def catchterm(*args):
817 def catchterm(*args):
818 raise SignalInterrupt
818 raise SignalInterrupt
819
819
820 def run():
820 def run():
821 sys.exit(dispatch(sys.argv[1:]))
821 sys.exit(dispatch(sys.argv[1:]))
822
822
823 def dispatch(args):
823 def dispatch(args):
824 options = {}
824 options = {}
825 opts = [('v', 'verbose', None, 'verbose'),
825 opts = [('v', 'verbose', None, 'verbose'),
826 ('d', 'debug', None, 'debug'),
826 ('d', 'debug', None, 'debug'),
827 ('q', 'quiet', None, 'quiet'),
827 ('q', 'quiet', None, 'quiet'),
828 ('p', 'profile', None, 'profile'),
828 ('p', 'profile', None, 'profile'),
829 ('R', 'repository', "", 'repository root directory'),
829 ('R', 'repository', "", 'repository root directory'),
830 ('', 'traceback', None, 'print traceback on exception'),
830 ('', 'traceback', None, 'print traceback on exception'),
831 ('y', 'noninteractive', None, 'run non-interactively'),
831 ('y', 'noninteractive', None, 'run non-interactively'),
832 ('', 'version', None, 'output version information and exit'),
832 ('', 'version', None, 'output version information and exit'),
833 ]
833 ]
834
834
835 args = fancyopts.fancyopts(args, opts, options,
835 args = fancyopts.fancyopts(args, opts, options,
836 'hg [options] <command> [options] [files]')
836 'hg [options] <command> [options] [files]')
837
837
838 if not args:
838 if not args:
839 cmd = "help"
839 cmd = "help"
840 else:
840 else:
841 cmd, args = args[0], args[1:]
841 cmd, args = args[0], args[1:]
842
842
843 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
843 u = ui.ui(options["verbose"], options["debug"], options["quiet"],
844 not options["noninteractive"])
844 not options["noninteractive"])
845
845
846 if options["version"]:
846 if options["version"]:
847 show_version(u)
847 show_version(u)
848 sys.exit(0)
848 sys.exit(0)
849
849
850 try:
850 try:
851 i = find(cmd)
851 i = find(cmd)
852 except UnknownCommand:
852 except UnknownCommand:
853 u.warn("hg: unknown command '%s'\n" % cmd)
853 u.warn("hg: unknown command '%s'\n" % cmd)
854 help(u)
854 help(u)
855 sys.exit(1)
855 sys.exit(1)
856
856
857 signal.signal(signal.SIGTERM, catchterm)
857 signal.signal(signal.SIGTERM, catchterm)
858
858
859 cmdoptions = {}
859 cmdoptions = {}
860 try:
860 try:
861 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
861 args = fancyopts.fancyopts(args, i[1], cmdoptions, i[2])
862 except fancyopts.getopt.GetoptError, inst:
862 except fancyopts.getopt.GetoptError, inst:
863 u.warn("hg %s: %s\n" % (cmd, inst))
863 u.warn("hg %s: %s\n" % (cmd, inst))
864 help(u, cmd)
864 help(u, cmd)
865 sys.exit(-1)
865 sys.exit(-1)
866
866
867 try:
867 try:
868 try:
868 try:
869 if cmd not in norepo.split():
869 if cmd not in norepo.split():
870 path = options["repository"] or ""
870 path = options["repository"] or ""
871 repo = hg.repository(ui=u, path=path)
871 repo = hg.repository(ui=u, path=path)
872 d = lambda: i[0](u, repo, *args, **cmdoptions)
872 d = lambda: i[0](u, repo, *args, **cmdoptions)
873 else:
873 else:
874 d = lambda: i[0](u, *args, **cmdoptions)
874 d = lambda: i[0](u, *args, **cmdoptions)
875
875
876 if options['profile']:
876 if options['profile']:
877 import hotshot, hotshot.stats
877 import hotshot, hotshot.stats
878 prof = hotshot.Profile("hg.prof")
878 prof = hotshot.Profile("hg.prof")
879 r = prof.runcall(d)
879 r = prof.runcall(d)
880 prof.close()
880 prof.close()
881 stats = hotshot.stats.load("hg.prof")
881 stats = hotshot.stats.load("hg.prof")
882 stats.strip_dirs()
882 stats.strip_dirs()
883 stats.sort_stats('time', 'calls')
883 stats.sort_stats('time', 'calls')
884 stats.print_stats(40)
884 stats.print_stats(40)
885 return r
885 return r
886 else:
886 else:
887 return d()
887 return d()
888 except:
888 except:
889 if options['traceback']:
889 if options['traceback']:
890 traceback.print_exc()
890 traceback.print_exc()
891 raise
891 raise
892 except util.CommandError, inst:
892 except util.CommandError, inst:
893 u.warn("abort: %s\n" % inst.args)
893 u.warn("abort: %s\n" % inst.args)
894 except hg.RepoError, inst:
894 except hg.RepoError, inst:
895 u.warn("abort: ", inst, "!\n")
895 u.warn("abort: ", inst, "!\n")
896 except SignalInterrupt:
896 except SignalInterrupt:
897 u.warn("killed!\n")
897 u.warn("killed!\n")
898 except KeyboardInterrupt:
898 except KeyboardInterrupt:
899 u.warn("interrupted!\n")
899 u.warn("interrupted!\n")
900 except IOError, inst:
900 except IOError, inst:
901 if hasattr(inst, "code"):
901 if hasattr(inst, "code"):
902 u.warn("abort: %s\n" % inst)
902 u.warn("abort: %s\n" % inst)
903 elif hasattr(inst, "reason"):
903 elif hasattr(inst, "reason"):
904 u.warn("abort: error %d: %s\n" % (inst.reason[0], inst.reason[1]))
904 u.warn("abort: error %d: %s\n" % (inst.reason[0], inst.reason[1]))
905 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
905 elif hasattr(inst, "args") and inst[0] == errno.EPIPE:
906 u.warn("broken pipe\n")
906 u.warn("broken pipe\n")
907 else:
907 else:
908 raise
908 raise
909 except TypeError, inst:
909 except TypeError, inst:
910 # was this an argument error?
910 # was this an argument error?
911 tb = traceback.extract_tb(sys.exc_info()[2])
911 tb = traceback.extract_tb(sys.exc_info()[2])
912 if len(tb) > 2: # no
912 if len(tb) > 2: # no
913 raise
913 raise
914 u.debug(inst, "\n")
914 u.debug(inst, "\n")
915 u.warn("%s: invalid arguments\n" % i[0].__name__)
915 u.warn("%s: invalid arguments\n" % i[0].__name__)
916 help(u, cmd)
916 help(u, cmd)
917
917
918 sys.exit(-1)
918 sys.exit(-1)
919
919
@@ -1,111 +1,117 b''
1 + hg -d init
1 + hg -d init
2 + echo this is a1
2 + echo this is a1
3 + hg -d add a
3 + hg -d add a
4 + hg -d commit -t0 -d '0 0' -u user
4 + hg -d commit -t0 -d '0 0' -u user
5 a
5 a
6 + echo this is b1
6 + echo this is b1
7 + hg -d add b
7 + hg -d add b
8 + hg -d commit -t1 -d '0 0' -u user
8 + hg -d commit -t1 -d '0 0' -u user
9 b
9 b
10 + hg -d manifest 1
10 + hg -d manifest 1
11 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
11 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
12 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
12 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
13 + echo this is c1
13 + echo this is c1
14 + hg -d rawcommit -p 1 -d '0 0' -u user -t2 c
14 + hg -d rawcommit -p 1 -d '0 0' -u user -t2 c
15 + hg -d manifest 2
15 + hg -d manifest 2
16 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
16 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
17 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
17 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
18 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
18 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
19 + hg -d parents
19 + hg -d parents
20 changeset: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
20 changeset: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
21 tag: tip
21 tag: tip
22 parent: 1:3cefbe5cc27b3a068b7a6899ddff22a9874a7e69
22 parent: 1:3cefbe5cc27b3a068b7a6899ddff22a9874a7e69
23 parent: -1:0000000000000000000000000000000000000000
23 parent: -1:0000000000000000000000000000000000000000
24 manifest: 2:f5d7a10be55c91e08fbd4f527ab313aff2761fc6
24 manifest: 2:f5d7a10be55c91e08fbd4f527ab313aff2761fc6
25 user: user
25 user: user
26 date: Thu Jan 1 00:00:00 1970
26 date: Thu Jan 1 00:00:00 1970
27 files+: c
27 files+: c
28 description:
28 description:
29 2
29 2
30
30
31
31 + rm b
32 + rm b
32 + hg -d rawcommit -p 2 -d '0 0' -u user -t3 b
33 + hg -d rawcommit -p 2 -d '0 0' -u user -t3 b
33 + hg -d manifest 3
34 + hg -d manifest 3
34 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
35 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
35 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
36 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
36 + hg -d parents
37 + hg -d parents
37 changeset: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
38 changeset: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
38 tag: tip
39 tag: tip
39 parent: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
40 parent: 2:c4ef0ef0554dff3ceade68d75539e4f208a2be0a
40 parent: -1:0000000000000000000000000000000000000000
41 parent: -1:0000000000000000000000000000000000000000
41 manifest: 3:1102cb6dde652ec2ba8cc2777e464853afa67cef
42 manifest: 3:1102cb6dde652ec2ba8cc2777e464853afa67cef
42 user: user
43 user: user
43 date: Thu Jan 1 00:00:00 1970
44 date: Thu Jan 1 00:00:00 1970
44 files-: b
45 files-: b
45 description:
46 description:
46 3
47 3
47
48
49
48 + echo this is a22
50 + echo this is a22
49 + hg -d rawcommit -p 3 -d '0 0' -u user -t4 a
51 + hg -d rawcommit -p 3 -d '0 0' -u user -t4 a
50 + hg -d manifest 4
52 + hg -d manifest 4
51 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
53 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
52 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
54 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
53 + hg -d parents
55 + hg -d parents
54 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
56 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
55 tag: tip
57 tag: tip
56 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
58 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
57 parent: -1:0000000000000000000000000000000000000000
59 parent: -1:0000000000000000000000000000000000000000
58 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
60 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
59 user: user
61 user: user
60 date: Thu Jan 1 00:00:00 1970
62 date: Thu Jan 1 00:00:00 1970
61 files: a
63 files: a
62 description:
64 description:
63 4
65 4
64
66
67
65 + echo this is c22
68 + echo this is c22
66 + hg -d rawcommit -p 1 -d '0 0' -u user -t5 c
69 + hg -d rawcommit -p 1 -d '0 0' -u user -t5 c
67 + hg -d manifest 5
70 + hg -d manifest 5
68 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
71 05f9e54f4c9b86b09099803d8b49a50edcb4eaab 644 a
69 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
72 54837d97f2932a8194e69745a280a2c11e61ff9c 644 b
70 3570202ceac2b52517df64ebd0a062cb0d8fe33a 644 c
73 3570202ceac2b52517df64ebd0a062cb0d8fe33a 644 c
71 + hg -d parents
74 + hg -d parents
72 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
75 changeset: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
73 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
76 parent: 3:923669243607c26c4c8f0c11f48c1182ce1a7aff
74 parent: -1:0000000000000000000000000000000000000000
77 parent: -1:0000000000000000000000000000000000000000
75 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
78 manifest: 4:cf4021621d6357e928385ffeee996f87c0bf991d
76 user: user
79 user: user
77 date: Thu Jan 1 00:00:00 1970
80 date: Thu Jan 1 00:00:00 1970
78 files: a
81 files: a
79 description:
82 description:
80 4
83 4
81
84
85
82 + hg -d rawcommit -p 4 -p 5 -d '0 0' -u user -t6
86 + hg -d rawcommit -p 4 -p 5 -d '0 0' -u user -t6
83 + hg -d manifest 6
87 + hg -d manifest 6
84 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
88 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
85 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
89 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
86 + hg -d parents
90 + hg -d parents
87 changeset: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
91 changeset: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
88 tag: tip
92 tag: tip
89 parent: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
93 parent: 4:2361ec7b1da5142bce1285c50f3bb2960706263d
90 parent: 5:f8292b00383d88b470efcb2ea9c71409832ec9d6
94 parent: 5:f8292b00383d88b470efcb2ea9c71409832ec9d6
91 manifest: 6:71c4262e09a89666ee12a92fefa12085aad53243
95 manifest: 6:71c4262e09a89666ee12a92fefa12085aad53243
92 user: user
96 user: user
93 date: Thu Jan 1 00:00:00 1970
97 date: Thu Jan 1 00:00:00 1970
94 description:
98 description:
95 6
99 6
96
100
101
97 + hg -d rawcommit -p 6 -d '0 0' -u user -t7
102 + hg -d rawcommit -p 6 -d '0 0' -u user -t7
98 + hg -d manifest 7
103 + hg -d manifest 7
99 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
104 d6e3c4976c13feb1728cd3ac851abaf7256a5c23 644 a
100 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
105 76d5e637cbec1bcc04a5a3fa4bcc7d13f6847c00 644 c
101 + hg -d parents
106 + hg -d parents
102 changeset: 7:836ff890ac9ecb8c4b7c209b3e8b93f8805ca5f0
107 changeset: 7:836ff890ac9ecb8c4b7c209b3e8b93f8805ca5f0
103 tag: tip
108 tag: tip
104 parent: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
109 parent: 6:aaf55aee7b6249fd7d4ba295d98c4492ec2740d7
105 parent: -1:0000000000000000000000000000000000000000
110 parent: -1:0000000000000000000000000000000000000000
106 manifest: 7:c15305fbac9dd3f49bffcc17d659b2d06d10b9a2
111 manifest: 7:c15305fbac9dd3f49bffcc17d659b2d06d10b9a2
107 user: user
112 user: user
108 date: Thu Jan 1 00:00:00 1970
113 date: Thu Jan 1 00:00:00 1970
109 description:
114 description:
110 7
115 7
111
116
117
@@ -1,72 +1,74 b''
1 + mkdir r1
1 + mkdir r1
2 + cd r1
2 + cd r1
3 + hg init
3 + hg init
4 + echo a
4 + echo a
5 + hg addremove
5 + hg addremove
6 + hg commit -t 1 -u test -d '0 0'
6 + hg commit -t 1 -u test -d '0 0'
7 + hg clone . ../r2
7 + hg clone . ../r2
8 + cd ../r2
8 + cd ../r2
9 + hg up
9 + hg up
10 + echo abc
10 + echo abc
11 + hg diff
11 + hg diff
12 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
12 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
13 diff -r c19d34741b0a a
13 diff -r c19d34741b0a a
14 --- a/a
14 --- a/a
15 +++ b/a
15 +++ b/a
16 @@ -1,1 +1,1 @@
16 @@ -1,1 +1,1 @@
17 -a
17 -a
18 +abc
18 +abc
19 + cd ../r1
19 + cd ../r1
20 + echo b
20 + echo b
21 + echo a2
21 + echo a2
22 + hg addremove
22 + hg addremove
23 + hg commit -t 2 -u test -d '0 0'
23 + hg commit -t 2 -u test -d '0 0'
24 + cd ../r2
24 + cd ../r2
25 + hg -q pull ../r1
25 + hg -q pull ../r1
26 + hg status
26 + hg status
27 C a
27 C a
28 + hg -d up
28 + hg -d up
29 resolving manifests
29 resolving manifests
30 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
30 ancestor a0c8bcbbb45c local a0c8bcbbb45c remote 1165e8bd193e
31 a versions differ, resolve
31 a versions differ, resolve
32 remote created b
32 remote created b
33 getting b
33 getting b
34 merging a
34 merging a
35 resolving a
35 resolving a
36 file a: other d730145abbf9 ancestor b789fdd96dc2
36 file a: other d730145abbf9 ancestor b789fdd96dc2
37 + hg -d up -m
37 + hg -d up -m
38 resolving manifests
38 resolving manifests
39 ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e
39 ancestor 1165e8bd193e local 1165e8bd193e remote 1165e8bd193e
40 + hg parents
40 + hg parents
41 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
41 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
42 tag: tip
42 tag: tip
43 user: test
43 user: test
44 date: Thu Jan 1 00:00:00 1970
44 date: Thu Jan 1 00:00:00 1970
45 summary: 2
45 summary: 2
46
46
47 + hg -v history
47 + hg -v history
48 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
48 changeset: 1:1e71731e6fbb5b35fae293120dea6964371c13c6
49 tag: tip
49 tag: tip
50 manifest: 1:1165e8bd193e17ad7d321d846fcf27ff3f412758
50 manifest: 1:1165e8bd193e17ad7d321d846fcf27ff3f412758
51 user: test
51 user: test
52 date: Thu Jan 1 00:00:00 1970
52 date: Thu Jan 1 00:00:00 1970
53 files: a b
53 files: a b
54 description:
54 description:
55 2
55 2
56
56
57
57 changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e
58 changeset: 0:c19d34741b0a4ced8e4ba74bb834597d5193851e
58 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
59 manifest: 0:a0c8bcbbb45c63b90b70ad007bf38961f64f2af0
59 user: test
60 user: test
60 date: Thu Jan 1 00:00:00 1970
61 date: Thu Jan 1 00:00:00 1970
61 files: a
62 files: a
62 description:
63 description:
63 1
64 1
64
65
66
65 + hg diff
67 + hg diff
66 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
68 + sed 's/\(\(---\|+++\).*\)\t.*/\1/'
67 diff -r 1e71731e6fbb a
69 diff -r 1e71731e6fbb a
68 --- a/a
70 --- a/a
69 +++ b/a
71 +++ b/a
70 @@ -1,1 +1,1 @@
72 @@ -1,1 +1,1 @@
71 -a2
73 -a2
72 +abc
74 +abc
General Comments 0
You need to be logged in to leave comments. Login now