Show More
@@ -119,101 +119,107 b' def stripcmd(ui, repo, *revs, **opts):' | |||
|
119 | 119 | revs = list(revs) + opts.get('rev') |
|
120 | 120 | revs = set(scmutil.revrange(repo, revs)) |
|
121 | 121 | |
|
122 | if opts.get('bookmark'): | |
|
123 | mark = opts.get('bookmark') | |
|
124 | marks = repo._bookmarks | |
|
125 | if mark not in marks: | |
|
126 | raise util.Abort(_("bookmark '%s' not found") % mark) | |
|
122 | wlock = repo.wlock() | |
|
123 | try: | |
|
124 | if opts.get('bookmark'): | |
|
125 | mark = opts.get('bookmark') | |
|
126 | marks = repo._bookmarks | |
|
127 | if mark not in marks: | |
|
128 | raise util.Abort(_("bookmark '%s' not found") % mark) | |
|
129 | ||
|
130 | # If the requested bookmark is not the only one pointing to a | |
|
131 | # a revision we have to only delete the bookmark and not strip | |
|
132 | # anything. revsets cannot detect that case. | |
|
133 | uniquebm = True | |
|
134 | for m, n in marks.iteritems(): | |
|
135 | if m != mark and n == repo[mark].node(): | |
|
136 | uniquebm = False | |
|
137 | break | |
|
138 | if uniquebm: | |
|
139 | rsrevs = repo.revs("ancestors(bookmark(%s)) - " | |
|
140 | "ancestors(head() and not bookmark(%s)) - " | |
|
141 | "ancestors(bookmark() and not bookmark(%s))", | |
|
142 | mark, mark, mark) | |
|
143 | revs.update(set(rsrevs)) | |
|
144 | if not revs: | |
|
145 | del marks[mark] | |
|
146 | marks.write() | |
|
147 | ui.write(_("bookmark '%s' deleted\n") % mark) | |
|
148 | ||
|
149 | if not revs: | |
|
150 | raise util.Abort(_('empty revision set')) | |
|
151 | ||
|
152 | descendants = set(cl.descendants(revs)) | |
|
153 | strippedrevs = revs.union(descendants) | |
|
154 | roots = revs.difference(descendants) | |
|
155 | ||
|
156 | update = False | |
|
157 | # if one of the wdir parent is stripped we'll need | |
|
158 | # to update away to an earlier revision | |
|
159 | for p in repo.dirstate.parents(): | |
|
160 | if p != nullid and cl.rev(p) in strippedrevs: | |
|
161 | update = True | |
|
162 | break | |
|
163 | ||
|
164 | rootnodes = set(cl.node(r) for r in roots) | |
|
127 | 165 | |
|
128 | # If the requested bookmark is not the only one pointing to a | |
|
129 | # a revision we have to only delete the bookmark and not strip | |
|
130 | # anything. revsets cannot detect that case. | |
|
131 | uniquebm = True | |
|
132 | for m, n in marks.iteritems(): | |
|
133 | if m != mark and n == repo[mark].node(): | |
|
134 |
|
|
|
135 |
|
|
|
136 | if uniquebm: | |
|
137 | rsrevs = repo.revs("ancestors(bookmark(%s)) - " | |
|
138 | "ancestors(head() and not bookmark(%s)) - " | |
|
139 | "ancestors(bookmark() and not bookmark(%s))", | |
|
140 |
|
|
|
141 | revs.update(set(rsrevs)) | |
|
142 | if not revs: | |
|
166 | q = getattr(repo, 'mq', None) | |
|
167 | if q is not None and q.applied: | |
|
168 | # refresh queue state if we're about to strip | |
|
169 | # applied patches | |
|
170 | if cl.rev(repo.lookup('qtip')) in strippedrevs: | |
|
171 | q.applieddirty = True | |
|
172 | start = 0 | |
|
173 | end = len(q.applied) | |
|
174 | for i, statusentry in enumerate(q.applied): | |
|
175 | if statusentry.node in rootnodes: | |
|
176 | # if one of the stripped roots is an applied | |
|
177 | # patch, only part of the queue is stripped | |
|
178 | start = i | |
|
179 | break | |
|
180 | del q.applied[start:end] | |
|
181 | q.savedirty() | |
|
182 | ||
|
183 | revs = sorted(rootnodes) | |
|
184 | if update and opts.get('keep'): | |
|
185 | wlock = repo.wlock() | |
|
186 | try: | |
|
187 | urev, p2 = repo.changelog.parents(revs[0]) | |
|
188 | if (util.safehasattr(repo, 'mq') and p2 != nullid | |
|
189 | and p2 in [x.node for x in repo.mq.applied]): | |
|
190 | urev = p2 | |
|
191 | uctx = repo[urev] | |
|
192 | ||
|
193 | # only reset the dirstate for files that would actually change | |
|
194 | # between the working context and uctx | |
|
195 | descendantrevs = repo.revs("%s::." % uctx.rev()) | |
|
196 | changedfiles = [] | |
|
197 | for rev in descendantrevs: | |
|
198 | # blindly reset the files, regardless of what actually | |
|
199 | # changed | |
|
200 | changedfiles.extend(repo[rev].files()) | |
|
201 | ||
|
202 | # reset files that only changed in the dirstate too | |
|
203 | dirstate = repo.dirstate | |
|
204 | dirchanges = [f for f in dirstate if dirstate[f] != 'n'] | |
|
205 | changedfiles.extend(dirchanges) | |
|
206 | ||
|
207 | repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles) | |
|
208 | repo.dirstate.write() | |
|
209 | update = False | |
|
210 | finally: | |
|
211 | wlock.release() | |
|
212 | ||
|
213 | if opts.get('bookmark'): | |
|
214 | if mark == repo._bookmarkcurrent: | |
|
215 | bookmarks.unsetcurrent(repo) | |
|
143 | 216 | del marks[mark] |
|
144 | 217 | marks.write() |
|
145 | 218 | ui.write(_("bookmark '%s' deleted\n") % mark) |
|
146 | 219 | |
|
147 | if not revs: | |
|
148 | raise util.Abort(_('empty revision set')) | |
|
149 | ||
|
150 | descendants = set(cl.descendants(revs)) | |
|
151 | strippedrevs = revs.union(descendants) | |
|
152 | roots = revs.difference(descendants) | |
|
153 | ||
|
154 | update = False | |
|
155 | # if one of the wdir parent is stripped we'll need | |
|
156 | # to update away to an earlier revision | |
|
157 | for p in repo.dirstate.parents(): | |
|
158 | if p != nullid and cl.rev(p) in strippedrevs: | |
|
159 | update = True | |
|
160 | break | |
|
161 | ||
|
162 | rootnodes = set(cl.node(r) for r in roots) | |
|
163 | ||
|
164 | q = getattr(repo, 'mq', None) | |
|
165 | if q is not None and q.applied: | |
|
166 | # refresh queue state if we're about to strip | |
|
167 | # applied patches | |
|
168 | if cl.rev(repo.lookup('qtip')) in strippedrevs: | |
|
169 | q.applieddirty = True | |
|
170 | start = 0 | |
|
171 | end = len(q.applied) | |
|
172 | for i, statusentry in enumerate(q.applied): | |
|
173 | if statusentry.node in rootnodes: | |
|
174 | # if one of the stripped roots is an applied | |
|
175 | # patch, only part of the queue is stripped | |
|
176 | start = i | |
|
177 | break | |
|
178 | del q.applied[start:end] | |
|
179 | q.savedirty() | |
|
180 | ||
|
181 | revs = sorted(rootnodes) | |
|
182 | if update and opts.get('keep'): | |
|
183 | wlock = repo.wlock() | |
|
184 | try: | |
|
185 | urev, p2 = repo.changelog.parents(revs[0]) | |
|
186 | if (util.safehasattr(repo, 'mq') and p2 != nullid | |
|
187 | and p2 in [x.node for x in repo.mq.applied]): | |
|
188 | urev = p2 | |
|
189 | uctx = repo[urev] | |
|
190 | ||
|
191 | # only reset the dirstate for files that would actually change | |
|
192 | # between the working context and uctx | |
|
193 | descendantrevs = repo.revs("%s::." % uctx.rev()) | |
|
194 | changedfiles = [] | |
|
195 | for rev in descendantrevs: | |
|
196 | # blindly reset the files, regardless of what actually changed | |
|
197 | changedfiles.extend(repo[rev].files()) | |
|
198 | ||
|
199 | # reset files that only changed in the dirstate too | |
|
200 | dirstate = repo.dirstate | |
|
201 | dirchanges = [f for f in dirstate if dirstate[f] != 'n'] | |
|
202 | changedfiles.extend(dirchanges) | |
|
203 | ||
|
204 | repo.dirstate.rebuild(urev, uctx.manifest(), changedfiles) | |
|
205 | repo.dirstate.write() | |
|
206 | update = False | |
|
207 | finally: | |
|
208 | wlock.release() | |
|
209 | ||
|
210 | if opts.get('bookmark'): | |
|
211 | if mark == repo._bookmarkcurrent: | |
|
212 | bookmarks.unsetcurrent(repo) | |
|
213 | del marks[mark] | |
|
214 | marks.write() | |
|
215 | ui.write(_("bookmark '%s' deleted\n") % mark) | |
|
216 | ||
|
217 | strip(ui, repo, revs, backup=backup, update=update, force=opts.get('force')) | |
|
220 | strip(ui, repo, revs, backup=backup, update=update, | |
|
221 | force=opts.get('force')) | |
|
222 | finally: | |
|
223 | wlock.release() | |
|
218 | 224 | |
|
219 | 225 | return 0 |
General Comments 0
You need to be logged in to leave comments.
Login now