hgext/evolve.py
changeset 265 24943df310d4
parent 264 1c21865bf8ba
child 268 2da5af3dadeb
equal deleted inserted replaced
264:1c21865bf8ba 265:24943df310d4
    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