Mercurial > hg
comparison hgext/histedit.py @ 28216:eed7d8c07c20
histedit: make histedit aware of obsolescense not stored in state (issue4800)
Before this change, when histedit exited to interactive session (during edit
command for example), user could introduce obsolescence markers that would not
be known to histedit. For example, user could've amended one of the commits.
The fact of this amendment would not be stored in histedit's state file
and later, when histedit would try to process all the replacements,
one of the final successors (in histedit's opinion) would turn out to be hidden.
This behavior is described in issue4800. This commit fixes it.
author | Kostia Balytskyi <ikostia@fb.com> |
---|---|
date | Tue, 23 Feb 2016 21:38:36 +0000 |
parents | 2e11f6756d9c |
children | 8ec5478aa0d6 |
comparison
equal
deleted
inserted
replaced
28215:f7c5c7847b53 | 28216:eed7d8c07c20 |
---|---|
1384 raise error.ParseError(_('missing rules for changeset %s') % | 1384 raise error.ParseError(_('missing rules for changeset %s') % |
1385 missing[0][:12], | 1385 missing[0][:12], |
1386 hint=_('use "drop %s" to discard, see also: ' | 1386 hint=_('use "drop %s" to discard, see also: ' |
1387 '"hg help -e histedit.config"') % missing[0][:12]) | 1387 '"hg help -e histedit.config"') % missing[0][:12]) |
1388 | 1388 |
1389 def adjustreplacementsfrommarkers(repo, oldreplacements): | |
1390 """Adjust replacements from obsolescense markers | |
1391 | |
1392 Replacements structure is originally generated based on | |
1393 histedit's state and does not account for changes that are | |
1394 not recorded there. This function fixes that by adding | |
1395 data read from obsolescense markers""" | |
1396 if not obsolete.isenabled(repo, obsolete.createmarkersopt): | |
1397 return oldreplacements | |
1398 | |
1399 unfi = repo.unfiltered() | |
1400 newreplacements = list(oldreplacements) | |
1401 oldsuccs = [r[1] for r in oldreplacements] | |
1402 # successors that have already been added to succstocheck once | |
1403 seensuccs = set().union(*oldsuccs) # create a set from an iterable of tuples | |
1404 succstocheck = list(seensuccs) | |
1405 while succstocheck: | |
1406 n = succstocheck.pop() | |
1407 try: | |
1408 ctx = unfi[n] | |
1409 except error.RepoError: | |
1410 # XXX node unknown locally, we should properly follow marker | |
1411 newreplacements.append((n, ())) | |
1412 continue | |
1413 | |
1414 for marker in obsolete.successormarkers(ctx): | |
1415 nsuccs = marker.succnodes() | |
1416 newreplacements.append((n, nsuccs)) | |
1417 for nsucc in nsuccs: | |
1418 if nsucc not in seensuccs: | |
1419 seensuccs.add(nsucc) | |
1420 succstocheck.append(nsucc) | |
1421 | |
1422 return newreplacements | |
1423 | |
1389 def processreplacement(state): | 1424 def processreplacement(state): |
1390 """process the list of replacements to return | 1425 """process the list of replacements to return |
1391 | 1426 |
1392 1) the final mapping between original and created nodes | 1427 1) the final mapping between original and created nodes |
1393 2) the list of temporary node created by histedit | 1428 2) the list of temporary node created by histedit |
1394 3) the list of new commit created by histedit""" | 1429 3) the list of new commit created by histedit""" |
1395 replacements = state.replacements | 1430 replacements = adjustreplacementsfrommarkers(state.repo, state.replacements) |
1396 allsuccs = set() | 1431 allsuccs = set() |
1397 replaced = set() | 1432 replaced = set() |
1398 fullmapping = {} | 1433 fullmapping = {} |
1399 # initialize basic set | 1434 # initialize basic set |
1400 # fullmapping records all operations recorded in replacement | 1435 # fullmapping records all operations recorded in replacement |