Mercurial > hg
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 |