# HG changeset patch # User Augie Fackler # Date 1255732639 14400 # Node ID 990e07054f291ce695ba4d3f31907b15b3080139 # Parent cad864ed29de167cd4983010e899a1adffb8c5f1 replay: fix potential over-reporting of edited files in hg changelog diff --git a/hgsubversion/editor.py b/hgsubversion/editor.py --- a/hgsubversion/editor.py +++ b/hgsubversion/editor.py @@ -35,7 +35,7 @@ class RevisionData(object): __slots__ = [ 'file', 'files', 'deleted', 'rev', 'execfiles', 'symlinks', 'batons', 'copies', 'missing', 'emptybranches', 'base', 'externals', 'ui', - 'exception', + 'exception', 'maybeedits', ] def __init__(self, ui): @@ -57,6 +57,7 @@ class RevisionData(object): self.base = None self.externals = {} self.exception = None + self.maybeedits = set() def set(self, path, data, isexec=False, islink=False): if islink: @@ -280,6 +281,7 @@ class HgEditor(delta.Editor): parentctx = self.repo.changectx(parentid) for k, v in copies.iteritems(): if util.issamefile(parentctx, cp_f_ctx, v): + self.current.maybeedits.add(k) self.current.copies.update({k: v}) return path @@ -326,6 +328,11 @@ class HgEditor(delta.Editor): or self.current.file in self.current.missing), '%s not found' % self.current.file if self.current.file in self.current.missing: return lambda x: None + # If we apply a textdelta, the body of the file is going to change. + # There's little reason to check and see if it matches the parent, because + # that's extremely unlikely. If we see cases where that happens, + # maybe this line can go, but until then, it stays. + self.current.maybeedits.discard(self.current.file) base = self.current.files[self.current.file] source = cStringIO.StringIO(base) target = cStringIO.StringIO() diff --git a/hgsubversion/replay.py b/hgsubversion/replay.py --- a/hgsubversion/replay.py +++ b/hgsubversion/replay.py @@ -85,6 +85,22 @@ def convert_rev(ui, meta, svn, r, tbdelt if not meta.is_path_valid(f): continue p, b = meta.split_branch_path(f)[:2] + # Subversion sometimes "over reports" edits from our perspective, + # typically when a directory is restored from some past version. + # This isn't something we can detect reliably until the end of + # the delta edit, so we have to punt this detection until here + # This just verifies that if the file content is identical + # in the parent and the to-be-committed file, we don't bother + # marking it in the changelog as modified in this revision. + if f in current.maybeedits: + pctx = meta.repo[meta.get_parent_revision(rev.revnum, b)] + if p in pctx and pctx[p].data() == current.files[f]: + flags = pctx[p].flags() + is_exec = current.execfiles.get(f, 'x' in flags) + is_link = current.symlinks.get(f, 'l' in flags) + if is_link == ('l' in flags) and is_exec == ('x' in flags): + # file is wholly unchanged, we can skip it + continue if b not in branch_batches: branch_batches[b] = [] branch_batches[b].append((p, f))