# HG changeset patch # User Boris Feld # Date 2017-07-06 13:00:07 # Node ID 187bc224554adff72fb5df3879649a1f52ed08a6 # Parent 95759620d4922e64768a5f2687af98b983046fe1 effectflag: detect when diff changed Store in effect flag when the diff changed between the predecessor and its successors. Comparing the diff is not easy because we do not want to incorrectly detect a diff --git a/mercurial/obsutil.py b/mercurial/obsutil.py --- a/mercurial/obsutil.py +++ b/mercurial/obsutil.py @@ -312,6 +312,7 @@ EFFECTFLAGFIELD = "ef1" DESCCHANGED = 1 << 0 # action changed the description METACHANGED = 1 << 1 # action change the meta +DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset PARENTCHANGED = 1 << 2 # action change the parent USERCHANGED = 1 << 4 # the user changed DATECHANGED = 1 << 5 # the date changed @@ -332,6 +333,47 @@ def metanotblacklisted(metaitem): return not any(pattern.match(metakey) for pattern in METABLACKLIST) +def _prepare_hunk(hunk): + """Drop all information but the username and patch""" + cleanhunk = [] + for line in hunk.splitlines(): + if line.startswith(b'# User') or not line.startswith(b'#'): + if line.startswith(b'@@'): + line = b'@@\n' + cleanhunk.append(line) + return cleanhunk + +def _getdifflines(iterdiff): + """return a cleaned up lines""" + lines = next(iterdiff, None) + + if lines is None: + return lines + + return _prepare_hunk(lines) + +def _cmpdiff(leftctx, rightctx): + """return True if both ctx introduce the "same diff" + + This is a first and basic implementation, with many shortcoming. + """ + + # Leftctx or right ctx might be filtered, so we need to use the contexts + # with an unfiltered repository to safely compute the diff + leftunfi = leftctx._repo.unfiltered()[leftctx.rev()] + leftdiff = leftunfi.diff(git=1) + rightunfi = rightctx._repo.unfiltered()[rightctx.rev()] + rightdiff = rightunfi.diff(git=1) + + left, right = (0, 0) + while None not in (left, right): + left = _getdifflines(leftdiff) + right = _getdifflines(rightdiff) + + if left != right: + return False + return True + def geteffectflag(relation): """ From an obs-marker relation, compute what changed between the predecessor and the successor. @@ -371,6 +413,10 @@ def geteffectflag(relation): if ctxmeta != srcmeta: effects |= METACHANGED + # Check if the diff has changed + if not _cmpdiff(source, changectx): + effects |= DIFFCHANGED + return effects def getobsoleted(repo, tr): diff --git a/tests/test-obsmarkers-effectflag.t b/tests/test-obsmarkers-effectflag.t --- a/tests/test-obsmarkers-effectflag.t +++ b/tests/test-obsmarkers-effectflag.t @@ -93,7 +93,7 @@ amend touching the diff check result $ hg debugobsolete --rev . - ebfe0333e0d96f68a917afd97c0a0af87f1c3b5f 75781fdbdbf58a987516b00c980bccda1e9ae588 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '0', 'operation': 'amend', 'user': 'test'} + ebfe0333e0d96f68a917afd97c0a0af87f1c3b5f 75781fdbdbf58a987516b00c980bccda1e9ae588 0 (Thu Jan 01 00:00:00 1970 +0000) {'ef1': '8', 'operation': 'amend', 'user': 'test'} amend with multiple effect (desc and meta) -------------------------------------------