comparison mercurial/metadata.py @ 45667:0303fc1f43f8

changing-files: add clean computation of changed files for linear changesets The `files` field is not reliable, so we need to compute things from scratch. We deal with the second simplest case, linear changesets. We diff the current manifest with the parent manifest. This reveal the file added, changed and removed. Differential Revision: https://phab.mercurial-scm.org/D9127
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Tue, 29 Sep 2020 22:46:29 +0200
parents f6811e5bd994
children 47ad23549b81
comparison
equal deleted inserted replaced
45666:f6811e5bd994 45667:0303fc1f43f8
228 """compute the files changed by a revision""" 228 """compute the files changed by a revision"""
229 p1 = ctx.p1() 229 p1 = ctx.p1()
230 p2 = ctx.p2() 230 p2 = ctx.p2()
231 if p1.rev() == node.nullrev and p2.rev() == node.nullrev: 231 if p1.rev() == node.nullrev and p2.rev() == node.nullrev:
232 return _process_root(ctx) 232 return _process_root(ctx)
233 elif p1.rev() != node.nullrev and p2.rev() == node.nullrev:
234 return _process_linear(p1, ctx)
235 elif p1.rev() == node.nullrev and p2.rev() != node.nullrev:
236 # In the wild, one can encounter changeset where p1 is null but p2 is not
237 return _process_linear(p1, ctx, parent=2)
238 elif p1.rev() == p2.rev():
239 # In the wild, one can encounter such "non-merge"
240 return _process_linear(p1, ctx)
233 filescopies = computechangesetcopies(ctx) 241 filescopies = computechangesetcopies(ctx)
234 filesadded = computechangesetfilesadded(ctx) 242 filesadded = computechangesetfilesadded(ctx)
235 filesremoved = computechangesetfilesremoved(ctx) 243 filesremoved = computechangesetfilesremoved(ctx)
236 filesmerged = computechangesetfilesmerged(ctx) 244 filesmerged = computechangesetfilesmerged(ctx)
237 files = ChangingFiles() 245 files = ChangingFiles()
250 # Simple, there was nothing before it, so everything is added. 258 # Simple, there was nothing before it, so everything is added.
251 md = ChangingFiles() 259 md = ChangingFiles()
252 manifest = ctx.manifest() 260 manifest = ctx.manifest()
253 for filename in manifest: 261 for filename in manifest:
254 md.mark_added(filename) 262 md.mark_added(filename)
263 return md
264
265
266 def _process_linear(parent_ctx, children_ctx, parent=1):
267 """compute the appropriate changed files for a changeset with a single parent
268 """
269 md = ChangingFiles()
270 parent_manifest = parent_ctx.manifest()
271 children_manifest = children_ctx.manifest()
272
273 copies_candidate = []
274
275 for filename, d in parent_manifest.diff(children_manifest).items():
276 if d[1][0] is None:
277 # no filenode for the "new" value, file is absent
278 md.mark_removed(filename)
279 else:
280 copies_candidate.append(filename)
281 if d[0][0] is None:
282 # not filenode for the "old" value file was absent
283 md.mark_added(filename)
284 else:
285 # filenode for both "old" and "new"
286 md.mark_touched(filename)
287
288 if parent == 1:
289 copied = md.mark_copied_from_p1
290 elif parent == 2:
291 copied = md.mark_copied_from_p2
292 else:
293 assert False, "bad parent value %d" % parent
294
295 for filename in copies_candidate:
296 copy_info = children_ctx[filename].renamed()
297 if copy_info:
298 source, srcnode = copy_info
299 copied(source, filename)
300
255 return md 301 return md
256 302
257 303
258 def computechangesetfilesadded(ctx): 304 def computechangesetfilesadded(ctx):
259 """return the list of files added in a changeset 305 """return the list of files added in a changeset