comparison mercurial/obsutil.py @ 34421:187bc224554a

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
author Boris Feld <boris.feld@octobus.net>
date Thu, 06 Jul 2017 15:00:07 +0200
parents 95759620d492
children 2fd06499dc8e
comparison
equal deleted inserted replaced
34420:95759620d492 34421:187bc224554a
310 # logic around storing and using effect flags 310 # logic around storing and using effect flags
311 EFFECTFLAGFIELD = "ef1" 311 EFFECTFLAGFIELD = "ef1"
312 312
313 DESCCHANGED = 1 << 0 # action changed the description 313 DESCCHANGED = 1 << 0 # action changed the description
314 METACHANGED = 1 << 1 # action change the meta 314 METACHANGED = 1 << 1 # action change the meta
315 DIFFCHANGED = 1 << 3 # action change diff introduced by the changeset
315 PARENTCHANGED = 1 << 2 # action change the parent 316 PARENTCHANGED = 1 << 2 # action change the parent
316 USERCHANGED = 1 << 4 # the user changed 317 USERCHANGED = 1 << 4 # the user changed
317 DATECHANGED = 1 << 5 # the date changed 318 DATECHANGED = 1 << 5 # the date changed
318 BRANCHCHANGED = 1 << 6 # the branch changed 319 BRANCHCHANGED = 1 << 6 # the branch changed
319 320
330 """ 331 """
331 metakey = metaitem[0] 332 metakey = metaitem[0]
332 333
333 return not any(pattern.match(metakey) for pattern in METABLACKLIST) 334 return not any(pattern.match(metakey) for pattern in METABLACKLIST)
334 335
336 def _prepare_hunk(hunk):
337 """Drop all information but the username and patch"""
338 cleanhunk = []
339 for line in hunk.splitlines():
340 if line.startswith(b'# User') or not line.startswith(b'#'):
341 if line.startswith(b'@@'):
342 line = b'@@\n'
343 cleanhunk.append(line)
344 return cleanhunk
345
346 def _getdifflines(iterdiff):
347 """return a cleaned up lines"""
348 lines = next(iterdiff, None)
349
350 if lines is None:
351 return lines
352
353 return _prepare_hunk(lines)
354
355 def _cmpdiff(leftctx, rightctx):
356 """return True if both ctx introduce the "same diff"
357
358 This is a first and basic implementation, with many shortcoming.
359 """
360
361 # Leftctx or right ctx might be filtered, so we need to use the contexts
362 # with an unfiltered repository to safely compute the diff
363 leftunfi = leftctx._repo.unfiltered()[leftctx.rev()]
364 leftdiff = leftunfi.diff(git=1)
365 rightunfi = rightctx._repo.unfiltered()[rightctx.rev()]
366 rightdiff = rightunfi.diff(git=1)
367
368 left, right = (0, 0)
369 while None not in (left, right):
370 left = _getdifflines(leftdiff)
371 right = _getdifflines(rightdiff)
372
373 if left != right:
374 return False
375 return True
376
335 def geteffectflag(relation): 377 def geteffectflag(relation):
336 """ From an obs-marker relation, compute what changed between the 378 """ From an obs-marker relation, compute what changed between the
337 predecessor and the successor. 379 predecessor and the successor.
338 """ 380 """
339 effects = 0 381 effects = 0
368 sourceextra = source.extra().items() 410 sourceextra = source.extra().items()
369 srcmeta = filter(metanotblacklisted, sourceextra) 411 srcmeta = filter(metanotblacklisted, sourceextra)
370 412
371 if ctxmeta != srcmeta: 413 if ctxmeta != srcmeta:
372 effects |= METACHANGED 414 effects |= METACHANGED
415
416 # Check if the diff has changed
417 if not _cmpdiff(source, changectx):
418 effects |= DIFFCHANGED
373 419
374 return effects 420 return effects
375 421
376 def getobsoleted(repo, tr): 422 def getobsoleted(repo, tr):
377 """return the set of pre-existing revisions obsoleted by a transaction""" 423 """return the set of pre-existing revisions obsoleted by a transaction"""