96 overrides = {('phases', 'new-commit'): commitphase} |
96 overrides = {('phases', 'new-commit'): commitphase} |
97 with repo.ui.configoverride(overrides, 'uncommit'): |
97 with repo.ui.configoverride(overrides, 'uncommit'): |
98 newid = repo.commitctx(new) |
98 newid = repo.commitctx(new) |
99 return newid |
99 return newid |
100 |
100 |
101 def _uncommitdirstate(repo, oldctx, match): |
101 def _fixdirstate(repo, oldctx, newctx, status): |
102 """Fix the dirstate after switching the working directory from |
102 """ fix the dirstate after switching the working directory from oldctx to |
103 oldctx to a copy of oldctx not containing changed files matched by |
103 newctx which can be result of either unamend or uncommit. |
104 match. |
104 """ |
105 """ |
|
106 ctx = repo['.'] |
|
107 ds = repo.dirstate |
105 ds = repo.dirstate |
108 copies = dict(ds.copies()) |
106 copies = dict(ds.copies()) |
109 s = repo.status(oldctx.p1(), oldctx, match=match) |
107 s = status |
110 for f in s.modified: |
108 for f in s.modified: |
111 if ds[f] == 'r': |
109 if ds[f] == 'r': |
112 # modified + removed -> removed |
110 # modified + removed -> removed |
113 continue |
111 continue |
114 ds.normallookup(f) |
112 ds.normallookup(f) |
136 oldcopies.update(copies) |
134 oldcopies.update(copies) |
137 copies = dict((dst, oldcopies.get(src, src)) |
135 copies = dict((dst, oldcopies.get(src, src)) |
138 for dst, src in oldcopies.iteritems()) |
136 for dst, src in oldcopies.iteritems()) |
139 # Adjust the dirstate copies |
137 # Adjust the dirstate copies |
140 for dst, src in copies.iteritems(): |
138 for dst, src in copies.iteritems(): |
141 if (src not in ctx or dst in ctx or ds[dst] != 'a'): |
139 if (src not in newctx or dst in newctx or ds[dst] != 'a'): |
142 src = None |
140 src = None |
143 ds.copy(src, dst) |
141 ds.copy(src, dst) |
144 |
142 |
145 @command('uncommit', |
143 @command('uncommit', |
146 [('', 'keep', False, _('allow an empty commit after uncommiting')), |
144 [('', 'keep', False, _('allow an empty commit after uncommiting')), |
192 |
190 |
193 scmutil.cleanupnodes(repo, mapping, 'uncommit') |
191 scmutil.cleanupnodes(repo, mapping, 'uncommit') |
194 |
192 |
195 with repo.dirstate.parentchange(): |
193 with repo.dirstate.parentchange(): |
196 repo.dirstate.setparents(newid, node.nullid) |
194 repo.dirstate.setparents(newid, node.nullid) |
197 _uncommitdirstate(repo, old, match) |
195 s = repo.status(old.p1(), old, match=match) |
|
196 _fixdirstate(repo, old, repo[newid], s) |
198 |
197 |
199 def predecessormarkers(ctx): |
198 def predecessormarkers(ctx): |
200 """yields the obsolete markers marking the given changeset as a successor""" |
199 """yields the obsolete markers marking the given changeset as a successor""" |
201 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()): |
200 for data in ctx.repo().obsstore.predecessors.get(ctx.node(), ()): |
202 yield obsutil.marker(ctx.repo(), data) |
201 yield obsutil.marker(ctx.repo(), data) |
203 |
|
204 def _unamenddirstate(repo, predctx, curctx): |
|
205 """""" |
|
206 |
|
207 s = repo.status(predctx, curctx) |
|
208 ds = repo.dirstate |
|
209 copies = dict(ds.copies()) |
|
210 for f in s.modified: |
|
211 if ds[f] == 'r': |
|
212 # modified + removed -> removed |
|
213 continue |
|
214 ds.normallookup(f) |
|
215 |
|
216 for f in s.added: |
|
217 if ds[f] == 'r': |
|
218 # added + removed -> unknown |
|
219 ds.drop(f) |
|
220 elif ds[f] != 'a': |
|
221 ds.add(f) |
|
222 |
|
223 for f in s.removed: |
|
224 if ds[f] == 'a': |
|
225 # removed + added -> normal |
|
226 ds.normallookup(f) |
|
227 elif ds[f] != 'r': |
|
228 ds.remove(f) |
|
229 |
|
230 # Merge old parent and old working dir copies |
|
231 oldcopies = {} |
|
232 for f in (s.modified + s.added): |
|
233 src = curctx[f].renamed() |
|
234 if src: |
|
235 oldcopies[f] = src[0] |
|
236 oldcopies.update(copies) |
|
237 copies = dict((dst, oldcopies.get(src, src)) |
|
238 for dst, src in oldcopies.iteritems()) |
|
239 # Adjust the dirstate copies |
|
240 for dst, src in copies.iteritems(): |
|
241 if (src not in predctx or dst in predctx or ds[dst] != 'a'): |
|
242 src = None |
|
243 ds.copy(src, dst) |
|
244 |
202 |
245 @command('^unamend', []) |
203 @command('^unamend', []) |
246 def unamend(ui, repo, **opts): |
204 def unamend(ui, repo, **opts): |
247 """ |
205 """ |
248 undo the most recent amend operation on a current changeset |
206 undo the most recent amend operation on a current changeset |
310 diff = cm.diff(wm) |
268 diff = cm.diff(wm) |
311 changedfiles.extend(diff.iterkeys()) |
269 changedfiles.extend(diff.iterkeys()) |
312 |
270 |
313 with dirstate.parentchange(): |
271 with dirstate.parentchange(): |
314 dirstate.setparents(newprednode, node.nullid) |
272 dirstate.setparents(newprednode, node.nullid) |
315 _unamenddirstate(repo, newpredctx, curctx) |
273 s = repo.status(predctx, curctx) |
|
274 _fixdirstate(repo, curctx, newpredctx, s) |
316 |
275 |
317 mapping = {curctx.node(): (newprednode,)} |
276 mapping = {curctx.node(): (newprednode,)} |
318 scmutil.cleanupnodes(repo, mapping, 'unamend') |
277 scmutil.cleanupnodes(repo, mapping, 'unamend') |