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