663 ### template keywords |
663 ### template keywords |
664 # XXX it does not handle troubles well :-/ |
664 # XXX it does not handle troubles well :-/ |
665 |
665 |
666 @eh.templatekw('obsolete') |
666 @eh.templatekw('obsolete') |
667 def obsoletekw(repo, ctx, templ, **args): |
667 def obsoletekw(repo, ctx, templ, **args): |
668 """:obsolete: String. The obsolescence level of the node, could be |
668 """:obsolete: String. Whether the changeset is ``obsolete``. |
669 ``stable``, ``unstable``, ``suspended`` or ``extinct``. |
|
670 """ |
669 """ |
671 if ctx.obsolete(): |
670 if ctx.obsolete(): |
672 if ctx.extinct(): |
671 return 'obsolete' |
673 return 'extinct' |
672 return '' |
674 else: |
|
675 return 'suspended' |
|
676 elif ctx.unstable(): |
|
677 return 'unstable' |
|
678 return 'stable' |
|
679 |
673 |
680 @eh.templatekw('troubles') |
674 @eh.templatekw('troubles') |
681 def showtroubles(repo, ctx, **args): |
675 def showtroubles(repo, ctx, **args): |
682 """:troubles: List of strings. Evolution troubles affecting the changeset |
676 """:troubles: List of strings. Evolution troubles affecting the changeset |
683 (zero or more of "unstable", "divergent" or "bumped").""" |
677 (zero or more of "unstable", "divergent" or "bumped").""" |
962 'not be updated\n') % sha1) |
956 'not be updated\n') % sha1) |
963 |
957 |
964 tr = repo.currenttransaction() |
958 tr = repo.currenttransaction() |
965 assert tr is not None |
959 assert tr is not None |
966 try: |
960 try: |
967 try: |
961 r = _evolvemerge(repo, orig, dest, pctx, keepbranch) |
968 r = _evolvemerge(repo, orig, dest, pctx, keepbranch) |
962 if r[-1]: #some conflict |
969 if r[-1]: #some conflict |
963 raise error.Abort( |
970 raise error.Abort( |
964 'unresolved merge conflicts (see hg help resolve)') |
971 'unresolved merge conflicts (see hg help resolve)') |
965 nodenew = _relocatecommit(repo, orig, commitmsg) |
972 nodenew = _relocatecommit(repo, orig, commitmsg) |
966 except error.Abort as exc: |
973 except error.Abort as exc: |
967 repo.dirstate.beginparentchange() |
974 repo.dirstate.beginparentchange() |
968 repo.setparents(repo['.'].node(), nullid) |
975 repo.setparents(repo['.'].node(), nullid) |
969 writedirstate(repo.dirstate, tr) |
976 writedirstate(repo.dirstate, tr) |
970 # fix up dirstate for copies and renames |
977 # fix up dirstate for copies and renames |
971 copies.duplicatecopies(repo, dest.rev(), orig.p1().rev()) |
978 copies.duplicatecopies(repo, dest.rev(), orig.p1().rev()) |
972 repo.dirstate.endparentchange() |
979 repo.dirstate.endparentchange() |
973 class LocalMergeFailure(MergeFailure, exc.__class__): |
980 class LocalMergeFailure(MergeFailure, exc.__class__): |
974 pass |
981 pass |
975 exc.__class__ = LocalMergeFailure |
982 exc.__class__ = LocalMergeFailure |
976 tr.close() # to keep changes in this transaction (e.g. dirstate) |
983 tr.close() # to keep changes in this transaction (e.g. dirstate) |
977 raise |
984 raise |
978 oldbookmarks = repo.nodebookmarks(nodesrc) |
985 oldbookmarks = repo.nodebookmarks(nodesrc) |
979 _finalizerelocate(repo, orig, dest, nodenew, tr) |
986 _finalizerelocate(repo, orig, dest, nodenew, tr) |
|
987 finally: |
|
988 pass # TODO: remove this redundant try/finally block |
|
989 return nodenew |
980 return nodenew |
990 |
981 |
991 def _bookmarksupdater(repo, oldid, tr): |
982 def _bookmarksupdater(repo, oldid, tr): |
992 """Return a callable update(newid) updating the current bookmark |
983 """Return a callable update(newid) updating the current bookmark |
993 and bookmarks bound to oldid to newid. |
984 and bookmarks bound to oldid to newid. |
1792 state = _evolvestateread(repo) |
1783 state = _evolvestateread(repo) |
1793 if state is None: |
1784 if state is None: |
1794 raise error.Abort('no evolve to continue') |
1785 raise error.Abort('no evolve to continue') |
1795 orig = repo[state['current']] |
1786 orig = repo[state['current']] |
1796 # XXX This is a terrible terrible hack, please get rid of it. |
1787 # XXX This is a terrible terrible hack, please get rid of it. |
1797 repo.opener.write('graftstate', orig.hex() + '\n') |
1788 lock = repo.wlock() |
1798 try: |
1789 try: |
1799 graftcmd = commands.table['graft'][0] |
1790 repo.opener.write('graftstate', orig.hex() + '\n') |
1800 ret = graftcmd(ui, repo, old_obsolete=True, **{'continue': True}) |
1791 try: |
1801 _evolvestatedelete(repo) |
1792 graftcmd = commands.table['graft'][0] |
1802 return ret |
1793 ret = graftcmd(ui, repo, old_obsolete=True, **{'continue': True}) |
|
1794 _evolvestatedelete(repo) |
|
1795 return ret |
|
1796 finally: |
|
1797 util.unlinkpath(repo.join('graftstate'), ignoremissing=True) |
1803 finally: |
1798 finally: |
1804 util.unlinkpath(repo.join('graftstate'), ignoremissing=True) |
1799 lock.release() |
1805 cmdutil.bailifchanged(repo) |
1800 cmdutil.bailifchanged(repo) |
1806 |
1801 |
1807 |
1802 |
1808 if revopt and allopt: |
1803 if revopt and allopt: |
1809 raise error.Abort('cannot specify both "--rev" and "--all"') |
1804 raise error.Abort('cannot specify both "--rev" and "--all"') |
1992 tmpctx = bumped |
1987 tmpctx = bumped |
1993 # Basic check for common parent. Far too complicated and fragile |
1988 # Basic check for common parent. Far too complicated and fragile |
1994 tr = repo.currenttransaction() |
1989 tr = repo.currenttransaction() |
1995 assert tr is not None |
1990 assert tr is not None |
1996 bmupdate = _bookmarksupdater(repo, bumped.node(), tr) |
1991 bmupdate = _bookmarksupdater(repo, bumped.node(), tr) |
1997 try: |
1992 if not list(repo.set('parents(%d) and parents(%d)', bumped, prec)): |
1998 if not list(repo.set('parents(%d) and parents(%d)', bumped, prec)): |
1993 # Need to rebase the changeset at the right place |
1999 # Need to rebase the changeset at the right place |
1994 repo.ui.status( |
2000 repo.ui.status( |
1995 _('rebasing to destination parent: %s\n') % prec.p1()) |
2001 _('rebasing to destination parent: %s\n') % prec.p1()) |
1996 try: |
2002 try: |
1997 tmpid = relocate(repo, bumped, prec.p1()) |
2003 tmpid = relocate(repo, bumped, prec.p1()) |
1998 if tmpid is not None: |
2004 if tmpid is not None: |
1999 tmpctx = repo[tmpid] |
2005 tmpctx = repo[tmpid] |
2000 obsolete.createmarkers(repo, [(bumped, (tmpctx,))]) |
2006 obsolete.createmarkers(repo, [(bumped, (tmpctx,))]) |
2001 except MergeFailure: |
2007 except MergeFailure: |
2002 repo.opener.write('graftstate', bumped.hex() + '\n') |
2008 repo.opener.write('graftstate', bumped.hex() + '\n') |
2003 repo.ui.write_err(_('evolution failed!\n')) |
2009 repo.ui.write_err(_('evolution failed!\n')) |
2004 repo.ui.write_err( |
2010 repo.ui.write_err( |
2005 _('fix conflict and run "hg evolve --continue"\n')) |
2011 _('fix conflict and run "hg evolve --continue"\n')) |
2006 raise |
2012 raise |
2007 # Create the new commit context |
2013 # Create the new commit context |
2008 repo.ui.status(_('computing new diff\n')) |
2014 repo.ui.status(_('computing new diff\n')) |
2009 files = set() |
2015 files = set() |
2010 copied = copies.pathcopies(prec, bumped) |
2016 copied = copies.pathcopies(prec, bumped) |
2011 precmanifest = prec.manifest().copy() |
2017 precmanifest = prec.manifest().copy() |
2012 # 3.3.2 needs a list. |
2018 # 3.3.2 needs a list. |
2013 # future 3.4 don't detect the size change during iteration |
2019 # future 3.4 don't detect the size change during iteration |
2014 # this is fishy |
2020 # this is fishy |
2015 for key, val in list(bumped.manifest().iteritems()): |
2021 for key, val in list(bumped.manifest().iteritems()): |
2016 precvalue = precmanifest.get(key, None) |
2022 precvalue = precmanifest.get(key, None) |
2017 if precvalue is not None: |
2023 if precvalue is not None: |
2018 del precmanifest[key] |
2024 del precmanifest[key] |
2019 if precvalue != val: |
2025 if precvalue != val: |
2020 files.add(key) |
2026 files.add(key) |
2021 files.update(precmanifest) # add missing files |
2027 files.update(precmanifest) # add missing files |
2022 # commit it |
2028 # commit it |
2023 if files: # something to commit! |
2029 if files: # something to commit! |
2024 def filectxfn(repo, ctx, path): |
2030 def filectxfn(repo, ctx, path): |
2025 if path in bumped: |
2031 if path in bumped: |
2026 fctx = bumped[path] |
2032 fctx = bumped[path] |
2027 flags = fctx.flags() |
2033 flags = fctx.flags() |
2028 mctx = memfilectx(repo, fctx.path(), fctx.data(), |
2034 mctx = memfilectx(repo, fctx.path(), fctx.data(), |
2029 islink='l' in flags, |
2035 islink='l' in flags, |
2030 isexec='x' in flags, |
2036 isexec='x' in flags, |
2031 copied=copied.get(path)) |
2037 copied=copied.get(path)) |
2032 return mctx |
2038 return mctx |
2033 return None |
2039 return None |
2034 text = 'bumped update to %s:\n\n' % prec |
2040 text = 'bumped update to %s:\n\n' % prec |
2035 text += bumped.description() |
2041 text += bumped.description() |
2036 |
2042 |
2037 new = context.memctx(repo, |
2043 new = context.memctx(repo, |
2038 parents=[prec.node(), node.nullid], |
2044 parents=[prec.node(), node.nullid], |
2039 text=text, |
2045 text=text, |
2040 files=files, |
2046 files=files, |
2041 filectxfn=filectxfn, |
2047 filectxfn=filectxfn, |
2042 user=bumped.user(), |
2048 user=bumped.user(), |
2043 date=bumped.date(), |
2049 date=bumped.date(), |
2044 extra=bumped.extra()) |
2050 extra=bumped.extra()) |
2045 |
2051 |
2046 newid = repo.commitctx(new) |
2052 newid = repo.commitctx(new) |
2047 if newid is None: |
2053 if newid is None: |
2048 obsolete.createmarkers(repo, [(tmpctx, ())]) |
2054 obsolete.createmarkers(repo, [(tmpctx, ())]) |
2049 newid = prec.node() |
2055 newid = prec.node() |
2050 else: |
2056 else: |
2051 phases.retractboundary(repo, tr, bumped.phase(), [newid]) |
2057 phases.retractboundary(repo, tr, bumped.phase(), [newid]) |
2052 obsolete.createmarkers(repo, [(tmpctx, (repo[newid],))], |
2058 obsolete.createmarkers(repo, [(tmpctx, (repo[newid],))], |
2053 flag=obsolete.bumpedfix) |
2059 flag=obsolete.bumpedfix) |
2054 bmupdate(newid) |
2060 bmupdate(newid) |
2055 repo.ui.status(_('committed as %s\n') % node.short(newid)) |
2061 repo.ui.status(_('committed as %s\n') % node.short(newid)) |
|
2062 finally: |
|
2063 pass # TODO: remove this redundant try/finally block |
|
2064 # reroute the working copy parent to the new changeset |
2056 # reroute the working copy parent to the new changeset |
2065 repo.dirstate.beginparentchange() |
2057 repo.dirstate.beginparentchange() |
2066 repo.dirstate.setparents(newid, node.nullid) |
2058 repo.dirstate.setparents(newid, node.nullid) |
2067 repo.dirstate.endparentchange() |
2059 repo.dirstate.endparentchange() |
2068 |
2060 |