55 |
55 |
56 ### changeset rewriting logic |
56 ### changeset rewriting logic |
57 ############################# |
57 ############################# |
58 |
58 |
59 def rewrite(repo, old, updates, head, newbases, commitopts): |
59 def rewrite(repo, old, updates, head, newbases, commitopts): |
|
60 """Return (nodeid, created) where nodeid is the identifier of the |
|
61 changeset generated by the rewrite process, and created is True if |
|
62 nodeid was actually created. If created is False, nodeid |
|
63 references a changeset existing before the rewrite call. |
|
64 """ |
60 if len(old.parents()) > 1: #XXX remove this unecessary limitation. |
65 if len(old.parents()) > 1: #XXX remove this unecessary limitation. |
61 raise error.Abort(_('cannot amend merge changesets')) |
66 raise error.Abort(_('cannot amend merge changesets')) |
62 base = old.p1() |
67 base = old.p1() |
63 bm = bookmarks.readcurrent(repo) |
68 bm = bookmarks.readcurrent(repo) |
64 |
69 |
124 date=date, |
129 date=date, |
125 extra=extra) |
130 extra=extra) |
126 |
131 |
127 if commitopts.get('edit'): |
132 if commitopts.get('edit'): |
128 new._text = cmdutil.commitforceeditor(repo, new, []) |
133 new._text = cmdutil.commitforceeditor(repo, new, []) |
|
134 revcount = len(repo) |
129 newid = repo.commitctx(new) |
135 newid = repo.commitctx(new) |
130 new = repo[newid] |
136 new = repo[newid] |
131 |
137 created = len(repo) != revcount |
132 # update the bookmark |
138 if created: |
133 if bm: |
139 # update the bookmark |
134 repo._bookmarks[bm] = newid |
140 if bm: |
135 bookmarks.write(repo) |
141 repo._bookmarks[bm] = newid |
136 |
142 bookmarks.write(repo) |
137 # add evolution metadata |
143 |
138 repo.addobsolete(new.node(), old.node()) |
144 # add evolution metadata |
139 for u in updates: |
145 repo.addobsolete(new.node(), old.node()) |
140 repo.addobsolete(u.node(), old.node()) |
146 for u in updates: |
141 repo.addobsolete(new.node(), u.node()) |
147 repo.addobsolete(u.node(), old.node()) |
142 oldbookmarks = repo.nodebookmarks(old.node()) |
148 repo.addobsolete(new.node(), u.node()) |
143 for book in oldbookmarks: |
149 oldbookmarks = repo.nodebookmarks(old.node()) |
144 repo._bookmarks[book] = new.node() |
150 for book in oldbookmarks: |
145 if oldbookmarks: |
151 repo._bookmarks[book] = new.node() |
146 bookmarks.write(repo) |
152 if oldbookmarks: |
147 |
153 bookmarks.write(repo) |
|
154 else: |
|
155 # newid is an existing revision. It could make sense to |
|
156 # replace revisions with existing ones but probably not by |
|
157 # default. |
|
158 pass |
148 finally: |
159 finally: |
149 wlock.release() |
160 wlock.release() |
150 |
161 |
151 return newid |
162 return newid, created |
152 |
163 |
153 def relocate(repo, orig, dest): |
164 def relocate(repo, orig, dest): |
154 """rewrite <rev> on dest""" |
165 """rewrite <rev> on dest""" |
155 try: |
166 try: |
156 rebase = extensions.find('rebase') |
167 rebase = extensions.find('rebase') |
405 ciopts['message'] = opts.get('note') or ('amends %s' % old.hex()) |
416 ciopts['message'] = opts.get('note') or ('amends %s' % old.hex()) |
406 e = cmdutil.commiteditor |
417 e = cmdutil.commiteditor |
407 def commitfunc(ui, repo, message, match, opts): |
418 def commitfunc(ui, repo, message, match, opts): |
408 return repo.commit(message, opts.get('user'), opts.get('date'), match, |
419 return repo.commit(message, opts.get('user'), opts.get('date'), match, |
409 editor=e) |
420 editor=e) |
410 cmdutil.commit(ui, repo, commitfunc, pats, ciopts) |
421 revcount = len(repo) |
|
422 tempid = cmdutil.commit(ui, repo, commitfunc, pats, ciopts) |
|
423 if len(repo) == revcount: |
|
424 # No revision created |
|
425 tempid = None |
411 |
426 |
412 # find all changesets to be considered updates |
427 # find all changesets to be considered updates |
413 cl = repo.changelog |
428 cl = repo.changelog |
414 head = repo['.'] |
429 head = repo['.'] |
415 updatenodes = set(cl.nodesbetween(roots=[old.node()], |
430 updatenodes = set(cl.nodesbetween(roots=[old.node()], |
427 |
442 |
428 |
443 |
429 # perform amend |
444 # perform amend |
430 if opts.get('edit'): |
445 if opts.get('edit'): |
431 opts['force_editor'] = True |
446 opts['force_editor'] = True |
432 newid = rewrite(repo, old, updates, head, |
447 newid, created = rewrite(repo, old, updates, head, |
433 [old.p1().node(), old.p2().node()], opts) |
448 [old.p1().node(), old.p2().node()], opts) |
434 |
449 if created: |
435 # reroute the working copy parent to the new changeset |
450 # reroute the working copy parent to the new changeset |
436 phases.retractboundary(repo, oldphase, [newid]) |
451 phases.retractboundary(repo, oldphase, [newid]) |
437 repo.dirstate.setparents(newid, node.nullid) |
452 repo.dirstate.setparents(newid, node.nullid) |
438 |
453 else: |
|
454 # rewrite() recreated an existing revision, discard |
|
455 # the intermediate revision if any. No need to update |
|
456 # phases or parents. |
|
457 if tempid is not None: |
|
458 repo.addobsolete(node.nullid, tempid) |
|
459 # XXX: need another message in collapse case. |
|
460 raise error.Abort(_('no updates found')) |
439 finally: |
461 finally: |
440 wlock.release() |
462 wlock.release() |
441 finally: |
463 finally: |
442 lock.release() |
464 lock.release() |
443 |
465 |