Mercurial > hg
comparison mercurial/hgweb/webutil.py @ 17991:d605a82cf189
hgweb: display diff for a changeset against any parents (issue2810)
During merge of branches, it is useful to compare merge results against
the two parents. This change adds this support to hgweb. To specify
which parent to compare to, use rev/12300:12345 where 12300 is a
parent changeset number. Two links are added to changeset web page so
that one can choose which parent to compare to.
author | Weiwen <weiwen@fb.com> |
---|---|
date | Mon, 12 Nov 2012 14:05:39 -0800 |
parents | 5c64ce6168da |
children | 60680d691a0b |
comparison
equal
deleted
inserted
replaced
17990:8216eb592dcd | 17991:d605a82cf189 |
---|---|
138 | 138 |
139 def cleanpath(repo, path): | 139 def cleanpath(repo, path): |
140 path = path.lstrip('/') | 140 path = path.lstrip('/') |
141 return scmutil.canonpath(repo.root, '', path) | 141 return scmutil.canonpath(repo.root, '', path) |
142 | 142 |
143 def changectx(repo, req): | 143 def changeidctx (repo, changeid): |
144 changeid = "tip" | |
145 if 'node' in req.form: | |
146 changeid = req.form['node'][0] | |
147 elif 'manifest' in req.form: | |
148 changeid = req.form['manifest'][0] | |
149 | |
150 try: | 144 try: |
151 ctx = repo[changeid] | 145 ctx = repo[changeid] |
152 except error.RepoError: | 146 except error.RepoError: |
153 man = repo.manifest | 147 man = repo.manifest |
154 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))] | 148 ctx = repo[man.linkrev(man.rev(man.lookup(changeid)))] |
155 | 149 |
156 return ctx | 150 return ctx |
151 | |
152 def changectx (repo, req): | |
153 changeid = "tip" | |
154 if 'node' in req.form: | |
155 changeid = req.form['node'][0] | |
156 ipos=changeid.find(':') | |
157 if ipos != -1: | |
158 changeid = changeid[(ipos + 1):] | |
159 elif 'manifest' in req.form: | |
160 changeid = req.form['manifest'][0] | |
161 | |
162 return changeidctx(repo, changeid) | |
163 | |
164 def basechangectx(repo, req): | |
165 if 'node' in req.form: | |
166 changeid = req.form['node'][0] | |
167 ipos=changeid.find(':') | |
168 if ipos != -1: | |
169 changeid = changeid[:ipos] | |
170 return changeidctx(repo, changeid) | |
171 | |
172 return None | |
157 | 173 |
158 def filectx(repo, req): | 174 def filectx(repo, req): |
159 if 'file' not in req.form: | 175 if 'file' not in req.form: |
160 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given') | 176 raise ErrorResponse(HTTP_NOT_FOUND, 'file not given') |
161 path = cleanpath(repo, req.form['file'][0]) | 177 path = cleanpath(repo, req.form['file'][0]) |
176 for f in files[:max]: | 192 for f in files[:max]: |
177 yield tmpl('filedifflink', node=hex(node), file=f) | 193 yield tmpl('filedifflink', node=hex(node), file=f) |
178 if len(files) > max: | 194 if len(files) > max: |
179 yield tmpl('fileellipses') | 195 yield tmpl('fileellipses') |
180 | 196 |
181 def diffs(repo, tmpl, ctx, files, parity, style): | 197 def diffs(repo, tmpl, ctx, basectx, files, parity, style): |
182 | 198 |
183 def countgen(): | 199 def countgen(): |
184 start = 1 | 200 start = 1 |
185 while True: | 201 while True: |
186 yield start | 202 yield start |
207 m = match.exact(repo.root, repo.getcwd(), files) | 223 m = match.exact(repo.root, repo.getcwd(), files) |
208 else: | 224 else: |
209 m = match.always(repo.root, repo.getcwd()) | 225 m = match.always(repo.root, repo.getcwd()) |
210 | 226 |
211 diffopts = patch.diffopts(repo.ui, untrusted=True) | 227 diffopts = patch.diffopts(repo.ui, untrusted=True) |
212 parents = ctx.parents() | 228 if basectx is None: |
213 node1 = parents and parents[0].node() or nullid | 229 parents = ctx.parents() |
230 node1 = parents and parents[0].node() or nullid | |
231 else: | |
232 node1 = basectx.node() | |
214 node2 = ctx.node() | 233 node2 = ctx.node() |
215 | 234 |
216 block = [] | 235 block = [] |
217 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts): | 236 for chunk in patch.diff(repo, node1, node2, m, opts=diffopts): |
218 if chunk.startswith('diff') and block: | 237 if chunk.startswith('diff') and block: |
272 yield tmpl('comparisonblock', lines=getblock(s.get_opcodes())) | 291 yield tmpl('comparisonblock', lines=getblock(s.get_opcodes())) |
273 else: | 292 else: |
274 for oc in s.get_grouped_opcodes(n=context): | 293 for oc in s.get_grouped_opcodes(n=context): |
275 yield tmpl('comparisonblock', lines=getblock(oc)) | 294 yield tmpl('comparisonblock', lines=getblock(oc)) |
276 | 295 |
277 def diffstatgen(ctx): | 296 def diffstatgen(ctx, basectx): |
278 '''Generator function that provides the diffstat data.''' | 297 '''Generator function that provides the diffstat data.''' |
279 | 298 |
280 stats = patch.diffstatdata(util.iterlines(ctx.diff())) | 299 stats = patch.diffstatdata(util.iterlines(ctx.diff(basectx))) |
281 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats) | 300 maxname, maxtotal, addtotal, removetotal, binary = patch.diffstatsum(stats) |
282 while True: | 301 while True: |
283 yield stats, maxname, maxtotal, addtotal, removetotal, binary | 302 yield stats, maxname, maxtotal, addtotal, removetotal, binary |
284 | 303 |
285 def diffsummary(statgen): | 304 def diffsummary(statgen): |