##// END OF EJS Templates
hgweb: walk the graph through the changelog...
Pierre-Yves David -
r18428:8c10f760 default
parent child Browse files
Show More
@@ -1,985 +1,988 b''
1 #
1 #
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 import os, mimetypes, re, cgi, copy
8 import os, mimetypes, re, cgi, copy
9 import webutil
9 import webutil
10 from mercurial import error, encoding, archival, templater, templatefilters
10 from mercurial import error, encoding, archival, templater, templatefilters
11 from mercurial.node import short, hex, nullid
11 from mercurial.node import short, hex, nullid
12 from mercurial.util import binary
12 from mercurial.util import binary
13 from common import paritygen, staticfile, get_contact, ErrorResponse
13 from common import paritygen, staticfile, get_contact, ErrorResponse
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
14 from common import HTTP_OK, HTTP_FORBIDDEN, HTTP_NOT_FOUND
15 from mercurial import graphmod, patch
15 from mercurial import graphmod, patch
16 from mercurial import help as helpmod
16 from mercurial import help as helpmod
17 from mercurial import scmutil
17 from mercurial import scmutil
18 from mercurial.i18n import _
18 from mercurial.i18n import _
19
19
20 # __all__ is populated with the allowed commands. Be sure to add to it if
20 # __all__ is populated with the allowed commands. Be sure to add to it if
21 # you're adding a new command, or the new command won't work.
21 # you're adding a new command, or the new command won't work.
22
22
23 __all__ = [
23 __all__ = [
24 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
24 'log', 'rawfile', 'file', 'changelog', 'shortlog', 'changeset', 'rev',
25 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
25 'manifest', 'tags', 'bookmarks', 'branches', 'summary', 'filediff', 'diff',
26 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
26 'comparison', 'annotate', 'filelog', 'archive', 'static', 'graph', 'help',
27 ]
27 ]
28
28
29 def log(web, req, tmpl):
29 def log(web, req, tmpl):
30 if 'file' in req.form and req.form['file'][0]:
30 if 'file' in req.form and req.form['file'][0]:
31 return filelog(web, req, tmpl)
31 return filelog(web, req, tmpl)
32 else:
32 else:
33 return changelog(web, req, tmpl)
33 return changelog(web, req, tmpl)
34
34
35 def rawfile(web, req, tmpl):
35 def rawfile(web, req, tmpl):
36 guessmime = web.configbool('web', 'guessmime', False)
36 guessmime = web.configbool('web', 'guessmime', False)
37
37
38 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
38 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
39 if not path:
39 if not path:
40 content = manifest(web, req, tmpl)
40 content = manifest(web, req, tmpl)
41 req.respond(HTTP_OK, web.ctype)
41 req.respond(HTTP_OK, web.ctype)
42 return content
42 return content
43
43
44 try:
44 try:
45 fctx = webutil.filectx(web.repo, req)
45 fctx = webutil.filectx(web.repo, req)
46 except error.LookupError, inst:
46 except error.LookupError, inst:
47 try:
47 try:
48 content = manifest(web, req, tmpl)
48 content = manifest(web, req, tmpl)
49 req.respond(HTTP_OK, web.ctype)
49 req.respond(HTTP_OK, web.ctype)
50 return content
50 return content
51 except ErrorResponse:
51 except ErrorResponse:
52 raise inst
52 raise inst
53
53
54 path = fctx.path()
54 path = fctx.path()
55 text = fctx.data()
55 text = fctx.data()
56 mt = 'application/binary'
56 mt = 'application/binary'
57 if guessmime:
57 if guessmime:
58 mt = mimetypes.guess_type(path)[0]
58 mt = mimetypes.guess_type(path)[0]
59 if mt is None:
59 if mt is None:
60 mt = binary(text) and 'application/binary' or 'text/plain'
60 mt = binary(text) and 'application/binary' or 'text/plain'
61 if mt.startswith('text/'):
61 if mt.startswith('text/'):
62 mt += '; charset="%s"' % encoding.encoding
62 mt += '; charset="%s"' % encoding.encoding
63
63
64 req.respond(HTTP_OK, mt, path, body=text)
64 req.respond(HTTP_OK, mt, path, body=text)
65 return []
65 return []
66
66
67 def _filerevision(web, tmpl, fctx):
67 def _filerevision(web, tmpl, fctx):
68 f = fctx.path()
68 f = fctx.path()
69 text = fctx.data()
69 text = fctx.data()
70 parity = paritygen(web.stripecount)
70 parity = paritygen(web.stripecount)
71
71
72 if binary(text):
72 if binary(text):
73 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
73 mt = mimetypes.guess_type(f)[0] or 'application/octet-stream'
74 text = '(binary:%s)' % mt
74 text = '(binary:%s)' % mt
75
75
76 def lines():
76 def lines():
77 for lineno, t in enumerate(text.splitlines(True)):
77 for lineno, t in enumerate(text.splitlines(True)):
78 yield {"line": t,
78 yield {"line": t,
79 "lineid": "l%d" % (lineno + 1),
79 "lineid": "l%d" % (lineno + 1),
80 "linenumber": "% 6d" % (lineno + 1),
80 "linenumber": "% 6d" % (lineno + 1),
81 "parity": parity.next()}
81 "parity": parity.next()}
82
82
83 return tmpl("filerevision",
83 return tmpl("filerevision",
84 file=f,
84 file=f,
85 path=webutil.up(f),
85 path=webutil.up(f),
86 text=lines(),
86 text=lines(),
87 rev=fctx.rev(),
87 rev=fctx.rev(),
88 node=fctx.hex(),
88 node=fctx.hex(),
89 author=fctx.user(),
89 author=fctx.user(),
90 date=fctx.date(),
90 date=fctx.date(),
91 desc=fctx.description(),
91 desc=fctx.description(),
92 branch=webutil.nodebranchnodefault(fctx),
92 branch=webutil.nodebranchnodefault(fctx),
93 parent=webutil.parents(fctx),
93 parent=webutil.parents(fctx),
94 child=webutil.children(fctx),
94 child=webutil.children(fctx),
95 rename=webutil.renamelink(fctx),
95 rename=webutil.renamelink(fctx),
96 permissions=fctx.manifest().flags(f))
96 permissions=fctx.manifest().flags(f))
97
97
98 def file(web, req, tmpl):
98 def file(web, req, tmpl):
99 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
99 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
100 if not path:
100 if not path:
101 return manifest(web, req, tmpl)
101 return manifest(web, req, tmpl)
102 try:
102 try:
103 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
103 return _filerevision(web, tmpl, webutil.filectx(web.repo, req))
104 except error.LookupError, inst:
104 except error.LookupError, inst:
105 try:
105 try:
106 return manifest(web, req, tmpl)
106 return manifest(web, req, tmpl)
107 except ErrorResponse:
107 except ErrorResponse:
108 raise inst
108 raise inst
109
109
110 def _search(web, req, tmpl):
110 def _search(web, req, tmpl):
111
111
112 query = req.form['rev'][0]
112 query = req.form['rev'][0]
113 revcount = web.maxchanges
113 revcount = web.maxchanges
114 if 'revcount' in req.form:
114 if 'revcount' in req.form:
115 revcount = int(req.form.get('revcount', [revcount])[0])
115 revcount = int(req.form.get('revcount', [revcount])[0])
116 revcount = max(revcount, 1)
116 revcount = max(revcount, 1)
117 tmpl.defaults['sessionvars']['revcount'] = revcount
117 tmpl.defaults['sessionvars']['revcount'] = revcount
118
118
119 lessvars = copy.copy(tmpl.defaults['sessionvars'])
119 lessvars = copy.copy(tmpl.defaults['sessionvars'])
120 lessvars['revcount'] = max(revcount / 2, 1)
120 lessvars['revcount'] = max(revcount / 2, 1)
121 lessvars['rev'] = query
121 lessvars['rev'] = query
122 morevars = copy.copy(tmpl.defaults['sessionvars'])
122 morevars = copy.copy(tmpl.defaults['sessionvars'])
123 morevars['revcount'] = revcount * 2
123 morevars['revcount'] = revcount * 2
124 morevars['rev'] = query
124 morevars['rev'] = query
125
125
126 def changelist(**map):
126 def changelist(**map):
127 count = 0
127 count = 0
128 lower = encoding.lower
128 lower = encoding.lower
129 qw = lower(query).split()
129 qw = lower(query).split()
130
130
131 def revgen():
131 def revgen():
132 for i in xrange(len(web.repo) - 1, 0, -100):
132 for i in xrange(len(web.repo) - 1, 0, -100):
133 l = []
133 l = []
134 for j in xrange(max(0, i - 100), i + 1):
134 for j in xrange(max(0, i - 100), i + 1):
135 ctx = web.repo[j]
135 ctx = web.repo[j]
136 l.append(ctx)
136 l.append(ctx)
137 l.reverse()
137 l.reverse()
138 for e in l:
138 for e in l:
139 yield e
139 yield e
140
140
141 for ctx in revgen():
141 for ctx in revgen():
142 miss = 0
142 miss = 0
143 for q in qw:
143 for q in qw:
144 if not (q in lower(ctx.user()) or
144 if not (q in lower(ctx.user()) or
145 q in lower(ctx.description()) or
145 q in lower(ctx.description()) or
146 q in lower(" ".join(ctx.files()))):
146 q in lower(" ".join(ctx.files()))):
147 miss = 1
147 miss = 1
148 break
148 break
149 if miss:
149 if miss:
150 continue
150 continue
151
151
152 count += 1
152 count += 1
153 n = ctx.node()
153 n = ctx.node()
154 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
154 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
155 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
155 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
156
156
157 yield tmpl('searchentry',
157 yield tmpl('searchentry',
158 parity=parity.next(),
158 parity=parity.next(),
159 author=ctx.user(),
159 author=ctx.user(),
160 parent=webutil.parents(ctx),
160 parent=webutil.parents(ctx),
161 child=webutil.children(ctx),
161 child=webutil.children(ctx),
162 changelogtag=showtags,
162 changelogtag=showtags,
163 desc=ctx.description(),
163 desc=ctx.description(),
164 date=ctx.date(),
164 date=ctx.date(),
165 files=files,
165 files=files,
166 rev=ctx.rev(),
166 rev=ctx.rev(),
167 node=hex(n),
167 node=hex(n),
168 tags=webutil.nodetagsdict(web.repo, n),
168 tags=webutil.nodetagsdict(web.repo, n),
169 bookmarks=webutil.nodebookmarksdict(web.repo, n),
169 bookmarks=webutil.nodebookmarksdict(web.repo, n),
170 inbranch=webutil.nodeinbranch(web.repo, ctx),
170 inbranch=webutil.nodeinbranch(web.repo, ctx),
171 branches=webutil.nodebranchdict(web.repo, ctx))
171 branches=webutil.nodebranchdict(web.repo, ctx))
172
172
173 if count >= revcount:
173 if count >= revcount:
174 break
174 break
175
175
176 tip = web.repo['tip']
176 tip = web.repo['tip']
177 parity = paritygen(web.stripecount)
177 parity = paritygen(web.stripecount)
178
178
179 return tmpl('search', query=query, node=tip.hex(),
179 return tmpl('search', query=query, node=tip.hex(),
180 entries=changelist, archives=web.archivelist("tip"),
180 entries=changelist, archives=web.archivelist("tip"),
181 morevars=morevars, lessvars=lessvars)
181 morevars=morevars, lessvars=lessvars)
182
182
183 def changelog(web, req, tmpl, shortlog=False):
183 def changelog(web, req, tmpl, shortlog=False):
184
184
185 if 'node' in req.form:
185 if 'node' in req.form:
186 ctx = webutil.changectx(web.repo, req)
186 ctx = webutil.changectx(web.repo, req)
187 else:
187 else:
188 if 'rev' in req.form:
188 if 'rev' in req.form:
189 hi = req.form['rev'][0]
189 hi = req.form['rev'][0]
190 else:
190 else:
191 hi = len(web.repo) - 1
191 hi = len(web.repo) - 1
192 try:
192 try:
193 ctx = web.repo[hi]
193 ctx = web.repo[hi]
194 except error.RepoError:
194 except error.RepoError:
195 return _search(web, req, tmpl) # XXX redirect to 404 page?
195 return _search(web, req, tmpl) # XXX redirect to 404 page?
196
196
197 def changelist(latestonly, **map):
197 def changelist(latestonly, **map):
198 l = [] # build a list in forward order for efficiency
198 l = [] # build a list in forward order for efficiency
199 revs = []
199 revs = []
200 if start < end:
200 if start < end:
201 revs = web.repo.changelog.revs(start, end - 1)
201 revs = web.repo.changelog.revs(start, end - 1)
202 if latestonly:
202 if latestonly:
203 for r in revs:
203 for r in revs:
204 pass
204 pass
205 revs = (r,)
205 revs = (r,)
206 for i in revs:
206 for i in revs:
207 ctx = web.repo[i]
207 ctx = web.repo[i]
208 n = ctx.node()
208 n = ctx.node()
209 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
209 showtags = webutil.showtag(web.repo, tmpl, 'changelogtag', n)
210 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
210 files = webutil.listfilediffs(tmpl, ctx.files(), n, web.maxfiles)
211
211
212 l.append({"parity": parity.next(),
212 l.append({"parity": parity.next(),
213 "author": ctx.user(),
213 "author": ctx.user(),
214 "parent": webutil.parents(ctx, i - 1),
214 "parent": webutil.parents(ctx, i - 1),
215 "child": webutil.children(ctx, i + 1),
215 "child": webutil.children(ctx, i + 1),
216 "changelogtag": showtags,
216 "changelogtag": showtags,
217 "desc": ctx.description(),
217 "desc": ctx.description(),
218 "date": ctx.date(),
218 "date": ctx.date(),
219 "files": files,
219 "files": files,
220 "rev": i,
220 "rev": i,
221 "node": hex(n),
221 "node": hex(n),
222 "tags": webutil.nodetagsdict(web.repo, n),
222 "tags": webutil.nodetagsdict(web.repo, n),
223 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
223 "bookmarks": webutil.nodebookmarksdict(web.repo, n),
224 "inbranch": webutil.nodeinbranch(web.repo, ctx),
224 "inbranch": webutil.nodeinbranch(web.repo, ctx),
225 "branches": webutil.nodebranchdict(web.repo, ctx)
225 "branches": webutil.nodebranchdict(web.repo, ctx)
226 })
226 })
227 for e in reversed(l):
227 for e in reversed(l):
228 yield e
228 yield e
229
229
230 revcount = shortlog and web.maxshortchanges or web.maxchanges
230 revcount = shortlog and web.maxshortchanges or web.maxchanges
231 if 'revcount' in req.form:
231 if 'revcount' in req.form:
232 revcount = int(req.form.get('revcount', [revcount])[0])
232 revcount = int(req.form.get('revcount', [revcount])[0])
233 revcount = max(revcount, 1)
233 revcount = max(revcount, 1)
234 tmpl.defaults['sessionvars']['revcount'] = revcount
234 tmpl.defaults['sessionvars']['revcount'] = revcount
235
235
236 lessvars = copy.copy(tmpl.defaults['sessionvars'])
236 lessvars = copy.copy(tmpl.defaults['sessionvars'])
237 lessvars['revcount'] = max(revcount / 2, 1)
237 lessvars['revcount'] = max(revcount / 2, 1)
238 morevars = copy.copy(tmpl.defaults['sessionvars'])
238 morevars = copy.copy(tmpl.defaults['sessionvars'])
239 morevars['revcount'] = revcount * 2
239 morevars['revcount'] = revcount * 2
240
240
241 count = len(web.repo)
241 count = len(web.repo)
242 pos = ctx.rev()
242 pos = ctx.rev()
243 start = max(0, pos - revcount + 1)
243 start = max(0, pos - revcount + 1)
244 end = min(count, start + revcount)
244 end = min(count, start + revcount)
245 pos = end - 1
245 pos = end - 1
246 parity = paritygen(web.stripecount, offset=start - end)
246 parity = paritygen(web.stripecount, offset=start - end)
247
247
248 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
248 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
249
249
250 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
250 return tmpl(shortlog and 'shortlog' or 'changelog', changenav=changenav,
251 node=ctx.hex(), rev=pos, changesets=count,
251 node=ctx.hex(), rev=pos, changesets=count,
252 entries=lambda **x: changelist(latestonly=False, **x),
252 entries=lambda **x: changelist(latestonly=False, **x),
253 latestentry=lambda **x: changelist(latestonly=True, **x),
253 latestentry=lambda **x: changelist(latestonly=True, **x),
254 archives=web.archivelist("tip"), revcount=revcount,
254 archives=web.archivelist("tip"), revcount=revcount,
255 morevars=morevars, lessvars=lessvars)
255 morevars=morevars, lessvars=lessvars)
256
256
257 def shortlog(web, req, tmpl):
257 def shortlog(web, req, tmpl):
258 return changelog(web, req, tmpl, shortlog = True)
258 return changelog(web, req, tmpl, shortlog = True)
259
259
260 def changeset(web, req, tmpl):
260 def changeset(web, req, tmpl):
261 ctx = webutil.changectx(web.repo, req)
261 ctx = webutil.changectx(web.repo, req)
262 basectx = webutil.basechangectx(web.repo, req)
262 basectx = webutil.basechangectx(web.repo, req)
263 if basectx is None:
263 if basectx is None:
264 basectx = ctx.p1()
264 basectx = ctx.p1()
265 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
265 showtags = webutil.showtag(web.repo, tmpl, 'changesettag', ctx.node())
266 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
266 showbookmarks = webutil.showbookmark(web.repo, tmpl, 'changesetbookmark',
267 ctx.node())
267 ctx.node())
268 showbranch = webutil.nodebranchnodefault(ctx)
268 showbranch = webutil.nodebranchnodefault(ctx)
269
269
270 files = []
270 files = []
271 parity = paritygen(web.stripecount)
271 parity = paritygen(web.stripecount)
272 for blockno, f in enumerate(ctx.files()):
272 for blockno, f in enumerate(ctx.files()):
273 template = f in ctx and 'filenodelink' or 'filenolink'
273 template = f in ctx and 'filenodelink' or 'filenolink'
274 files.append(tmpl(template,
274 files.append(tmpl(template,
275 node=ctx.hex(), file=f, blockno=blockno + 1,
275 node=ctx.hex(), file=f, blockno=blockno + 1,
276 parity=parity.next()))
276 parity=parity.next()))
277
277
278 style = web.config('web', 'style', 'paper')
278 style = web.config('web', 'style', 'paper')
279 if 'style' in req.form:
279 if 'style' in req.form:
280 style = req.form['style'][0]
280 style = req.form['style'][0]
281
281
282 parity = paritygen(web.stripecount)
282 parity = paritygen(web.stripecount)
283 diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
283 diffs = webutil.diffs(web.repo, tmpl, ctx, basectx, None, parity, style)
284
284
285 parity = paritygen(web.stripecount)
285 parity = paritygen(web.stripecount)
286 diffstatgen = webutil.diffstatgen(ctx, basectx)
286 diffstatgen = webutil.diffstatgen(ctx, basectx)
287 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
287 diffstat = webutil.diffstat(tmpl, ctx, diffstatgen, parity)
288
288
289 return tmpl('changeset',
289 return tmpl('changeset',
290 diff=diffs,
290 diff=diffs,
291 rev=ctx.rev(),
291 rev=ctx.rev(),
292 node=ctx.hex(),
292 node=ctx.hex(),
293 parent=webutil.parents(ctx),
293 parent=webutil.parents(ctx),
294 child=webutil.children(ctx),
294 child=webutil.children(ctx),
295 currentbaseline=basectx.hex(),
295 currentbaseline=basectx.hex(),
296 changesettag=showtags,
296 changesettag=showtags,
297 changesetbookmark=showbookmarks,
297 changesetbookmark=showbookmarks,
298 changesetbranch=showbranch,
298 changesetbranch=showbranch,
299 author=ctx.user(),
299 author=ctx.user(),
300 desc=ctx.description(),
300 desc=ctx.description(),
301 date=ctx.date(),
301 date=ctx.date(),
302 files=files,
302 files=files,
303 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
303 diffsummary=lambda **x: webutil.diffsummary(diffstatgen),
304 diffstat=diffstat,
304 diffstat=diffstat,
305 archives=web.archivelist(ctx.hex()),
305 archives=web.archivelist(ctx.hex()),
306 tags=webutil.nodetagsdict(web.repo, ctx.node()),
306 tags=webutil.nodetagsdict(web.repo, ctx.node()),
307 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
307 bookmarks=webutil.nodebookmarksdict(web.repo, ctx.node()),
308 branch=webutil.nodebranchnodefault(ctx),
308 branch=webutil.nodebranchnodefault(ctx),
309 inbranch=webutil.nodeinbranch(web.repo, ctx),
309 inbranch=webutil.nodeinbranch(web.repo, ctx),
310 branches=webutil.nodebranchdict(web.repo, ctx))
310 branches=webutil.nodebranchdict(web.repo, ctx))
311
311
312 rev = changeset
312 rev = changeset
313
313
314 def decodepath(path):
314 def decodepath(path):
315 """Hook for mapping a path in the repository to a path in the
315 """Hook for mapping a path in the repository to a path in the
316 working copy.
316 working copy.
317
317
318 Extensions (e.g., largefiles) can override this to remap files in
318 Extensions (e.g., largefiles) can override this to remap files in
319 the virtual file system presented by the manifest command below."""
319 the virtual file system presented by the manifest command below."""
320 return path
320 return path
321
321
322 def manifest(web, req, tmpl):
322 def manifest(web, req, tmpl):
323 ctx = webutil.changectx(web.repo, req)
323 ctx = webutil.changectx(web.repo, req)
324 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
324 path = webutil.cleanpath(web.repo, req.form.get('file', [''])[0])
325 mf = ctx.manifest()
325 mf = ctx.manifest()
326 node = ctx.node()
326 node = ctx.node()
327
327
328 files = {}
328 files = {}
329 dirs = {}
329 dirs = {}
330 parity = paritygen(web.stripecount)
330 parity = paritygen(web.stripecount)
331
331
332 if path and path[-1] != "/":
332 if path and path[-1] != "/":
333 path += "/"
333 path += "/"
334 l = len(path)
334 l = len(path)
335 abspath = "/" + path
335 abspath = "/" + path
336
336
337 for full, n in mf.iteritems():
337 for full, n in mf.iteritems():
338 # the virtual path (working copy path) used for the full
338 # the virtual path (working copy path) used for the full
339 # (repository) path
339 # (repository) path
340 f = decodepath(full)
340 f = decodepath(full)
341
341
342 if f[:l] != path:
342 if f[:l] != path:
343 continue
343 continue
344 remain = f[l:]
344 remain = f[l:]
345 elements = remain.split('/')
345 elements = remain.split('/')
346 if len(elements) == 1:
346 if len(elements) == 1:
347 files[remain] = full
347 files[remain] = full
348 else:
348 else:
349 h = dirs # need to retain ref to dirs (root)
349 h = dirs # need to retain ref to dirs (root)
350 for elem in elements[0:-1]:
350 for elem in elements[0:-1]:
351 if elem not in h:
351 if elem not in h:
352 h[elem] = {}
352 h[elem] = {}
353 h = h[elem]
353 h = h[elem]
354 if len(h) > 1:
354 if len(h) > 1:
355 break
355 break
356 h[None] = None # denotes files present
356 h[None] = None # denotes files present
357
357
358 if mf and not files and not dirs:
358 if mf and not files and not dirs:
359 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
359 raise ErrorResponse(HTTP_NOT_FOUND, 'path not found: ' + path)
360
360
361 def filelist(**map):
361 def filelist(**map):
362 for f in sorted(files):
362 for f in sorted(files):
363 full = files[f]
363 full = files[f]
364
364
365 fctx = ctx.filectx(full)
365 fctx = ctx.filectx(full)
366 yield {"file": full,
366 yield {"file": full,
367 "parity": parity.next(),
367 "parity": parity.next(),
368 "basename": f,
368 "basename": f,
369 "date": fctx.date(),
369 "date": fctx.date(),
370 "size": fctx.size(),
370 "size": fctx.size(),
371 "permissions": mf.flags(full)}
371 "permissions": mf.flags(full)}
372
372
373 def dirlist(**map):
373 def dirlist(**map):
374 for d in sorted(dirs):
374 for d in sorted(dirs):
375
375
376 emptydirs = []
376 emptydirs = []
377 h = dirs[d]
377 h = dirs[d]
378 while isinstance(h, dict) and len(h) == 1:
378 while isinstance(h, dict) and len(h) == 1:
379 k, v = h.items()[0]
379 k, v = h.items()[0]
380 if v:
380 if v:
381 emptydirs.append(k)
381 emptydirs.append(k)
382 h = v
382 h = v
383
383
384 path = "%s%s" % (abspath, d)
384 path = "%s%s" % (abspath, d)
385 yield {"parity": parity.next(),
385 yield {"parity": parity.next(),
386 "path": path,
386 "path": path,
387 "emptydirs": "/".join(emptydirs),
387 "emptydirs": "/".join(emptydirs),
388 "basename": d}
388 "basename": d}
389
389
390 return tmpl("manifest",
390 return tmpl("manifest",
391 rev=ctx.rev(),
391 rev=ctx.rev(),
392 node=hex(node),
392 node=hex(node),
393 path=abspath,
393 path=abspath,
394 up=webutil.up(abspath),
394 up=webutil.up(abspath),
395 upparity=parity.next(),
395 upparity=parity.next(),
396 fentries=filelist,
396 fentries=filelist,
397 dentries=dirlist,
397 dentries=dirlist,
398 archives=web.archivelist(hex(node)),
398 archives=web.archivelist(hex(node)),
399 tags=webutil.nodetagsdict(web.repo, node),
399 tags=webutil.nodetagsdict(web.repo, node),
400 bookmarks=webutil.nodebookmarksdict(web.repo, node),
400 bookmarks=webutil.nodebookmarksdict(web.repo, node),
401 inbranch=webutil.nodeinbranch(web.repo, ctx),
401 inbranch=webutil.nodeinbranch(web.repo, ctx),
402 branches=webutil.nodebranchdict(web.repo, ctx))
402 branches=webutil.nodebranchdict(web.repo, ctx))
403
403
404 def tags(web, req, tmpl):
404 def tags(web, req, tmpl):
405 i = list(reversed(web.repo.tagslist()))
405 i = list(reversed(web.repo.tagslist()))
406 parity = paritygen(web.stripecount)
406 parity = paritygen(web.stripecount)
407
407
408 def entries(notip, latestonly, **map):
408 def entries(notip, latestonly, **map):
409 t = i
409 t = i
410 if notip:
410 if notip:
411 t = [(k, n) for k, n in i if k != "tip"]
411 t = [(k, n) for k, n in i if k != "tip"]
412 if latestonly:
412 if latestonly:
413 t = t[:1]
413 t = t[:1]
414 for k, n in t:
414 for k, n in t:
415 yield {"parity": parity.next(),
415 yield {"parity": parity.next(),
416 "tag": k,
416 "tag": k,
417 "date": web.repo[n].date(),
417 "date": web.repo[n].date(),
418 "node": hex(n)}
418 "node": hex(n)}
419
419
420 return tmpl("tags",
420 return tmpl("tags",
421 node=hex(web.repo.changelog.tip()),
421 node=hex(web.repo.changelog.tip()),
422 entries=lambda **x: entries(False, False, **x),
422 entries=lambda **x: entries(False, False, **x),
423 entriesnotip=lambda **x: entries(True, False, **x),
423 entriesnotip=lambda **x: entries(True, False, **x),
424 latestentry=lambda **x: entries(True, True, **x))
424 latestentry=lambda **x: entries(True, True, **x))
425
425
426 def bookmarks(web, req, tmpl):
426 def bookmarks(web, req, tmpl):
427 i = web.repo._bookmarks.items()
427 i = web.repo._bookmarks.items()
428 parity = paritygen(web.stripecount)
428 parity = paritygen(web.stripecount)
429
429
430 def entries(latestonly, **map):
430 def entries(latestonly, **map):
431 if latestonly:
431 if latestonly:
432 t = [min(i)]
432 t = [min(i)]
433 else:
433 else:
434 t = sorted(i)
434 t = sorted(i)
435 for k, n in t:
435 for k, n in t:
436 yield {"parity": parity.next(),
436 yield {"parity": parity.next(),
437 "bookmark": k,
437 "bookmark": k,
438 "date": web.repo[n].date(),
438 "date": web.repo[n].date(),
439 "node": hex(n)}
439 "node": hex(n)}
440
440
441 return tmpl("bookmarks",
441 return tmpl("bookmarks",
442 node=hex(web.repo.changelog.tip()),
442 node=hex(web.repo.changelog.tip()),
443 entries=lambda **x: entries(latestonly=False, **x),
443 entries=lambda **x: entries(latestonly=False, **x),
444 latestentry=lambda **x: entries(latestonly=True, **x))
444 latestentry=lambda **x: entries(latestonly=True, **x))
445
445
446 def branches(web, req, tmpl):
446 def branches(web, req, tmpl):
447 tips = []
447 tips = []
448 heads = web.repo.heads()
448 heads = web.repo.heads()
449 parity = paritygen(web.stripecount)
449 parity = paritygen(web.stripecount)
450 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
450 sortkey = lambda ctx: (not ctx.closesbranch(), ctx.rev())
451
451
452 def entries(limit, **map):
452 def entries(limit, **map):
453 count = 0
453 count = 0
454 if not tips:
454 if not tips:
455 for t, n in web.repo.branchtags().iteritems():
455 for t, n in web.repo.branchtags().iteritems():
456 tips.append(web.repo[n])
456 tips.append(web.repo[n])
457 for ctx in sorted(tips, key=sortkey, reverse=True):
457 for ctx in sorted(tips, key=sortkey, reverse=True):
458 if limit > 0 and count >= limit:
458 if limit > 0 and count >= limit:
459 return
459 return
460 count += 1
460 count += 1
461 if not web.repo.branchheads(ctx.branch()):
461 if not web.repo.branchheads(ctx.branch()):
462 status = 'closed'
462 status = 'closed'
463 elif ctx.node() not in heads:
463 elif ctx.node() not in heads:
464 status = 'inactive'
464 status = 'inactive'
465 else:
465 else:
466 status = 'open'
466 status = 'open'
467 yield {'parity': parity.next(),
467 yield {'parity': parity.next(),
468 'branch': ctx.branch(),
468 'branch': ctx.branch(),
469 'status': status,
469 'status': status,
470 'node': ctx.hex(),
470 'node': ctx.hex(),
471 'date': ctx.date()}
471 'date': ctx.date()}
472
472
473 return tmpl('branches', node=hex(web.repo.changelog.tip()),
473 return tmpl('branches', node=hex(web.repo.changelog.tip()),
474 entries=lambda **x: entries(0, **x),
474 entries=lambda **x: entries(0, **x),
475 latestentry=lambda **x: entries(1, **x))
475 latestentry=lambda **x: entries(1, **x))
476
476
477 def summary(web, req, tmpl):
477 def summary(web, req, tmpl):
478 i = reversed(web.repo.tagslist())
478 i = reversed(web.repo.tagslist())
479
479
480 def tagentries(**map):
480 def tagentries(**map):
481 parity = paritygen(web.stripecount)
481 parity = paritygen(web.stripecount)
482 count = 0
482 count = 0
483 for k, n in i:
483 for k, n in i:
484 if k == "tip": # skip tip
484 if k == "tip": # skip tip
485 continue
485 continue
486
486
487 count += 1
487 count += 1
488 if count > 10: # limit to 10 tags
488 if count > 10: # limit to 10 tags
489 break
489 break
490
490
491 yield tmpl("tagentry",
491 yield tmpl("tagentry",
492 parity=parity.next(),
492 parity=parity.next(),
493 tag=k,
493 tag=k,
494 node=hex(n),
494 node=hex(n),
495 date=web.repo[n].date())
495 date=web.repo[n].date())
496
496
497 def bookmarks(**map):
497 def bookmarks(**map):
498 parity = paritygen(web.stripecount)
498 parity = paritygen(web.stripecount)
499 b = web.repo._bookmarks.items()
499 b = web.repo._bookmarks.items()
500 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
500 for k, n in sorted(b)[:10]: # limit to 10 bookmarks
501 yield {'parity': parity.next(),
501 yield {'parity': parity.next(),
502 'bookmark': k,
502 'bookmark': k,
503 'date': web.repo[n].date(),
503 'date': web.repo[n].date(),
504 'node': hex(n)}
504 'node': hex(n)}
505
505
506 def branches(**map):
506 def branches(**map):
507 parity = paritygen(web.stripecount)
507 parity = paritygen(web.stripecount)
508
508
509 b = web.repo.branchtags()
509 b = web.repo.branchtags()
510 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
510 l = [(-web.repo.changelog.rev(n), n, t) for t, n in b.iteritems()]
511 for r, n, t in sorted(l):
511 for r, n, t in sorted(l):
512 yield {'parity': parity.next(),
512 yield {'parity': parity.next(),
513 'branch': t,
513 'branch': t,
514 'node': hex(n),
514 'node': hex(n),
515 'date': web.repo[n].date()}
515 'date': web.repo[n].date()}
516
516
517 def changelist(**map):
517 def changelist(**map):
518 parity = paritygen(web.stripecount, offset=start - end)
518 parity = paritygen(web.stripecount, offset=start - end)
519 l = [] # build a list in forward order for efficiency
519 l = [] # build a list in forward order for efficiency
520 for i in xrange(start, end):
520 for i in xrange(start, end):
521 ctx = web.repo[i]
521 ctx = web.repo[i]
522 n = ctx.node()
522 n = ctx.node()
523 hn = hex(n)
523 hn = hex(n)
524
524
525 l.append(tmpl(
525 l.append(tmpl(
526 'shortlogentry',
526 'shortlogentry',
527 parity=parity.next(),
527 parity=parity.next(),
528 author=ctx.user(),
528 author=ctx.user(),
529 desc=ctx.description(),
529 desc=ctx.description(),
530 date=ctx.date(),
530 date=ctx.date(),
531 rev=i,
531 rev=i,
532 node=hn,
532 node=hn,
533 tags=webutil.nodetagsdict(web.repo, n),
533 tags=webutil.nodetagsdict(web.repo, n),
534 bookmarks=webutil.nodebookmarksdict(web.repo, n),
534 bookmarks=webutil.nodebookmarksdict(web.repo, n),
535 inbranch=webutil.nodeinbranch(web.repo, ctx),
535 inbranch=webutil.nodeinbranch(web.repo, ctx),
536 branches=webutil.nodebranchdict(web.repo, ctx)))
536 branches=webutil.nodebranchdict(web.repo, ctx)))
537
537
538 l.reverse()
538 l.reverse()
539 yield l
539 yield l
540
540
541 tip = web.repo['tip']
541 tip = web.repo['tip']
542 count = len(web.repo)
542 count = len(web.repo)
543 start = max(0, count - web.maxchanges)
543 start = max(0, count - web.maxchanges)
544 end = min(count, start + web.maxchanges)
544 end = min(count, start + web.maxchanges)
545
545
546 return tmpl("summary",
546 return tmpl("summary",
547 desc=web.config("web", "description", "unknown"),
547 desc=web.config("web", "description", "unknown"),
548 owner=get_contact(web.config) or "unknown",
548 owner=get_contact(web.config) or "unknown",
549 lastchange=tip.date(),
549 lastchange=tip.date(),
550 tags=tagentries,
550 tags=tagentries,
551 bookmarks=bookmarks,
551 bookmarks=bookmarks,
552 branches=branches,
552 branches=branches,
553 shortlog=changelist,
553 shortlog=changelist,
554 node=tip.hex(),
554 node=tip.hex(),
555 archives=web.archivelist("tip"))
555 archives=web.archivelist("tip"))
556
556
557 def filediff(web, req, tmpl):
557 def filediff(web, req, tmpl):
558 fctx, ctx = None, None
558 fctx, ctx = None, None
559 try:
559 try:
560 fctx = webutil.filectx(web.repo, req)
560 fctx = webutil.filectx(web.repo, req)
561 except LookupError:
561 except LookupError:
562 ctx = webutil.changectx(web.repo, req)
562 ctx = webutil.changectx(web.repo, req)
563 path = webutil.cleanpath(web.repo, req.form['file'][0])
563 path = webutil.cleanpath(web.repo, req.form['file'][0])
564 if path not in ctx.files():
564 if path not in ctx.files():
565 raise
565 raise
566
566
567 if fctx is not None:
567 if fctx is not None:
568 n = fctx.node()
568 n = fctx.node()
569 path = fctx.path()
569 path = fctx.path()
570 ctx = fctx.changectx()
570 ctx = fctx.changectx()
571 else:
571 else:
572 n = ctx.node()
572 n = ctx.node()
573 # path already defined in except clause
573 # path already defined in except clause
574
574
575 parity = paritygen(web.stripecount)
575 parity = paritygen(web.stripecount)
576 style = web.config('web', 'style', 'paper')
576 style = web.config('web', 'style', 'paper')
577 if 'style' in req.form:
577 if 'style' in req.form:
578 style = req.form['style'][0]
578 style = req.form['style'][0]
579
579
580 diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style)
580 diffs = webutil.diffs(web.repo, tmpl, ctx, None, [path], parity, style)
581 rename = fctx and webutil.renamelink(fctx) or []
581 rename = fctx and webutil.renamelink(fctx) or []
582 ctx = fctx and fctx or ctx
582 ctx = fctx and fctx or ctx
583 return tmpl("filediff",
583 return tmpl("filediff",
584 file=path,
584 file=path,
585 node=hex(n),
585 node=hex(n),
586 rev=ctx.rev(),
586 rev=ctx.rev(),
587 date=ctx.date(),
587 date=ctx.date(),
588 desc=ctx.description(),
588 desc=ctx.description(),
589 author=ctx.user(),
589 author=ctx.user(),
590 rename=rename,
590 rename=rename,
591 branch=webutil.nodebranchnodefault(ctx),
591 branch=webutil.nodebranchnodefault(ctx),
592 parent=webutil.parents(ctx),
592 parent=webutil.parents(ctx),
593 child=webutil.children(ctx),
593 child=webutil.children(ctx),
594 diff=diffs)
594 diff=diffs)
595
595
596 diff = filediff
596 diff = filediff
597
597
598 def comparison(web, req, tmpl):
598 def comparison(web, req, tmpl):
599 ctx = webutil.changectx(web.repo, req)
599 ctx = webutil.changectx(web.repo, req)
600 if 'file' not in req.form:
600 if 'file' not in req.form:
601 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
601 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given')
602 path = webutil.cleanpath(web.repo, req.form['file'][0])
602 path = webutil.cleanpath(web.repo, req.form['file'][0])
603 rename = path in ctx and webutil.renamelink(ctx[path]) or []
603 rename = path in ctx and webutil.renamelink(ctx[path]) or []
604
604
605 parsecontext = lambda v: v == 'full' and -1 or int(v)
605 parsecontext = lambda v: v == 'full' and -1 or int(v)
606 if 'context' in req.form:
606 if 'context' in req.form:
607 context = parsecontext(req.form['context'][0])
607 context = parsecontext(req.form['context'][0])
608 else:
608 else:
609 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
609 context = parsecontext(web.config('web', 'comparisoncontext', '5'))
610
610
611 def filelines(f):
611 def filelines(f):
612 if binary(f.data()):
612 if binary(f.data()):
613 mt = mimetypes.guess_type(f.path())[0]
613 mt = mimetypes.guess_type(f.path())[0]
614 if not mt:
614 if not mt:
615 mt = 'application/octet-stream'
615 mt = 'application/octet-stream'
616 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
616 return [_('(binary file %s, hash: %s)') % (mt, hex(f.filenode()))]
617 return f.data().splitlines()
617 return f.data().splitlines()
618
618
619 if path in ctx:
619 if path in ctx:
620 fctx = ctx[path]
620 fctx = ctx[path]
621 rightrev = fctx.filerev()
621 rightrev = fctx.filerev()
622 rightnode = fctx.filenode()
622 rightnode = fctx.filenode()
623 rightlines = filelines(fctx)
623 rightlines = filelines(fctx)
624 parents = fctx.parents()
624 parents = fctx.parents()
625 if not parents:
625 if not parents:
626 leftrev = -1
626 leftrev = -1
627 leftnode = nullid
627 leftnode = nullid
628 leftlines = ()
628 leftlines = ()
629 else:
629 else:
630 pfctx = parents[0]
630 pfctx = parents[0]
631 leftrev = pfctx.filerev()
631 leftrev = pfctx.filerev()
632 leftnode = pfctx.filenode()
632 leftnode = pfctx.filenode()
633 leftlines = filelines(pfctx)
633 leftlines = filelines(pfctx)
634 else:
634 else:
635 rightrev = -1
635 rightrev = -1
636 rightnode = nullid
636 rightnode = nullid
637 rightlines = ()
637 rightlines = ()
638 fctx = ctx.parents()[0][path]
638 fctx = ctx.parents()[0][path]
639 leftrev = fctx.filerev()
639 leftrev = fctx.filerev()
640 leftnode = fctx.filenode()
640 leftnode = fctx.filenode()
641 leftlines = filelines(fctx)
641 leftlines = filelines(fctx)
642
642
643 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
643 comparison = webutil.compare(tmpl, context, leftlines, rightlines)
644 return tmpl('filecomparison',
644 return tmpl('filecomparison',
645 file=path,
645 file=path,
646 node=hex(ctx.node()),
646 node=hex(ctx.node()),
647 rev=ctx.rev(),
647 rev=ctx.rev(),
648 date=ctx.date(),
648 date=ctx.date(),
649 desc=ctx.description(),
649 desc=ctx.description(),
650 author=ctx.user(),
650 author=ctx.user(),
651 rename=rename,
651 rename=rename,
652 branch=webutil.nodebranchnodefault(ctx),
652 branch=webutil.nodebranchnodefault(ctx),
653 parent=webutil.parents(fctx),
653 parent=webutil.parents(fctx),
654 child=webutil.children(fctx),
654 child=webutil.children(fctx),
655 leftrev=leftrev,
655 leftrev=leftrev,
656 leftnode=hex(leftnode),
656 leftnode=hex(leftnode),
657 rightrev=rightrev,
657 rightrev=rightrev,
658 rightnode=hex(rightnode),
658 rightnode=hex(rightnode),
659 comparison=comparison)
659 comparison=comparison)
660
660
661 def annotate(web, req, tmpl):
661 def annotate(web, req, tmpl):
662 fctx = webutil.filectx(web.repo, req)
662 fctx = webutil.filectx(web.repo, req)
663 f = fctx.path()
663 f = fctx.path()
664 parity = paritygen(web.stripecount)
664 parity = paritygen(web.stripecount)
665 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
665 diffopts = patch.diffopts(web.repo.ui, untrusted=True, section='annotate')
666
666
667 def annotate(**map):
667 def annotate(**map):
668 last = None
668 last = None
669 if binary(fctx.data()):
669 if binary(fctx.data()):
670 mt = (mimetypes.guess_type(fctx.path())[0]
670 mt = (mimetypes.guess_type(fctx.path())[0]
671 or 'application/octet-stream')
671 or 'application/octet-stream')
672 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
672 lines = enumerate([((fctx.filectx(fctx.filerev()), 1),
673 '(binary:%s)' % mt)])
673 '(binary:%s)' % mt)])
674 else:
674 else:
675 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
675 lines = enumerate(fctx.annotate(follow=True, linenumber=True,
676 diffopts=diffopts))
676 diffopts=diffopts))
677 for lineno, ((f, targetline), l) in lines:
677 for lineno, ((f, targetline), l) in lines:
678 fnode = f.filenode()
678 fnode = f.filenode()
679
679
680 if last != fnode:
680 if last != fnode:
681 last = fnode
681 last = fnode
682
682
683 yield {"parity": parity.next(),
683 yield {"parity": parity.next(),
684 "node": f.hex(),
684 "node": f.hex(),
685 "rev": f.rev(),
685 "rev": f.rev(),
686 "author": f.user(),
686 "author": f.user(),
687 "desc": f.description(),
687 "desc": f.description(),
688 "file": f.path(),
688 "file": f.path(),
689 "targetline": targetline,
689 "targetline": targetline,
690 "line": l,
690 "line": l,
691 "lineid": "l%d" % (lineno + 1),
691 "lineid": "l%d" % (lineno + 1),
692 "linenumber": "% 6d" % (lineno + 1),
692 "linenumber": "% 6d" % (lineno + 1),
693 "revdate": f.date()}
693 "revdate": f.date()}
694
694
695 return tmpl("fileannotate",
695 return tmpl("fileannotate",
696 file=f,
696 file=f,
697 annotate=annotate,
697 annotate=annotate,
698 path=webutil.up(f),
698 path=webutil.up(f),
699 rev=fctx.rev(),
699 rev=fctx.rev(),
700 node=fctx.hex(),
700 node=fctx.hex(),
701 author=fctx.user(),
701 author=fctx.user(),
702 date=fctx.date(),
702 date=fctx.date(),
703 desc=fctx.description(),
703 desc=fctx.description(),
704 rename=webutil.renamelink(fctx),
704 rename=webutil.renamelink(fctx),
705 branch=webutil.nodebranchnodefault(fctx),
705 branch=webutil.nodebranchnodefault(fctx),
706 parent=webutil.parents(fctx),
706 parent=webutil.parents(fctx),
707 child=webutil.children(fctx),
707 child=webutil.children(fctx),
708 permissions=fctx.manifest().flags(f))
708 permissions=fctx.manifest().flags(f))
709
709
710 def filelog(web, req, tmpl):
710 def filelog(web, req, tmpl):
711
711
712 try:
712 try:
713 fctx = webutil.filectx(web.repo, req)
713 fctx = webutil.filectx(web.repo, req)
714 f = fctx.path()
714 f = fctx.path()
715 fl = fctx.filelog()
715 fl = fctx.filelog()
716 except error.LookupError:
716 except error.LookupError:
717 f = webutil.cleanpath(web.repo, req.form['file'][0])
717 f = webutil.cleanpath(web.repo, req.form['file'][0])
718 fl = web.repo.file(f)
718 fl = web.repo.file(f)
719 numrevs = len(fl)
719 numrevs = len(fl)
720 if not numrevs: # file doesn't exist at all
720 if not numrevs: # file doesn't exist at all
721 raise
721 raise
722 rev = webutil.changectx(web.repo, req).rev()
722 rev = webutil.changectx(web.repo, req).rev()
723 first = fl.linkrev(0)
723 first = fl.linkrev(0)
724 if rev < first: # current rev is from before file existed
724 if rev < first: # current rev is from before file existed
725 raise
725 raise
726 frev = numrevs - 1
726 frev = numrevs - 1
727 while fl.linkrev(frev) > rev:
727 while fl.linkrev(frev) > rev:
728 frev -= 1
728 frev -= 1
729 fctx = web.repo.filectx(f, fl.linkrev(frev))
729 fctx = web.repo.filectx(f, fl.linkrev(frev))
730
730
731 revcount = web.maxshortchanges
731 revcount = web.maxshortchanges
732 if 'revcount' in req.form:
732 if 'revcount' in req.form:
733 revcount = int(req.form.get('revcount', [revcount])[0])
733 revcount = int(req.form.get('revcount', [revcount])[0])
734 revcount = max(revcount, 1)
734 revcount = max(revcount, 1)
735 tmpl.defaults['sessionvars']['revcount'] = revcount
735 tmpl.defaults['sessionvars']['revcount'] = revcount
736
736
737 lessvars = copy.copy(tmpl.defaults['sessionvars'])
737 lessvars = copy.copy(tmpl.defaults['sessionvars'])
738 lessvars['revcount'] = max(revcount / 2, 1)
738 lessvars['revcount'] = max(revcount / 2, 1)
739 morevars = copy.copy(tmpl.defaults['sessionvars'])
739 morevars = copy.copy(tmpl.defaults['sessionvars'])
740 morevars['revcount'] = revcount * 2
740 morevars['revcount'] = revcount * 2
741
741
742 count = fctx.filerev() + 1
742 count = fctx.filerev() + 1
743 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
743 start = max(0, fctx.filerev() - revcount + 1) # first rev on this page
744 end = min(count, start + revcount) # last rev on this page
744 end = min(count, start + revcount) # last rev on this page
745 parity = paritygen(web.stripecount, offset=start - end)
745 parity = paritygen(web.stripecount, offset=start - end)
746
746
747 def entries(latestonly, **map):
747 def entries(latestonly, **map):
748 l = []
748 l = []
749
749
750 repo = web.repo
750 repo = web.repo
751 revs = repo.changelog.revs(start, end - 1)
751 revs = repo.changelog.revs(start, end - 1)
752 if latestonly:
752 if latestonly:
753 for r in revs:
753 for r in revs:
754 pass
754 pass
755 revs = (r,)
755 revs = (r,)
756 for i in revs:
756 for i in revs:
757 iterfctx = fctx.filectx(i)
757 iterfctx = fctx.filectx(i)
758
758
759 l.append({"parity": parity.next(),
759 l.append({"parity": parity.next(),
760 "filerev": i,
760 "filerev": i,
761 "file": f,
761 "file": f,
762 "node": iterfctx.hex(),
762 "node": iterfctx.hex(),
763 "author": iterfctx.user(),
763 "author": iterfctx.user(),
764 "date": iterfctx.date(),
764 "date": iterfctx.date(),
765 "rename": webutil.renamelink(iterfctx),
765 "rename": webutil.renamelink(iterfctx),
766 "parent": webutil.parents(iterfctx),
766 "parent": webutil.parents(iterfctx),
767 "child": webutil.children(iterfctx),
767 "child": webutil.children(iterfctx),
768 "desc": iterfctx.description(),
768 "desc": iterfctx.description(),
769 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
769 "tags": webutil.nodetagsdict(repo, iterfctx.node()),
770 "bookmarks": webutil.nodebookmarksdict(
770 "bookmarks": webutil.nodebookmarksdict(
771 repo, iterfctx.node()),
771 repo, iterfctx.node()),
772 "branch": webutil.nodebranchnodefault(iterfctx),
772 "branch": webutil.nodebranchnodefault(iterfctx),
773 "inbranch": webutil.nodeinbranch(repo, iterfctx),
773 "inbranch": webutil.nodeinbranch(repo, iterfctx),
774 "branches": webutil.nodebranchdict(repo, iterfctx)})
774 "branches": webutil.nodebranchdict(repo, iterfctx)})
775 for e in reversed(l):
775 for e in reversed(l):
776 yield e
776 yield e
777
777
778 revnav = webutil.filerevnav(web.repo, fctx.path())
778 revnav = webutil.filerevnav(web.repo, fctx.path())
779 nav = revnav.gen(end - 1, revcount, count)
779 nav = revnav.gen(end - 1, revcount, count)
780 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
780 return tmpl("filelog", file=f, node=fctx.hex(), nav=nav,
781 entries=lambda **x: entries(latestonly=False, **x),
781 entries=lambda **x: entries(latestonly=False, **x),
782 latestentry=lambda **x: entries(latestonly=True, **x),
782 latestentry=lambda **x: entries(latestonly=True, **x),
783 revcount=revcount, morevars=morevars, lessvars=lessvars)
783 revcount=revcount, morevars=morevars, lessvars=lessvars)
784
784
785 def archive(web, req, tmpl):
785 def archive(web, req, tmpl):
786 type_ = req.form.get('type', [None])[0]
786 type_ = req.form.get('type', [None])[0]
787 allowed = web.configlist("web", "allow_archive")
787 allowed = web.configlist("web", "allow_archive")
788 key = req.form['node'][0]
788 key = req.form['node'][0]
789
789
790 if type_ not in web.archives:
790 if type_ not in web.archives:
791 msg = 'Unsupported archive type: %s' % type_
791 msg = 'Unsupported archive type: %s' % type_
792 raise ErrorResponse(HTTP_NOT_FOUND, msg)
792 raise ErrorResponse(HTTP_NOT_FOUND, msg)
793
793
794 if not ((type_ in allowed or
794 if not ((type_ in allowed or
795 web.configbool("web", "allow" + type_, False))):
795 web.configbool("web", "allow" + type_, False))):
796 msg = 'Archive type not allowed: %s' % type_
796 msg = 'Archive type not allowed: %s' % type_
797 raise ErrorResponse(HTTP_FORBIDDEN, msg)
797 raise ErrorResponse(HTTP_FORBIDDEN, msg)
798
798
799 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
799 reponame = re.sub(r"\W+", "-", os.path.basename(web.reponame))
800 cnode = web.repo.lookup(key)
800 cnode = web.repo.lookup(key)
801 arch_version = key
801 arch_version = key
802 if cnode == key or key == 'tip':
802 if cnode == key or key == 'tip':
803 arch_version = short(cnode)
803 arch_version = short(cnode)
804 name = "%s-%s" % (reponame, arch_version)
804 name = "%s-%s" % (reponame, arch_version)
805 mimetype, artype, extension, encoding = web.archive_specs[type_]
805 mimetype, artype, extension, encoding = web.archive_specs[type_]
806 headers = [
806 headers = [
807 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
807 ('Content-Disposition', 'attachment; filename=%s%s' % (name, extension))
808 ]
808 ]
809 if encoding:
809 if encoding:
810 headers.append(('Content-Encoding', encoding))
810 headers.append(('Content-Encoding', encoding))
811 req.headers.extend(headers)
811 req.headers.extend(headers)
812 req.respond(HTTP_OK, mimetype)
812 req.respond(HTTP_OK, mimetype)
813
813
814 ctx = webutil.changectx(web.repo, req)
814 ctx = webutil.changectx(web.repo, req)
815 archival.archive(web.repo, req, cnode, artype, prefix=name,
815 archival.archive(web.repo, req, cnode, artype, prefix=name,
816 matchfn=scmutil.match(ctx, []),
816 matchfn=scmutil.match(ctx, []),
817 subrepos=web.configbool("web", "archivesubrepos"))
817 subrepos=web.configbool("web", "archivesubrepos"))
818 return []
818 return []
819
819
820
820
821 def static(web, req, tmpl):
821 def static(web, req, tmpl):
822 fname = req.form['file'][0]
822 fname = req.form['file'][0]
823 # a repo owner may set web.static in .hg/hgrc to get any file
823 # a repo owner may set web.static in .hg/hgrc to get any file
824 # readable by the user running the CGI script
824 # readable by the user running the CGI script
825 static = web.config("web", "static", None, untrusted=False)
825 static = web.config("web", "static", None, untrusted=False)
826 if not static:
826 if not static:
827 tp = web.templatepath or templater.templatepath()
827 tp = web.templatepath or templater.templatepath()
828 if isinstance(tp, str):
828 if isinstance(tp, str):
829 tp = [tp]
829 tp = [tp]
830 static = [os.path.join(p, 'static') for p in tp]
830 static = [os.path.join(p, 'static') for p in tp]
831 return [staticfile(static, fname, req)]
831 return [staticfile(static, fname, req)]
832
832
833 def graph(web, req, tmpl):
833 def graph(web, req, tmpl):
834
834
835 ctx = webutil.changectx(web.repo, req)
835 ctx = webutil.changectx(web.repo, req)
836 rev = ctx.rev()
836 rev = ctx.rev()
837
837
838 bg_height = 39
838 bg_height = 39
839 revcount = web.maxshortchanges
839 revcount = web.maxshortchanges
840 if 'revcount' in req.form:
840 if 'revcount' in req.form:
841 revcount = int(req.form.get('revcount', [revcount])[0])
841 revcount = int(req.form.get('revcount', [revcount])[0])
842 revcount = max(revcount, 1)
842 revcount = max(revcount, 1)
843 tmpl.defaults['sessionvars']['revcount'] = revcount
843 tmpl.defaults['sessionvars']['revcount'] = revcount
844
844
845 lessvars = copy.copy(tmpl.defaults['sessionvars'])
845 lessvars = copy.copy(tmpl.defaults['sessionvars'])
846 lessvars['revcount'] = max(revcount / 2, 1)
846 lessvars['revcount'] = max(revcount / 2, 1)
847 morevars = copy.copy(tmpl.defaults['sessionvars'])
847 morevars = copy.copy(tmpl.defaults['sessionvars'])
848 morevars['revcount'] = revcount * 2
848 morevars['revcount'] = revcount * 2
849
849
850 count = len(web.repo)
850 count = len(web.repo)
851 pos = rev
851 pos = rev
852 start = max(0, pos - revcount + 1)
852 start = max(0, pos - revcount + 1)
853 end = min(count, start + revcount)
853 end = min(count, start + revcount)
854 pos = end - 1
854 pos = end - 1
855
855
856 uprev = min(max(0, count - 1), rev + revcount)
856 uprev = min(max(0, count - 1), rev + revcount)
857 downrev = max(0, rev - revcount)
857 downrev = max(0, rev - revcount)
858 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
858 changenav = webutil.revnav(web.repo).gen(pos, revcount, count)
859
859
860 dag = graphmod.dagwalker(web.repo, range(start, end)[::-1])
860 tree = []
861 tree = list(graphmod.colored(dag, web.repo))
861 if start < end:
862 revs = list(web.repo.changelog.revs(end - 1, start))
863 dag = graphmod.dagwalker(web.repo, revs)
864 tree = list(graphmod.colored(dag, web.repo))
862
865
863 def getcolumns(tree):
866 def getcolumns(tree):
864 cols = 0
867 cols = 0
865 for (id, type, ctx, vtx, edges) in tree:
868 for (id, type, ctx, vtx, edges) in tree:
866 if type != graphmod.CHANGESET:
869 if type != graphmod.CHANGESET:
867 continue
870 continue
868 cols = max(cols, max([edge[0] for edge in edges] or [0]),
871 cols = max(cols, max([edge[0] for edge in edges] or [0]),
869 max([edge[1] for edge in edges] or [0]))
872 max([edge[1] for edge in edges] or [0]))
870 return cols
873 return cols
871
874
872 def graphdata(usetuples, **map):
875 def graphdata(usetuples, **map):
873 data = []
876 data = []
874
877
875 row = 0
878 row = 0
876 for (id, type, ctx, vtx, edges) in tree:
879 for (id, type, ctx, vtx, edges) in tree:
877 if type != graphmod.CHANGESET:
880 if type != graphmod.CHANGESET:
878 continue
881 continue
879 node = str(ctx)
882 node = str(ctx)
880 age = templatefilters.age(ctx.date())
883 age = templatefilters.age(ctx.date())
881 desc = templatefilters.firstline(ctx.description())
884 desc = templatefilters.firstline(ctx.description())
882 desc = cgi.escape(templatefilters.nonempty(desc))
885 desc = cgi.escape(templatefilters.nonempty(desc))
883 user = cgi.escape(templatefilters.person(ctx.user()))
886 user = cgi.escape(templatefilters.person(ctx.user()))
884 branch = ctx.branch()
887 branch = ctx.branch()
885 try:
888 try:
886 branchnode = web.repo.branchtip(branch)
889 branchnode = web.repo.branchtip(branch)
887 except error.RepoLookupError:
890 except error.RepoLookupError:
888 branchnode = None
891 branchnode = None
889 branch = branch, branchnode == ctx.node()
892 branch = branch, branchnode == ctx.node()
890
893
891 if usetuples:
894 if usetuples:
892 data.append((node, vtx, edges, desc, user, age, branch,
895 data.append((node, vtx, edges, desc, user, age, branch,
893 ctx.tags(), ctx.bookmarks()))
896 ctx.tags(), ctx.bookmarks()))
894 else:
897 else:
895 edgedata = [dict(col=edge[0], nextcol=edge[1],
898 edgedata = [dict(col=edge[0], nextcol=edge[1],
896 color=(edge[2] - 1) % 6 + 1,
899 color=(edge[2] - 1) % 6 + 1,
897 width=edge[3], bcolor=edge[4])
900 width=edge[3], bcolor=edge[4])
898 for edge in edges]
901 for edge in edges]
899
902
900 data.append(
903 data.append(
901 dict(node=node,
904 dict(node=node,
902 col=vtx[0],
905 col=vtx[0],
903 color=(vtx[1] - 1) % 6 + 1,
906 color=(vtx[1] - 1) % 6 + 1,
904 edges=edgedata,
907 edges=edgedata,
905 row=row,
908 row=row,
906 nextrow=row + 1,
909 nextrow=row + 1,
907 desc=desc,
910 desc=desc,
908 user=user,
911 user=user,
909 age=age,
912 age=age,
910 bookmarks=webutil.nodebookmarksdict(
913 bookmarks=webutil.nodebookmarksdict(
911 web.repo, ctx.node()),
914 web.repo, ctx.node()),
912 branches=webutil.nodebranchdict(web.repo, ctx),
915 branches=webutil.nodebranchdict(web.repo, ctx),
913 inbranch=webutil.nodeinbranch(web.repo, ctx),
916 inbranch=webutil.nodeinbranch(web.repo, ctx),
914 tags=webutil.nodetagsdict(web.repo, ctx.node())))
917 tags=webutil.nodetagsdict(web.repo, ctx.node())))
915
918
916 row += 1
919 row += 1
917
920
918 return data
921 return data
919
922
920 cols = getcolumns(tree)
923 cols = getcolumns(tree)
921 rows = len(tree)
924 rows = len(tree)
922 canvasheight = (rows + 1) * bg_height - 27
925 canvasheight = (rows + 1) * bg_height - 27
923
926
924 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
927 return tmpl('graph', rev=rev, revcount=revcount, uprev=uprev,
925 lessvars=lessvars, morevars=morevars, downrev=downrev,
928 lessvars=lessvars, morevars=morevars, downrev=downrev,
926 cols=cols, rows=rows,
929 cols=cols, rows=rows,
927 canvaswidth=(cols + 1) * bg_height,
930 canvaswidth=(cols + 1) * bg_height,
928 truecanvasheight=rows * bg_height,
931 truecanvasheight=rows * bg_height,
929 canvasheight=canvasheight, bg_height=bg_height,
932 canvasheight=canvasheight, bg_height=bg_height,
930 jsdata=lambda **x: graphdata(True, **x),
933 jsdata=lambda **x: graphdata(True, **x),
931 nodes=lambda **x: graphdata(False, **x),
934 nodes=lambda **x: graphdata(False, **x),
932 node=ctx.hex(), changenav=changenav)
935 node=ctx.hex(), changenav=changenav)
933
936
934 def _getdoc(e):
937 def _getdoc(e):
935 doc = e[0].__doc__
938 doc = e[0].__doc__
936 if doc:
939 if doc:
937 doc = _(doc).split('\n')[0]
940 doc = _(doc).split('\n')[0]
938 else:
941 else:
939 doc = _('(no help text available)')
942 doc = _('(no help text available)')
940 return doc
943 return doc
941
944
942 def help(web, req, tmpl):
945 def help(web, req, tmpl):
943 from mercurial import commands # avoid cycle
946 from mercurial import commands # avoid cycle
944
947
945 topicname = req.form.get('node', [None])[0]
948 topicname = req.form.get('node', [None])[0]
946 if not topicname:
949 if not topicname:
947 def topics(**map):
950 def topics(**map):
948 for entries, summary, _ in helpmod.helptable:
951 for entries, summary, _ in helpmod.helptable:
949 yield {'topic': entries[0], 'summary': summary}
952 yield {'topic': entries[0], 'summary': summary}
950
953
951 early, other = [], []
954 early, other = [], []
952 primary = lambda s: s.split('|')[0]
955 primary = lambda s: s.split('|')[0]
953 for c, e in commands.table.iteritems():
956 for c, e in commands.table.iteritems():
954 doc = _getdoc(e)
957 doc = _getdoc(e)
955 if 'DEPRECATED' in doc or c.startswith('debug'):
958 if 'DEPRECATED' in doc or c.startswith('debug'):
956 continue
959 continue
957 cmd = primary(c)
960 cmd = primary(c)
958 if cmd.startswith('^'):
961 if cmd.startswith('^'):
959 early.append((cmd[1:], doc))
962 early.append((cmd[1:], doc))
960 else:
963 else:
961 other.append((cmd, doc))
964 other.append((cmd, doc))
962
965
963 early.sort()
966 early.sort()
964 other.sort()
967 other.sort()
965
968
966 def earlycommands(**map):
969 def earlycommands(**map):
967 for c, doc in early:
970 for c, doc in early:
968 yield {'topic': c, 'summary': doc}
971 yield {'topic': c, 'summary': doc}
969
972
970 def othercommands(**map):
973 def othercommands(**map):
971 for c, doc in other:
974 for c, doc in other:
972 yield {'topic': c, 'summary': doc}
975 yield {'topic': c, 'summary': doc}
973
976
974 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
977 return tmpl('helptopics', topics=topics, earlycommands=earlycommands,
975 othercommands=othercommands, title='Index')
978 othercommands=othercommands, title='Index')
976
979
977 u = webutil.wsgiui()
980 u = webutil.wsgiui()
978 u.pushbuffer()
981 u.pushbuffer()
979 u.verbose = True
982 u.verbose = True
980 try:
983 try:
981 commands.help_(u, topicname)
984 commands.help_(u, topicname)
982 except error.UnknownCommand:
985 except error.UnknownCommand:
983 raise ErrorResponse(HTTP_NOT_FOUND)
986 raise ErrorResponse(HTTP_NOT_FOUND)
984 doc = u.popbuffer()
987 doc = u.popbuffer()
985 return tmpl('help', topic=topicname, doc=doc)
988 return tmpl('help', topic=topicname, doc=doc)
@@ -1,710 +1,710 b''
1 $ cat >> $HGRCPATH << EOF
1 $ cat >> $HGRCPATH << EOF
2 > [extensions]
2 > [extensions]
3 > graphlog=
3 > graphlog=
4 > [phases]
4 > [phases]
5 > # public changeset are not obsolete
5 > # public changeset are not obsolete
6 > publish=false
6 > publish=false
7 > EOF
7 > EOF
8 $ mkcommit() {
8 $ mkcommit() {
9 > echo "$1" > "$1"
9 > echo "$1" > "$1"
10 > hg add "$1"
10 > hg add "$1"
11 > hg ci -m "add $1"
11 > hg ci -m "add $1"
12 > }
12 > }
13 $ getid() {
13 $ getid() {
14 > hg id --debug --hidden -ir "desc('$1')"
14 > hg id --debug --hidden -ir "desc('$1')"
15 > }
15 > }
16
16
17 $ cat > debugkeys.py <<EOF
17 $ cat > debugkeys.py <<EOF
18 > def reposetup(ui, repo):
18 > def reposetup(ui, repo):
19 > class debugkeysrepo(repo.__class__):
19 > class debugkeysrepo(repo.__class__):
20 > def listkeys(self, namespace):
20 > def listkeys(self, namespace):
21 > ui.write('listkeys %s\n' % (namespace,))
21 > ui.write('listkeys %s\n' % (namespace,))
22 > return super(debugkeysrepo, self).listkeys(namespace)
22 > return super(debugkeysrepo, self).listkeys(namespace)
23 >
23 >
24 > if repo.local():
24 > if repo.local():
25 > repo.__class__ = debugkeysrepo
25 > repo.__class__ = debugkeysrepo
26 > EOF
26 > EOF
27
27
28 $ hg init tmpa
28 $ hg init tmpa
29 $ cd tmpa
29 $ cd tmpa
30 $ mkcommit kill_me
30 $ mkcommit kill_me
31
31
32 Checking that the feature is properly disabled
32 Checking that the feature is properly disabled
33
33
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
34 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
35 abort: obsolete feature is not enabled on this repo
35 abort: obsolete feature is not enabled on this repo
36 [255]
36 [255]
37
37
38 Enabling it
38 Enabling it
39
39
40 $ cat > ../obs.py << EOF
40 $ cat > ../obs.py << EOF
41 > import mercurial.obsolete
41 > import mercurial.obsolete
42 > mercurial.obsolete._enabled = True
42 > mercurial.obsolete._enabled = True
43 > EOF
43 > EOF
44 $ echo '[extensions]' >> $HGRCPATH
44 $ echo '[extensions]' >> $HGRCPATH
45 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
45 $ echo "obs=${TESTTMP}/obs.py" >> $HGRCPATH
46
46
47 Killing a single changeset without replacement
47 Killing a single changeset without replacement
48
48
49 $ hg debugobsolete 0
49 $ hg debugobsolete 0
50 abort: changeset references must be full hexadecimal node identifiers
50 abort: changeset references must be full hexadecimal node identifiers
51 [255]
51 [255]
52 $ hg debugobsolete '00'
52 $ hg debugobsolete '00'
53 abort: changeset references must be full hexadecimal node identifiers
53 abort: changeset references must be full hexadecimal node identifiers
54 [255]
54 [255]
55 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
55 $ hg debugobsolete -d '0 0' `getid kill_me` -u babar
56 $ hg debugobsolete
56 $ hg debugobsolete
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'}
57 97b7c2d76b1845ed3eb988cd612611e72406cef0 0 {'date': '0 0', 'user': 'babar'}
58 $ cd ..
58 $ cd ..
59
59
60 Killing a single changeset with replacement
60 Killing a single changeset with replacement
61
61
62 $ hg init tmpb
62 $ hg init tmpb
63 $ cd tmpb
63 $ cd tmpb
64 $ mkcommit a
64 $ mkcommit a
65 $ mkcommit b
65 $ mkcommit b
66 $ mkcommit original_c
66 $ mkcommit original_c
67 $ hg up "desc('b')"
67 $ hg up "desc('b')"
68 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
68 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
69 $ mkcommit new_c
69 $ mkcommit new_c
70 created new head
70 created new head
71 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
71 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
72 $ hg debugobsolete --flag 12 `getid original_c` `getid new_c` -d '56 12'
72 $ hg debugobsolete --flag 12 `getid original_c` `getid new_c` -d '56 12'
73 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
73 $ hg log -r 'hidden()' --template '{rev}:{node|short} {desc}\n' --hidden
74 2:245bde4270cd add original_c
74 2:245bde4270cd add original_c
75 $ hg debugobsolete
75 $ hg debugobsolete
76 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
76 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
77
77
78 do it again (it read the obsstore before adding new changeset)
78 do it again (it read the obsstore before adding new changeset)
79
79
80 $ hg up '.^'
80 $ hg up '.^'
81 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
81 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
82 $ mkcommit new_2_c
82 $ mkcommit new_2_c
83 created new head
83 created new head
84 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
84 $ hg debugobsolete -d '1337 0' `getid new_c` `getid new_2_c`
85 $ hg debugobsolete
85 $ hg debugobsolete
86 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
86 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
87 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
87 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
88
88
89 Register two markers with a missing node
89 Register two markers with a missing node
90
90
91 $ hg up '.^'
91 $ hg up '.^'
92 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
92 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
93 $ mkcommit new_3_c
93 $ mkcommit new_3_c
94 created new head
94 created new head
95 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
95 $ hg debugobsolete -d '1338 0' `getid new_2_c` 1337133713371337133713371337133713371337
96 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
96 $ hg debugobsolete -d '1339 0' 1337133713371337133713371337133713371337 `getid new_3_c`
97 $ hg debugobsolete
97 $ hg debugobsolete
98 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
98 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
99 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
99 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
100 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
100 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
101 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
101 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
102
102
103 Refuse pathological nullid successors
103 Refuse pathological nullid successors
104 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
104 $ hg debugobsolete -d '9001 0' 1337133713371337133713371337133713371337 0000000000000000000000000000000000000000
105 transaction abort!
105 transaction abort!
106 rollback completed
106 rollback completed
107 abort: bad obsolescence marker detected: invalid successors nullid
107 abort: bad obsolescence marker detected: invalid successors nullid
108 [255]
108 [255]
109
109
110 Check that graphlog detect that a changeset is obsolete:
110 Check that graphlog detect that a changeset is obsolete:
111
111
112 $ hg glog
112 $ hg glog
113 @ changeset: 5:5601fb93a350
113 @ changeset: 5:5601fb93a350
114 | tag: tip
114 | tag: tip
115 | parent: 1:7c3bad9141dc
115 | parent: 1:7c3bad9141dc
116 | user: test
116 | user: test
117 | date: Thu Jan 01 00:00:00 1970 +0000
117 | date: Thu Jan 01 00:00:00 1970 +0000
118 | summary: add new_3_c
118 | summary: add new_3_c
119 |
119 |
120 o changeset: 1:7c3bad9141dc
120 o changeset: 1:7c3bad9141dc
121 | user: test
121 | user: test
122 | date: Thu Jan 01 00:00:00 1970 +0000
122 | date: Thu Jan 01 00:00:00 1970 +0000
123 | summary: add b
123 | summary: add b
124 |
124 |
125 o changeset: 0:1f0dee641bb7
125 o changeset: 0:1f0dee641bb7
126 user: test
126 user: test
127 date: Thu Jan 01 00:00:00 1970 +0000
127 date: Thu Jan 01 00:00:00 1970 +0000
128 summary: add a
128 summary: add a
129
129
130
130
131 check that heads does not report them
131 check that heads does not report them
132
132
133 $ hg heads
133 $ hg heads
134 changeset: 5:5601fb93a350
134 changeset: 5:5601fb93a350
135 tag: tip
135 tag: tip
136 parent: 1:7c3bad9141dc
136 parent: 1:7c3bad9141dc
137 user: test
137 user: test
138 date: Thu Jan 01 00:00:00 1970 +0000
138 date: Thu Jan 01 00:00:00 1970 +0000
139 summary: add new_3_c
139 summary: add new_3_c
140
140
141 $ hg heads --hidden
141 $ hg heads --hidden
142 changeset: 5:5601fb93a350
142 changeset: 5:5601fb93a350
143 tag: tip
143 tag: tip
144 parent: 1:7c3bad9141dc
144 parent: 1:7c3bad9141dc
145 user: test
145 user: test
146 date: Thu Jan 01 00:00:00 1970 +0000
146 date: Thu Jan 01 00:00:00 1970 +0000
147 summary: add new_3_c
147 summary: add new_3_c
148
148
149 changeset: 4:ca819180edb9
149 changeset: 4:ca819180edb9
150 parent: 1:7c3bad9141dc
150 parent: 1:7c3bad9141dc
151 user: test
151 user: test
152 date: Thu Jan 01 00:00:00 1970 +0000
152 date: Thu Jan 01 00:00:00 1970 +0000
153 summary: add new_2_c
153 summary: add new_2_c
154
154
155 changeset: 3:cdbce2fbb163
155 changeset: 3:cdbce2fbb163
156 parent: 1:7c3bad9141dc
156 parent: 1:7c3bad9141dc
157 user: test
157 user: test
158 date: Thu Jan 01 00:00:00 1970 +0000
158 date: Thu Jan 01 00:00:00 1970 +0000
159 summary: add new_c
159 summary: add new_c
160
160
161 changeset: 2:245bde4270cd
161 changeset: 2:245bde4270cd
162 user: test
162 user: test
163 date: Thu Jan 01 00:00:00 1970 +0000
163 date: Thu Jan 01 00:00:00 1970 +0000
164 summary: add original_c
164 summary: add original_c
165
165
166
166
167
167
168 check that summary does not report them
168 check that summary does not report them
169
169
170 $ hg init ../sink
170 $ hg init ../sink
171 $ echo '[paths]' >> .hg/hgrc
171 $ echo '[paths]' >> .hg/hgrc
172 $ echo 'default=../sink' >> .hg/hgrc
172 $ echo 'default=../sink' >> .hg/hgrc
173 $ hg summary --remote
173 $ hg summary --remote
174 parent: 5:5601fb93a350 tip
174 parent: 5:5601fb93a350 tip
175 add new_3_c
175 add new_3_c
176 branch: default
176 branch: default
177 commit: (clean)
177 commit: (clean)
178 update: (current)
178 update: (current)
179 remote: 3 outgoing
179 remote: 3 outgoing
180
180
181 $ hg summary --remote --hidden
181 $ hg summary --remote --hidden
182 parent: 5:5601fb93a350 tip
182 parent: 5:5601fb93a350 tip
183 add new_3_c
183 add new_3_c
184 branch: default
184 branch: default
185 commit: (clean)
185 commit: (clean)
186 update: 3 new changesets, 4 branch heads (merge)
186 update: 3 new changesets, 4 branch heads (merge)
187 remote: 3 outgoing
187 remote: 3 outgoing
188
188
189 check that various commands work well with filtering
189 check that various commands work well with filtering
190
190
191 $ hg tip
191 $ hg tip
192 changeset: 5:5601fb93a350
192 changeset: 5:5601fb93a350
193 tag: tip
193 tag: tip
194 parent: 1:7c3bad9141dc
194 parent: 1:7c3bad9141dc
195 user: test
195 user: test
196 date: Thu Jan 01 00:00:00 1970 +0000
196 date: Thu Jan 01 00:00:00 1970 +0000
197 summary: add new_3_c
197 summary: add new_3_c
198
198
199 $ hg log -r 6
199 $ hg log -r 6
200 abort: unknown revision '6'!
200 abort: unknown revision '6'!
201 [255]
201 [255]
202 $ hg log -r 4
202 $ hg log -r 4
203 abort: unknown revision '4'!
203 abort: unknown revision '4'!
204 [255]
204 [255]
205
205
206 Check that public changeset are not accounted as obsolete:
206 Check that public changeset are not accounted as obsolete:
207
207
208 $ hg --hidden phase --public 2
208 $ hg --hidden phase --public 2
209 $ hg --config 'extensions.graphlog=' glog
209 $ hg --config 'extensions.graphlog=' glog
210 @ changeset: 5:5601fb93a350
210 @ changeset: 5:5601fb93a350
211 | tag: tip
211 | tag: tip
212 | parent: 1:7c3bad9141dc
212 | parent: 1:7c3bad9141dc
213 | user: test
213 | user: test
214 | date: Thu Jan 01 00:00:00 1970 +0000
214 | date: Thu Jan 01 00:00:00 1970 +0000
215 | summary: add new_3_c
215 | summary: add new_3_c
216 |
216 |
217 | o changeset: 2:245bde4270cd
217 | o changeset: 2:245bde4270cd
218 |/ user: test
218 |/ user: test
219 | date: Thu Jan 01 00:00:00 1970 +0000
219 | date: Thu Jan 01 00:00:00 1970 +0000
220 | summary: add original_c
220 | summary: add original_c
221 |
221 |
222 o changeset: 1:7c3bad9141dc
222 o changeset: 1:7c3bad9141dc
223 | user: test
223 | user: test
224 | date: Thu Jan 01 00:00:00 1970 +0000
224 | date: Thu Jan 01 00:00:00 1970 +0000
225 | summary: add b
225 | summary: add b
226 |
226 |
227 o changeset: 0:1f0dee641bb7
227 o changeset: 0:1f0dee641bb7
228 user: test
228 user: test
229 date: Thu Jan 01 00:00:00 1970 +0000
229 date: Thu Jan 01 00:00:00 1970 +0000
230 summary: add a
230 summary: add a
231
231
232
232
233 And that bumped changeset are detected
233 And that bumped changeset are detected
234 --------------------------------------
234 --------------------------------------
235
235
236 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
236 If we didn't filtered obsolete changesets out, 3 and 4 would show up too. Also
237 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
237 note that the bumped changeset (5:5601fb93a350) is not a direct successor of
238 the public changeset
238 the public changeset
239
239
240 $ hg log --hidden -r 'bumped()'
240 $ hg log --hidden -r 'bumped()'
241 changeset: 5:5601fb93a350
241 changeset: 5:5601fb93a350
242 tag: tip
242 tag: tip
243 parent: 1:7c3bad9141dc
243 parent: 1:7c3bad9141dc
244 user: test
244 user: test
245 date: Thu Jan 01 00:00:00 1970 +0000
245 date: Thu Jan 01 00:00:00 1970 +0000
246 summary: add new_3_c
246 summary: add new_3_c
247
247
248
248
249 And that we can't push bumped changeset
249 And that we can't push bumped changeset
250
250
251 $ hg push ../tmpa -r 0 --force #(make repo related)
251 $ hg push ../tmpa -r 0 --force #(make repo related)
252 pushing to ../tmpa
252 pushing to ../tmpa
253 searching for changes
253 searching for changes
254 warning: repository is unrelated
254 warning: repository is unrelated
255 adding changesets
255 adding changesets
256 adding manifests
256 adding manifests
257 adding file changes
257 adding file changes
258 added 1 changesets with 1 changes to 1 files (+1 heads)
258 added 1 changesets with 1 changes to 1 files (+1 heads)
259 $ hg push ../tmpa
259 $ hg push ../tmpa
260 pushing to ../tmpa
260 pushing to ../tmpa
261 searching for changes
261 searching for changes
262 abort: push includes bumped changeset: 5601fb93a350!
262 abort: push includes bumped changeset: 5601fb93a350!
263 [255]
263 [255]
264
264
265 Fixing "bumped" situation
265 Fixing "bumped" situation
266 We need to create a clone of 5 and add a special marker with a flag
266 We need to create a clone of 5 and add a special marker with a flag
267
267
268 $ hg up '5^'
268 $ hg up '5^'
269 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
269 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
270 $ hg revert -ar 5
270 $ hg revert -ar 5
271 adding new_3_c
271 adding new_3_c
272 $ hg ci -m 'add n3w_3_c'
272 $ hg ci -m 'add n3w_3_c'
273 created new head
273 created new head
274 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
274 $ hg debugobsolete -d '1338 0' --flags 1 `getid new_3_c` `getid n3w_3_c`
275 $ hg log -r 'bumped()'
275 $ hg log -r 'bumped()'
276 $ hg log -G
276 $ hg log -G
277 @ changeset: 6:6f9641995072
277 @ changeset: 6:6f9641995072
278 | tag: tip
278 | tag: tip
279 | parent: 1:7c3bad9141dc
279 | parent: 1:7c3bad9141dc
280 | user: test
280 | user: test
281 | date: Thu Jan 01 00:00:00 1970 +0000
281 | date: Thu Jan 01 00:00:00 1970 +0000
282 | summary: add n3w_3_c
282 | summary: add n3w_3_c
283 |
283 |
284 | o changeset: 2:245bde4270cd
284 | o changeset: 2:245bde4270cd
285 |/ user: test
285 |/ user: test
286 | date: Thu Jan 01 00:00:00 1970 +0000
286 | date: Thu Jan 01 00:00:00 1970 +0000
287 | summary: add original_c
287 | summary: add original_c
288 |
288 |
289 o changeset: 1:7c3bad9141dc
289 o changeset: 1:7c3bad9141dc
290 | user: test
290 | user: test
291 | date: Thu Jan 01 00:00:00 1970 +0000
291 | date: Thu Jan 01 00:00:00 1970 +0000
292 | summary: add b
292 | summary: add b
293 |
293 |
294 o changeset: 0:1f0dee641bb7
294 o changeset: 0:1f0dee641bb7
295 user: test
295 user: test
296 date: Thu Jan 01 00:00:00 1970 +0000
296 date: Thu Jan 01 00:00:00 1970 +0000
297 summary: add a
297 summary: add a
298
298
299
299
300
300
301
301
302 $ cd ..
302 $ cd ..
303
303
304 Exchange Test
304 Exchange Test
305 ============================
305 ============================
306
306
307 Destination repo does not have any data
307 Destination repo does not have any data
308 ---------------------------------------
308 ---------------------------------------
309
309
310 Try to pull markers
310 Try to pull markers
311 (extinct changeset are excluded but marker are pushed)
311 (extinct changeset are excluded but marker are pushed)
312
312
313 $ hg init tmpc
313 $ hg init tmpc
314 $ cd tmpc
314 $ cd tmpc
315 $ hg pull ../tmpb
315 $ hg pull ../tmpb
316 pulling from ../tmpb
316 pulling from ../tmpb
317 requesting all changes
317 requesting all changes
318 adding changesets
318 adding changesets
319 adding manifests
319 adding manifests
320 adding file changes
320 adding file changes
321 added 4 changesets with 4 changes to 4 files (+1 heads)
321 added 4 changesets with 4 changes to 4 files (+1 heads)
322 (run 'hg heads' to see heads, 'hg merge' to merge)
322 (run 'hg heads' to see heads, 'hg merge' to merge)
323 $ hg debugobsolete
323 $ hg debugobsolete
324 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
324 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
325 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
325 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
326 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
326 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
327 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
327 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
328 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
328 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
329
329
330 Rollback//Transaction support
330 Rollback//Transaction support
331
331
332 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
332 $ hg debugobsolete -d '1340 0' aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
333 $ hg debugobsolete
333 $ hg debugobsolete
334 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
334 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
335 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
335 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
336 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
336 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
337 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
337 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
338 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
338 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
339 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 {'date': '1340 0', 'user': 'test'}
339 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb 0 {'date': '1340 0', 'user': 'test'}
340 $ hg rollback -n
340 $ hg rollback -n
341 repository tip rolled back to revision 3 (undo debugobsolete)
341 repository tip rolled back to revision 3 (undo debugobsolete)
342 $ hg rollback
342 $ hg rollback
343 repository tip rolled back to revision 3 (undo debugobsolete)
343 repository tip rolled back to revision 3 (undo debugobsolete)
344 $ hg debugobsolete
344 $ hg debugobsolete
345 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
345 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
346 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
346 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
347 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
347 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
348 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
348 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
349 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
349 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
350
350
351 $ cd ..
351 $ cd ..
352
352
353 Try to pull markers
353 Try to pull markers
354
354
355 $ hg init tmpd
355 $ hg init tmpd
356 $ hg -R tmpb push tmpd
356 $ hg -R tmpb push tmpd
357 pushing to tmpd
357 pushing to tmpd
358 searching for changes
358 searching for changes
359 adding changesets
359 adding changesets
360 adding manifests
360 adding manifests
361 adding file changes
361 adding file changes
362 added 4 changesets with 4 changes to 4 files (+1 heads)
362 added 4 changesets with 4 changes to 4 files (+1 heads)
363 $ hg -R tmpd debugobsolete
363 $ hg -R tmpd debugobsolete
364 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
364 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
365 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
365 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
366 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
366 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
367 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
367 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
368 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
368 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
369
369
370 Check obsolete keys are exchanged only if source has an obsolete store
370 Check obsolete keys are exchanged only if source has an obsolete store
371
371
372 $ hg init empty
372 $ hg init empty
373 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
373 $ hg --config extensions.debugkeys=debugkeys.py -R empty push tmpd
374 pushing to tmpd
374 pushing to tmpd
375 no changes found
375 no changes found
376 listkeys phases
376 listkeys phases
377 listkeys bookmarks
377 listkeys bookmarks
378 [1]
378 [1]
379
379
380 clone support
380 clone support
381 (markers are copied and extinct changesets are included to allow hardlinks)
381 (markers are copied and extinct changesets are included to allow hardlinks)
382
382
383 $ hg clone tmpb clone-dest
383 $ hg clone tmpb clone-dest
384 updating to branch default
384 updating to branch default
385 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
385 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
386 $ hg -R clone-dest log -G --hidden
386 $ hg -R clone-dest log -G --hidden
387 @ changeset: 6:6f9641995072
387 @ changeset: 6:6f9641995072
388 | tag: tip
388 | tag: tip
389 | parent: 1:7c3bad9141dc
389 | parent: 1:7c3bad9141dc
390 | user: test
390 | user: test
391 | date: Thu Jan 01 00:00:00 1970 +0000
391 | date: Thu Jan 01 00:00:00 1970 +0000
392 | summary: add n3w_3_c
392 | summary: add n3w_3_c
393 |
393 |
394 | x changeset: 5:5601fb93a350
394 | x changeset: 5:5601fb93a350
395 |/ parent: 1:7c3bad9141dc
395 |/ parent: 1:7c3bad9141dc
396 | user: test
396 | user: test
397 | date: Thu Jan 01 00:00:00 1970 +0000
397 | date: Thu Jan 01 00:00:00 1970 +0000
398 | summary: add new_3_c
398 | summary: add new_3_c
399 |
399 |
400 | x changeset: 4:ca819180edb9
400 | x changeset: 4:ca819180edb9
401 |/ parent: 1:7c3bad9141dc
401 |/ parent: 1:7c3bad9141dc
402 | user: test
402 | user: test
403 | date: Thu Jan 01 00:00:00 1970 +0000
403 | date: Thu Jan 01 00:00:00 1970 +0000
404 | summary: add new_2_c
404 | summary: add new_2_c
405 |
405 |
406 | x changeset: 3:cdbce2fbb163
406 | x changeset: 3:cdbce2fbb163
407 |/ parent: 1:7c3bad9141dc
407 |/ parent: 1:7c3bad9141dc
408 | user: test
408 | user: test
409 | date: Thu Jan 01 00:00:00 1970 +0000
409 | date: Thu Jan 01 00:00:00 1970 +0000
410 | summary: add new_c
410 | summary: add new_c
411 |
411 |
412 | o changeset: 2:245bde4270cd
412 | o changeset: 2:245bde4270cd
413 |/ user: test
413 |/ user: test
414 | date: Thu Jan 01 00:00:00 1970 +0000
414 | date: Thu Jan 01 00:00:00 1970 +0000
415 | summary: add original_c
415 | summary: add original_c
416 |
416 |
417 o changeset: 1:7c3bad9141dc
417 o changeset: 1:7c3bad9141dc
418 | user: test
418 | user: test
419 | date: Thu Jan 01 00:00:00 1970 +0000
419 | date: Thu Jan 01 00:00:00 1970 +0000
420 | summary: add b
420 | summary: add b
421 |
421 |
422 o changeset: 0:1f0dee641bb7
422 o changeset: 0:1f0dee641bb7
423 user: test
423 user: test
424 date: Thu Jan 01 00:00:00 1970 +0000
424 date: Thu Jan 01 00:00:00 1970 +0000
425 summary: add a
425 summary: add a
426
426
427 $ hg -R clone-dest debugobsolete
427 $ hg -R clone-dest debugobsolete
428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
428 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
429 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
429 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
430 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
431 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
431 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
432 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
432 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
433
433
434
434
435 Destination repo have existing data
435 Destination repo have existing data
436 ---------------------------------------
436 ---------------------------------------
437
437
438 On pull
438 On pull
439
439
440 $ hg init tmpe
440 $ hg init tmpe
441 $ cd tmpe
441 $ cd tmpe
442 $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
442 $ hg debugobsolete -d '1339 0' 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339
443 $ hg pull ../tmpb
443 $ hg pull ../tmpb
444 pulling from ../tmpb
444 pulling from ../tmpb
445 requesting all changes
445 requesting all changes
446 adding changesets
446 adding changesets
447 adding manifests
447 adding manifests
448 adding file changes
448 adding file changes
449 added 4 changesets with 4 changes to 4 files (+1 heads)
449 added 4 changesets with 4 changes to 4 files (+1 heads)
450 (run 'hg heads' to see heads, 'hg merge' to merge)
450 (run 'hg heads' to see heads, 'hg merge' to merge)
451 $ hg debugobsolete
451 $ hg debugobsolete
452 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
452 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
453 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
453 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
454 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
454 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
455 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
455 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
456 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
456 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
457 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
457 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
458
458
459
459
460 On push
460 On push
461
461
462 $ hg push ../tmpc
462 $ hg push ../tmpc
463 pushing to ../tmpc
463 pushing to ../tmpc
464 searching for changes
464 searching for changes
465 no changes found
465 no changes found
466 [1]
466 [1]
467 $ hg -R ../tmpc debugobsolete
467 $ hg -R ../tmpc debugobsolete
468 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
468 245bde4270cd1072a27757984f9cda8ba26f08ca cdbce2fbb16313928851e97e0d85413f3f7eb77f C {'date': '56 12', 'user': 'test'}
469 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
469 cdbce2fbb16313928851e97e0d85413f3f7eb77f ca819180edb99ed25ceafb3e9584ac287e240b00 0 {'date': '1337 0', 'user': 'test'}
470 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
470 ca819180edb99ed25ceafb3e9584ac287e240b00 1337133713371337133713371337133713371337 0 {'date': '1338 0', 'user': 'test'}
471 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
471 1337133713371337133713371337133713371337 5601fb93a350734d935195fee37f4054c529ff39 0 {'date': '1339 0', 'user': 'test'}
472 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
472 5601fb93a350734d935195fee37f4054c529ff39 6f96419950729f3671185b847352890f074f7557 1 {'date': '1338 0', 'user': 'test'}
473 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
473 2448244824482448244824482448244824482448 1339133913391339133913391339133913391339 0 {'date': '1339 0', 'user': 'test'}
474
474
475 detect outgoing obsolete and unstable
475 detect outgoing obsolete and unstable
476 ---------------------------------------
476 ---------------------------------------
477
477
478
478
479 $ hg glog
479 $ hg glog
480 o changeset: 3:6f9641995072
480 o changeset: 3:6f9641995072
481 | tag: tip
481 | tag: tip
482 | parent: 1:7c3bad9141dc
482 | parent: 1:7c3bad9141dc
483 | user: test
483 | user: test
484 | date: Thu Jan 01 00:00:00 1970 +0000
484 | date: Thu Jan 01 00:00:00 1970 +0000
485 | summary: add n3w_3_c
485 | summary: add n3w_3_c
486 |
486 |
487 | o changeset: 2:245bde4270cd
487 | o changeset: 2:245bde4270cd
488 |/ user: test
488 |/ user: test
489 | date: Thu Jan 01 00:00:00 1970 +0000
489 | date: Thu Jan 01 00:00:00 1970 +0000
490 | summary: add original_c
490 | summary: add original_c
491 |
491 |
492 o changeset: 1:7c3bad9141dc
492 o changeset: 1:7c3bad9141dc
493 | user: test
493 | user: test
494 | date: Thu Jan 01 00:00:00 1970 +0000
494 | date: Thu Jan 01 00:00:00 1970 +0000
495 | summary: add b
495 | summary: add b
496 |
496 |
497 o changeset: 0:1f0dee641bb7
497 o changeset: 0:1f0dee641bb7
498 user: test
498 user: test
499 date: Thu Jan 01 00:00:00 1970 +0000
499 date: Thu Jan 01 00:00:00 1970 +0000
500 summary: add a
500 summary: add a
501
501
502 $ hg up 'desc("n3w_3_c")'
502 $ hg up 'desc("n3w_3_c")'
503 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
503 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
504 $ mkcommit original_d
504 $ mkcommit original_d
505 $ mkcommit original_e
505 $ mkcommit original_e
506 $ hg debugobsolete `getid original_d` -d '0 0'
506 $ hg debugobsolete `getid original_d` -d '0 0'
507 $ hg log -r 'obsolete()'
507 $ hg log -r 'obsolete()'
508 changeset: 4:94b33453f93b
508 changeset: 4:94b33453f93b
509 user: test
509 user: test
510 date: Thu Jan 01 00:00:00 1970 +0000
510 date: Thu Jan 01 00:00:00 1970 +0000
511 summary: add original_d
511 summary: add original_d
512
512
513 $ hg glog -r '::unstable()'
513 $ hg glog -r '::unstable()'
514 @ changeset: 5:cda648ca50f5
514 @ changeset: 5:cda648ca50f5
515 | tag: tip
515 | tag: tip
516 | user: test
516 | user: test
517 | date: Thu Jan 01 00:00:00 1970 +0000
517 | date: Thu Jan 01 00:00:00 1970 +0000
518 | summary: add original_e
518 | summary: add original_e
519 |
519 |
520 x changeset: 4:94b33453f93b
520 x changeset: 4:94b33453f93b
521 | user: test
521 | user: test
522 | date: Thu Jan 01 00:00:00 1970 +0000
522 | date: Thu Jan 01 00:00:00 1970 +0000
523 | summary: add original_d
523 | summary: add original_d
524 |
524 |
525 o changeset: 3:6f9641995072
525 o changeset: 3:6f9641995072
526 | parent: 1:7c3bad9141dc
526 | parent: 1:7c3bad9141dc
527 | user: test
527 | user: test
528 | date: Thu Jan 01 00:00:00 1970 +0000
528 | date: Thu Jan 01 00:00:00 1970 +0000
529 | summary: add n3w_3_c
529 | summary: add n3w_3_c
530 |
530 |
531 o changeset: 1:7c3bad9141dc
531 o changeset: 1:7c3bad9141dc
532 | user: test
532 | user: test
533 | date: Thu Jan 01 00:00:00 1970 +0000
533 | date: Thu Jan 01 00:00:00 1970 +0000
534 | summary: add b
534 | summary: add b
535 |
535 |
536 o changeset: 0:1f0dee641bb7
536 o changeset: 0:1f0dee641bb7
537 user: test
537 user: test
538 date: Thu Jan 01 00:00:00 1970 +0000
538 date: Thu Jan 01 00:00:00 1970 +0000
539 summary: add a
539 summary: add a
540
540
541
541
542 refuse to push obsolete changeset
542 refuse to push obsolete changeset
543
543
544 $ hg push ../tmpc/ -r 'desc("original_d")'
544 $ hg push ../tmpc/ -r 'desc("original_d")'
545 pushing to ../tmpc/
545 pushing to ../tmpc/
546 searching for changes
546 searching for changes
547 abort: push includes obsolete changeset: 94b33453f93b!
547 abort: push includes obsolete changeset: 94b33453f93b!
548 [255]
548 [255]
549
549
550 refuse to push unstable changeset
550 refuse to push unstable changeset
551
551
552 $ hg push ../tmpc/
552 $ hg push ../tmpc/
553 pushing to ../tmpc/
553 pushing to ../tmpc/
554 searching for changes
554 searching for changes
555 abort: push includes unstable changeset: cda648ca50f5!
555 abort: push includes unstable changeset: cda648ca50f5!
556 [255]
556 [255]
557
557
558 Test that extinct changeset are properly detected
558 Test that extinct changeset are properly detected
559
559
560 $ hg log -r 'extinct()'
560 $ hg log -r 'extinct()'
561
561
562 Don't try to push extinct changeset
562 Don't try to push extinct changeset
563
563
564 $ hg init ../tmpf
564 $ hg init ../tmpf
565 $ hg out ../tmpf
565 $ hg out ../tmpf
566 comparing with ../tmpf
566 comparing with ../tmpf
567 searching for changes
567 searching for changes
568 changeset: 0:1f0dee641bb7
568 changeset: 0:1f0dee641bb7
569 user: test
569 user: test
570 date: Thu Jan 01 00:00:00 1970 +0000
570 date: Thu Jan 01 00:00:00 1970 +0000
571 summary: add a
571 summary: add a
572
572
573 changeset: 1:7c3bad9141dc
573 changeset: 1:7c3bad9141dc
574 user: test
574 user: test
575 date: Thu Jan 01 00:00:00 1970 +0000
575 date: Thu Jan 01 00:00:00 1970 +0000
576 summary: add b
576 summary: add b
577
577
578 changeset: 2:245bde4270cd
578 changeset: 2:245bde4270cd
579 user: test
579 user: test
580 date: Thu Jan 01 00:00:00 1970 +0000
580 date: Thu Jan 01 00:00:00 1970 +0000
581 summary: add original_c
581 summary: add original_c
582
582
583 changeset: 3:6f9641995072
583 changeset: 3:6f9641995072
584 parent: 1:7c3bad9141dc
584 parent: 1:7c3bad9141dc
585 user: test
585 user: test
586 date: Thu Jan 01 00:00:00 1970 +0000
586 date: Thu Jan 01 00:00:00 1970 +0000
587 summary: add n3w_3_c
587 summary: add n3w_3_c
588
588
589 changeset: 4:94b33453f93b
589 changeset: 4:94b33453f93b
590 user: test
590 user: test
591 date: Thu Jan 01 00:00:00 1970 +0000
591 date: Thu Jan 01 00:00:00 1970 +0000
592 summary: add original_d
592 summary: add original_d
593
593
594 changeset: 5:cda648ca50f5
594 changeset: 5:cda648ca50f5
595 tag: tip
595 tag: tip
596 user: test
596 user: test
597 date: Thu Jan 01 00:00:00 1970 +0000
597 date: Thu Jan 01 00:00:00 1970 +0000
598 summary: add original_e
598 summary: add original_e
599
599
600 $ hg push ../tmpf -f # -f because be push unstable too
600 $ hg push ../tmpf -f # -f because be push unstable too
601 pushing to ../tmpf
601 pushing to ../tmpf
602 searching for changes
602 searching for changes
603 adding changesets
603 adding changesets
604 adding manifests
604 adding manifests
605 adding file changes
605 adding file changes
606 added 6 changesets with 6 changes to 6 files (+1 heads)
606 added 6 changesets with 6 changes to 6 files (+1 heads)
607
607
608 no warning displayed
608 no warning displayed
609
609
610 $ hg push ../tmpf
610 $ hg push ../tmpf
611 pushing to ../tmpf
611 pushing to ../tmpf
612 searching for changes
612 searching for changes
613 no changes found
613 no changes found
614 [1]
614 [1]
615
615
616 Do not warn about new head when the new head is a successors of a remote one
616 Do not warn about new head when the new head is a successors of a remote one
617
617
618 $ hg glog
618 $ hg glog
619 @ changeset: 5:cda648ca50f5
619 @ changeset: 5:cda648ca50f5
620 | tag: tip
620 | tag: tip
621 | user: test
621 | user: test
622 | date: Thu Jan 01 00:00:00 1970 +0000
622 | date: Thu Jan 01 00:00:00 1970 +0000
623 | summary: add original_e
623 | summary: add original_e
624 |
624 |
625 x changeset: 4:94b33453f93b
625 x changeset: 4:94b33453f93b
626 | user: test
626 | user: test
627 | date: Thu Jan 01 00:00:00 1970 +0000
627 | date: Thu Jan 01 00:00:00 1970 +0000
628 | summary: add original_d
628 | summary: add original_d
629 |
629 |
630 o changeset: 3:6f9641995072
630 o changeset: 3:6f9641995072
631 | parent: 1:7c3bad9141dc
631 | parent: 1:7c3bad9141dc
632 | user: test
632 | user: test
633 | date: Thu Jan 01 00:00:00 1970 +0000
633 | date: Thu Jan 01 00:00:00 1970 +0000
634 | summary: add n3w_3_c
634 | summary: add n3w_3_c
635 |
635 |
636 | o changeset: 2:245bde4270cd
636 | o changeset: 2:245bde4270cd
637 |/ user: test
637 |/ user: test
638 | date: Thu Jan 01 00:00:00 1970 +0000
638 | date: Thu Jan 01 00:00:00 1970 +0000
639 | summary: add original_c
639 | summary: add original_c
640 |
640 |
641 o changeset: 1:7c3bad9141dc
641 o changeset: 1:7c3bad9141dc
642 | user: test
642 | user: test
643 | date: Thu Jan 01 00:00:00 1970 +0000
643 | date: Thu Jan 01 00:00:00 1970 +0000
644 | summary: add b
644 | summary: add b
645 |
645 |
646 o changeset: 0:1f0dee641bb7
646 o changeset: 0:1f0dee641bb7
647 user: test
647 user: test
648 date: Thu Jan 01 00:00:00 1970 +0000
648 date: Thu Jan 01 00:00:00 1970 +0000
649 summary: add a
649 summary: add a
650
650
651 $ hg up -q 'desc(n3w_3_c)'
651 $ hg up -q 'desc(n3w_3_c)'
652 $ mkcommit obsolete_e
652 $ mkcommit obsolete_e
653 created new head
653 created new head
654 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
654 $ hg debugobsolete `getid 'original_e'` `getid 'obsolete_e'`
655 $ hg push ../tmpf
655 $ hg push ../tmpf
656 pushing to ../tmpf
656 pushing to ../tmpf
657 searching for changes
657 searching for changes
658 adding changesets
658 adding changesets
659 adding manifests
659 adding manifests
660 adding file changes
660 adding file changes
661 added 1 changesets with 1 changes to 1 files (+1 heads)
661 added 1 changesets with 1 changes to 1 files (+1 heads)
662
662
663 check hgweb does not explode
663 check hgweb does not explode
664 ====================================
664 ====================================
665
665
666 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
666 $ hg unbundle $TESTDIR/bundles/hgweb+obs.hg
667 adding changesets
667 adding changesets
668 adding manifests
668 adding manifests
669 adding file changes
669 adding file changes
670 added 62 changesets with 63 changes to 9 files (+60 heads)
670 added 62 changesets with 63 changes to 9 files (+60 heads)
671 (run 'hg heads .' to see heads, 'hg merge' to merge)
671 (run 'hg heads .' to see heads, 'hg merge' to merge)
672 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
672 $ for node in `hg log -r 'desc(babar_)' --template '{node}\n'`;
673 > do
673 > do
674 > hg debugobsolete $node
674 > hg debugobsolete $node
675 > done
675 > done
676 $ hg up tip
676 $ hg up tip
677 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
677 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
678
678
679 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
679 $ hg serve -n test -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log
680 $ cat hg.pid >> $DAEMON_PIDS
680 $ cat hg.pid >> $DAEMON_PIDS
681
681
682 check changelog view
682 check changelog view
683
683
684 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'shortlog/'
684 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'shortlog/'
685 200 Script output follows
685 200 Script output follows
686
686
687 #check graph view
687 check graph view
688 #
688
689 # $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'graph'
689 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'graph'
690 # 200 Script output follows
690 200 Script output follows
691
691 check filelog view
692 check filelog view
692
693
693 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'log/'`hg id --debug --id`/'babar'
694 $ "$TESTDIR/get-with-headers.py" --headeronly localhost:$HGPORT 'log/'`hg id --debug --id`/'babar'
694 200 Script output follows
695 200 Script output follows
695
696 $ kill `cat hg.pid`
696 $ kill `cat hg.pid`
697
697
698 Checking _enable=False warning if obsolete marker exists
698 Checking _enable=False warning if obsolete marker exists
699
699
700 $ echo '[extensions]' >> $HGRCPATH
700 $ echo '[extensions]' >> $HGRCPATH
701 $ echo "obs=!" >> $HGRCPATH
701 $ echo "obs=!" >> $HGRCPATH
702 $ hg log -r tip
702 $ hg log -r tip
703 obsolete feature not enabled but 68 markers found!
703 obsolete feature not enabled but 68 markers found!
704 changeset: 68:c15e9edfca13
704 changeset: 68:c15e9edfca13
705 tag: tip
705 tag: tip
706 parent: 7:50c51b361e60
706 parent: 7:50c51b361e60
707 user: test
707 user: test
708 date: Thu Jan 01 00:00:00 1970 +0000
708 date: Thu Jan 01 00:00:00 1970 +0000
709 summary: add celestine
709 summary: add celestine
710
710
General Comments 0
You need to be logged in to leave comments. Login now