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