##// END OF EJS Templates
scmutil: add a cleanupnodes method for developers...
Jun Wu -
r33088:65cadeea default
parent child Browse files
Show More
@@ -16,6 +16,8 b' import socket'
16
16
17 from .i18n import _
17 from .i18n import _
18 from .node import (
18 from .node import (
19 hex,
20 nullid,
19 wdirid,
21 wdirid,
20 wdirrev,
22 wdirrev,
21 )
23 )
@@ -24,6 +26,7 b' from . import ('
24 encoding,
26 encoding,
25 error,
27 error,
26 match as matchmod,
28 match as matchmod,
29 obsolete,
27 pathutil,
30 pathutil,
28 phases,
31 phases,
29 pycompat,
32 pycompat,
@@ -561,6 +564,68 b' def origpath(ui, repo, filepath):'
561
564
562 return fullorigpath + ".orig"
565 return fullorigpath + ".orig"
563
566
567 def cleanupnodes(repo, mapping, operation):
568 """do common cleanups when old nodes are replaced by new nodes
569
570 That includes writing obsmarkers or stripping nodes, and moving bookmarks.
571 (we might also want to move working directory parent in the future)
572
573 mapping is {oldnode: [newnode]} or a iterable of nodes if they do not have
574 replacements. operation is a string, like "rebase".
575 """
576 if not util.safehasattr(mapping, 'items'):
577 mapping = {n: () for n in mapping}
578
579 with repo.transaction('cleanup') as tr:
580 # Move bookmarks
581 bmarks = repo._bookmarks
582 bmarkchanged = False
583 for oldnode, newnodes in mapping.items():
584 oldbmarks = repo.nodebookmarks(oldnode)
585 if not oldbmarks:
586 continue
587 bmarkchanged = True
588 if len(newnodes) > 1:
589 heads = list(repo.set('heads(%ln)', newnodes))
590 if len(heads) != 1:
591 raise error.ProgrammingError(
592 'cannot figure out bookmark movement')
593 newnode = heads[0].node()
594 elif len(newnodes) == 0:
595 # move bookmark backwards
596 roots = list(repo.set('max((::%n) - %ln)', oldnode,
597 list(mapping)))
598 if roots:
599 newnode = roots[0].node()
600 else:
601 newnode = nullid
602 else:
603 newnode = newnodes[0]
604 repo.ui.debug('moving bookmarks %r from %s to %s\n' %
605 (oldbmarks, hex(oldnode), hex(newnode)))
606 for name in oldbmarks:
607 bmarks[name] = newnode
608 if bmarkchanged:
609 bmarks.recordchange(tr)
610
611 # Obsolete or strip nodes
612 if obsolete.isenabled(repo, obsolete.createmarkersopt):
613 # If a node is already obsoleted, and we want to obsolete it
614 # without a successor, skip that obssolete request since it's
615 # unnecessary. That's the "if s or not isobs(n)" check below.
616 # Also sort the node in topology order, that might be useful for
617 # some obsstore logic.
618 # NOTE: the filtering and sorting might belong to createmarkers.
619 isobs = repo.obsstore.successors.__contains__
620 sortfunc = lambda ns: repo.changelog.rev(ns[0])
621 rels = [(repo[n], (repo[m] for m in s))
622 for n, s in sorted(mapping.items(), key=sortfunc)
623 if s or not isobs(n)]
624 obsolete.createmarkers(repo, rels, operation=operation)
625 else:
626 from . import repair # avoid import cycle
627 repair.delayedstrip(repo.ui, repo, list(mapping), operation)
628
564 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
629 def addremove(repo, matcher, prefix, opts=None, dry_run=None, similarity=None):
565 if opts is None:
630 if opts is None:
566 opts = {}
631 opts = {}
@@ -955,6 +955,7 b' Use delayedstrip to strip inside a trans'
955 > \|/
955 > \|/
956 > A Z
956 > A Z
957 > EOS
957 > EOS
958 $ cp -R . ../scmutilcleanup
958
959
959 $ hg up -C I
960 $ hg up -C I
960 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
961 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
@@ -990,3 +991,104 b' Use delayedstrip to strip inside a trans'
990 |/
991 |/
991 o 0:426bada5c675 A
992 o 0:426bada5c675 A
992
993
994 Test high-level scmutil.cleanupnodes API
995
996 $ cd $TESTTMP/scmutilcleanup
997 $ hg debugdrawdag <<'EOS'
998 > D2 F2 G2 # D2, F2, G2 are replacements for D, F, G
999 > | | |
1000 > C H G
1001 > EOS
1002 $ for i in B C D F G I Z; do
1003 > hg bookmark -i -r $i b-$i
1004 > done
1005 $ cp -R . ../scmutilcleanup.obsstore
1006
1007 $ cat > $TESTTMP/scmutilcleanup.py <<EOF
1008 > from mercurial import scmutil
1009 > def reposetup(ui, repo):
1010 > def nodes(expr):
1011 > return [repo.changelog.node(r) for r in repo.revs(expr)]
1012 > def node(expr):
1013 > return nodes(expr)[0]
1014 > with repo.wlock():
1015 > with repo.lock():
1016 > with repo.transaction('delayedstrip'):
1017 > mapping = {node('F'): [node('F2')],
1018 > node('D'): [node('D2')],
1019 > node('G'): [node('G2')]}
1020 > scmutil.cleanupnodes(repo, mapping, 'replace')
1021 > scmutil.cleanupnodes(repo, nodes('((B::)+I+Z)-D2'), 'replace')
1022 > EOF
1023 $ hg log -r . -T '\n' --config extensions.t=$TESTTMP/scmutilcleanup.py
1024 warning: orphaned descendants detected, not stripping 112478962961, 1fc8102cda62, 26805aba1e60
1025 saved backup bundle to $TESTTMP/scmutilcleanup/.hg/strip-backup/f585351a92f8-73fb7c03-replace.hg (glob)
1026
1027 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1028 o 8:1473d4b996d1 G2 b-G
1029 |
1030 | o 7:d94e89b773b6 F2 b-F
1031 | |
1032 | o 5:7fe5bac4c918 H
1033 |/|
1034 | o 3:7fb047a69f22 E
1035 | |
1036 | | o 6:7c78f703e465 D2 b-D
1037 | | |
1038 | | o 4:26805aba1e60 C
1039 | | |
1040 | | o 2:112478962961 B
1041 | |/
1042 o | 1:1fc8102cda62 G
1043 /
1044 o 0:426bada5c675 A b-B b-C b-I
1045
1046 $ hg bookmark
1047 b-B 0:426bada5c675
1048 b-C 0:426bada5c675
1049 b-D 6:7c78f703e465
1050 b-F 7:d94e89b773b6
1051 b-G 8:1473d4b996d1
1052 b-I 0:426bada5c675
1053 b-Z -1:000000000000
1054
1055 Test the above using obsstore "by the way". Not directly related to strip, but
1056 we have reusable code here
1057
1058 $ cd $TESTTMP/scmutilcleanup.obsstore
1059 $ cat >> .hg/hgrc <<EOF
1060 > [experimental]
1061 > evolution=all
1062 > evolution.track-operation=1
1063 > EOF
1064
1065 $ hg log -r . -T '\n' --config extensions.t=$TESTTMP/scmutilcleanup.py
1066
1067 $ rm .hg/localtags
1068 $ hg log -G -T '{rev}:{node|short} {desc} {bookmarks}' -r 'sort(all(), topo)'
1069 o 12:1473d4b996d1 G2 b-G
1070 |
1071 | o 11:d94e89b773b6 F2 b-F
1072 | |
1073 | o 8:7fe5bac4c918 H
1074 |/|
1075 | o 4:7fb047a69f22 E
1076 | |
1077 | | o 10:7c78f703e465 D2 b-D
1078 | | |
1079 | | x 6:26805aba1e60 C
1080 | | |
1081 | | x 3:112478962961 B
1082 | |/
1083 x | 1:1fc8102cda62 G
1084 /
1085 o 0:426bada5c675 A b-B b-C b-I
1086
1087 $ hg debugobsolete
1088 1fc8102cda6204549f031015641606ccf5513ec3 1473d4b996d1d1b121de6b39fab6a04fbf9d873e 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1089 64a8289d249234b9886244d379f15e6b650b28e3 d94e89b773b67e72642a931159ada8d1a9246998 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1090 f585351a92f85104bff7c284233c338b10eb1df7 7c78f703e465d73102cc8780667ce269c5208a40 0 (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1091 48b9aae0607f43ff110d84e6883c151942add5ab 0 {0000000000000000000000000000000000000000} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1092 112478962961147124edd43549aedd1a335e44bf 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1093 08ebfeb61bac6e3f12079de774d285a0d6689eba 0 {426bada5c67598ca65036d57d9e4b64b0c1ce7a0} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
1094 26805aba1e600a82e93661149f2313866a221a7b 0 {112478962961147124edd43549aedd1a335e44bf} (Thu Jan 01 00:00:00 1970 +0000) {'operation': 'replace', 'user': 'test'}
General Comments 0
You need to be logged in to leave comments. Login now