Mercurial > hg-stable
comparison mercurial/repair.py @ 16252:cf17e76be4dd stable
strip: enhance repair.strip to receive a list of nodes (issue3299)
Originally, mq.strip called repair.strip a single rev at a time.
repair.strip stores in a backup bundle any revision greater than
the revision being stripped, strips, then restores the backup with
repo.addchangegroup. So, when stripping revisions on more than one
topological branch, some could end up being restored from the backup
bundle, only to be later removed by a subsequent repair.strip call.
But repo.addchangegroup calls hooks for all those restore operations.
And 9df9444e96ec changed it to delay all hook calls until the
repository lock were released - by mq.strip, after stripping all
revisions. Thus, the hooks could be called over revisions already
removed from the repository at that point.
By generating the revision lists at once inside repo.strip, we avoid
calling addchangegroup for temporary restores. Incidentally, this
also avoids creating many backup files for a single strip command.
author | Wagner Bruna <wbruna@softwareexpress.com.br> |
---|---|
date | Mon, 12 Mar 2012 17:02:45 -0300 |
parents | 73c4b3d0c711 |
children | 17f179805297 |
comparison
equal
deleted
inserted
replaced
16244:3d26d69ef822 | 16252:cf17e76be4dd |
---|---|
52 for fname in files: | 52 for fname in files: |
53 collectone(repo.file(fname)) | 53 collectone(repo.file(fname)) |
54 | 54 |
55 return s | 55 return s |
56 | 56 |
57 def strip(ui, repo, node, backup="all"): | 57 def strip(ui, repo, nodelist, backup="all"): |
58 cl = repo.changelog | 58 cl = repo.changelog |
59 # TODO delete the undo files, and handle undo of merge sets | 59 # TODO delete the undo files, and handle undo of merge sets |
60 striprev = cl.rev(node) | 60 if isinstance(nodelist, str): |
61 nodelist = [nodelist] | |
62 striplist = [cl.rev(node) for node in nodelist] | |
63 striprev = min(striplist) | |
61 | 64 |
62 keeppartialbundle = backup == 'strip' | 65 keeppartialbundle = backup == 'strip' |
63 | 66 |
64 # Some revisions with rev > striprev may not be descendants of striprev. | 67 # Some revisions with rev > striprev may not be descendants of striprev. |
65 # We have to find these revisions and put them in a bundle, so that | 68 # We have to find these revisions and put them in a bundle, so that |
66 # we can restore them after the truncations. | 69 # we can restore them after the truncations. |
67 # To create the bundle we use repo.changegroupsubset which requires | 70 # To create the bundle we use repo.changegroupsubset which requires |
68 # the list of heads and bases of the set of interesting revisions. | 71 # the list of heads and bases of the set of interesting revisions. |
69 # (head = revision in the set that has no descendant in the set; | 72 # (head = revision in the set that has no descendant in the set; |
70 # base = revision in the set that has no ancestor in the set) | 73 # base = revision in the set that has no ancestor in the set) |
71 tostrip = set(cl.descendants(striprev)) | 74 tostrip = set(striplist) |
72 tostrip.add(striprev) | 75 for rev in striplist: |
76 for desc in cl.descendants(rev): | |
77 tostrip.add(desc) | |
73 | 78 |
74 files = _collectfiles(repo, striprev) | 79 files = _collectfiles(repo, striprev) |
75 saverevs = _collectbrokencsets(repo, files, striprev) | 80 saverevs = _collectbrokencsets(repo, files, striprev) |
76 | 81 |
77 # compute heads | 82 # compute heads |
86 # compute base nodes | 91 # compute base nodes |
87 if saverevs: | 92 if saverevs: |
88 descendants = set(cl.descendants(*saverevs)) | 93 descendants = set(cl.descendants(*saverevs)) |
89 saverevs.difference_update(descendants) | 94 saverevs.difference_update(descendants) |
90 savebases = [cl.node(r) for r in saverevs] | 95 savebases = [cl.node(r) for r in saverevs] |
96 stripbases = [cl.node(r) for r in tostrip] | |
91 | 97 |
92 bm = repo._bookmarks | 98 bm = repo._bookmarks |
93 updatebm = [] | 99 updatebm = [] |
94 for m in bm: | 100 for m in bm: |
95 rev = repo[bm[m]].rev() | 101 rev = repo[bm[m]].rev() |
97 updatebm.append(m) | 103 updatebm.append(m) |
98 | 104 |
99 # create a changegroup for all the branches we need to keep | 105 # create a changegroup for all the branches we need to keep |
100 backupfile = None | 106 backupfile = None |
101 if backup == "all": | 107 if backup == "all": |
102 backupfile = _bundle(repo, [node], cl.heads(), node, 'backup') | 108 backupfile = _bundle(repo, stripbases, cl.heads(), node, 'backup') |
103 repo.ui.status(_("saved backup bundle to %s\n") % backupfile) | 109 repo.ui.status(_("saved backup bundle to %s\n") % backupfile) |
104 if saveheads or savebases: | 110 if saveheads or savebases: |
105 # do not compress partial bundle if we remove it from disk later | 111 # do not compress partial bundle if we remove it from disk later |
106 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp', | 112 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp', |
107 compress=keeppartialbundle) | 113 compress=keeppartialbundle) |