comparison hgext/uncommit.py @ 41341:19c590ce8661

unamend: fix unamending of renamed rename Before this patch, we were passing in the result of a status call for a different set of commits than what we calculated copies for, which seemed suspicous to me. The rewritten version gets status and copy information from the same sets of commits. Differential Revision: https://phab.mercurial-scm.org/D5661
author Martin von Zweigbergk <martinvonz@google.com>
date Sun, 20 Jan 2019 22:00:25 -0800
parents c9f1fd82a826
children fe83040400b7
comparison
equal deleted inserted replaced
41340:c9f1fd82a826 41341:19c590ce8661
91 user=ctx.user(), 91 user=ctx.user(),
92 date=ctx.date(), 92 date=ctx.date(),
93 extra=ctx.extra()) 93 extra=ctx.extra())
94 return repo.commitctx(new) 94 return repo.commitctx(new)
95 95
96 def _fixdirstate(repo, oldctx, newctx, status): 96 def _fixdirstate(repo, oldctx, newctx, match=None):
97 """ fix the dirstate after switching the working directory from oldctx to 97 """ fix the dirstate after switching the working directory from oldctx to
98 newctx which can be result of either unamend or uncommit. 98 newctx which can be result of either unamend or uncommit.
99 """ 99 """
100 ds = repo.dirstate 100 ds = repo.dirstate
101 copies = dict(ds.copies()) 101 copies = dict(ds.copies())
102 s = status 102 s = newctx.status(oldctx, match=match)
103 for f in s.modified: 103 for f in s.modified:
104 if ds[f] == 'r': 104 if ds[f] == 'r':
105 # modified + removed -> removed 105 # modified + removed -> removed
106 continue 106 continue
107 ds.normallookup(f) 107 ds.normallookup(f)
119 ds.normallookup(f) 119 ds.normallookup(f)
120 elif ds[f] != 'r': 120 elif ds[f] != 'r':
121 ds.remove(f) 121 ds.remove(f)
122 122
123 # Merge old parent and old working dir copies 123 # Merge old parent and old working dir copies
124 oldcopies = {} 124 oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
125 for f in (s.modified + s.added):
126 src = oldctx[f].renamed()
127 if src:
128 oldcopies[f] = src[0]
129 oldcopies.update(copies) 125 oldcopies.update(copies)
130 copies = dict((dst, oldcopies.get(src, src)) 126 copies = dict((dst, oldcopies.get(src, src))
131 for dst, src in oldcopies.iteritems()) 127 for dst, src in oldcopies.iteritems())
132 # Adjust the dirstate copies 128 # Adjust the dirstate copies
133 for dst, src in copies.iteritems(): 129 for dst, src in copies.iteritems():
179 # Fully removed the old commit 175 # Fully removed the old commit
180 mapping[old.node()] = () 176 mapping[old.node()] = ()
181 177
182 with repo.dirstate.parentchange(): 178 with repo.dirstate.parentchange():
183 repo.dirstate.setparents(newid, node.nullid) 179 repo.dirstate.setparents(newid, node.nullid)
184 s = old.p1().status(old, match=match) 180 _fixdirstate(repo, old, repo[newid], match)
185 _fixdirstate(repo, old, repo[newid], s)
186 181
187 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True) 182 scmutil.cleanupnodes(repo, mapping, 'uncommit', fixphase=True)
188 183
189 def predecessormarkers(ctx): 184 def predecessormarkers(ctx):
190 """yields the obsolete markers marking the given changeset as a successor""" 185 """yields the obsolete markers marking the given changeset as a successor"""
243 newpredctx = repo[newprednode] 238 newpredctx = repo[newprednode]
244 dirstate = repo.dirstate 239 dirstate = repo.dirstate
245 240
246 with dirstate.parentchange(): 241 with dirstate.parentchange():
247 dirstate.setparents(newprednode, node.nullid) 242 dirstate.setparents(newprednode, node.nullid)
248 s = repo.status(predctx, curctx) 243 _fixdirstate(repo, curctx, newpredctx)
249 _fixdirstate(repo, curctx, newpredctx, s)
250 244
251 mapping = {curctx.node(): (newprednode,)} 245 mapping = {curctx.node(): (newprednode,)}
252 scmutil.cleanupnodes(repo, mapping, 'unamend', fixphase=True) 246 scmutil.cleanupnodes(repo, mapping, 'unamend', fixphase=True)