mercurial/cmdutil.py
changeset 26587 56b2bcea2529
parent 26579 dc2b8c005697
child 26632 59b5e8844eb0
equal deleted inserted replaced
26586:d51c658d3f04 26587:56b2bcea2529
    83     if not ui.interactive():
    83     if not ui.interactive():
    84         if cmdsuggest:
    84         if cmdsuggest:
    85             msg = _('running non-interactively, use %s instead') % cmdsuggest
    85             msg = _('running non-interactively, use %s instead') % cmdsuggest
    86         else:
    86         else:
    87             msg = _('running non-interactively')
    87             msg = _('running non-interactively')
    88         raise util.Abort(msg)
    88         raise error.Abort(msg)
    89 
    89 
    90     # make sure username is set before going interactive
    90     # make sure username is set before going interactive
    91     if not opts.get('user'):
    91     if not opts.get('user'):
    92         ui.username() # raise exception, username not provided
    92         ui.username() # raise exception, username not provided
    93 
    93 
   107         """
   107         """
   108 
   108 
   109         checkunfinished(repo, commit=True)
   109         checkunfinished(repo, commit=True)
   110         merge = len(repo[None].parents()) > 1
   110         merge = len(repo[None].parents()) > 1
   111         if merge:
   111         if merge:
   112             raise util.Abort(_('cannot partially commit a merge '
   112             raise error.Abort(_('cannot partially commit a merge '
   113                                '(use "hg commit" instead)'))
   113                                '(use "hg commit" instead)'))
   114 
   114 
   115         status = repo.status(match=match)
   115         status = repo.status(match=match)
   116         diffopts = patch.difffeatureopts(ui, opts=opts, whitespace=True)
   116         diffopts = patch.difffeatureopts(ui, opts=opts, whitespace=True)
   117         diffopts.nodates = True
   117         diffopts.nodates = True
   121 
   121 
   122         # 1. filter patch, so we have intending-to apply subset of it
   122         # 1. filter patch, so we have intending-to apply subset of it
   123         try:
   123         try:
   124             chunks = filterfn(ui, originalchunks)
   124             chunks = filterfn(ui, originalchunks)
   125         except patch.PatchError as err:
   125         except patch.PatchError as err:
   126             raise util.Abort(_('error parsing patch: %s') % err)
   126             raise error.Abort(_('error parsing patch: %s') % err)
   127 
   127 
   128         # We need to keep a backup of files that have been newly added and
   128         # We need to keep a backup of files that have been newly added and
   129         # modified during the recording process because there is a previous
   129         # modified during the recording process because there is a previous
   130         # version without the edit in the workdir
   130         # version without the edit in the workdir
   131         newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
   131         newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
   191                 try:
   191                 try:
   192                     ui.debug('applying patch\n')
   192                     ui.debug('applying patch\n')
   193                     ui.debug(fp.getvalue())
   193                     ui.debug(fp.getvalue())
   194                     patch.internalpatch(ui, repo, fp, 1, eolmode=None)
   194                     patch.internalpatch(ui, repo, fp, 1, eolmode=None)
   195                 except patch.PatchError as err:
   195                 except patch.PatchError as err:
   196                     raise util.Abort(str(err))
   196                     raise error.Abort(str(err))
   197             del fp
   197             del fp
   198 
   198 
   199             # 4. We prepared working directory according to filtered
   199             # 4. We prepared working directory according to filtered
   200             #    patch. Now is the time to delegate the job to
   200             #    patch. Now is the time to delegate the job to
   201             #    commit/qrefresh or the like!
   201             #    commit/qrefresh or the like!
   303 
   303 
   304     return p
   304     return p
   305 
   305 
   306 def bailifchanged(repo, merge=True):
   306 def bailifchanged(repo, merge=True):
   307     if merge and repo.dirstate.p2() != nullid:
   307     if merge and repo.dirstate.p2() != nullid:
   308         raise util.Abort(_('outstanding uncommitted merge'))
   308         raise error.Abort(_('outstanding uncommitted merge'))
   309     modified, added, removed, deleted = repo.status()[:4]
   309     modified, added, removed, deleted = repo.status()[:4]
   310     if modified or added or removed or deleted:
   310     if modified or added or removed or deleted:
   311         raise util.Abort(_('uncommitted changes'))
   311         raise error.Abort(_('uncommitted changes'))
   312     ctx = repo[None]
   312     ctx = repo[None]
   313     for s in sorted(ctx.substate):
   313     for s in sorted(ctx.substate):
   314         ctx.sub(s).bailifchanged()
   314         ctx.sub(s).bailifchanged()
   315 
   315 
   316 def logmessage(ui, opts):
   316 def logmessage(ui, opts):
   317     """ get the log message according to -m and -l option """
   317     """ get the log message according to -m and -l option """
   318     message = opts.get('message')
   318     message = opts.get('message')
   319     logfile = opts.get('logfile')
   319     logfile = opts.get('logfile')
   320 
   320 
   321     if message and logfile:
   321     if message and logfile:
   322         raise util.Abort(_('options --message and --logfile are mutually '
   322         raise error.Abort(_('options --message and --logfile are mutually '
   323                            'exclusive'))
   323                            'exclusive'))
   324     if not message and logfile:
   324     if not message and logfile:
   325         try:
   325         try:
   326             if logfile == '-':
   326             if logfile == '-':
   327                 message = ui.fin.read()
   327                 message = ui.fin.read()
   328             else:
   328             else:
   329                 message = '\n'.join(util.readfile(logfile).splitlines())
   329                 message = '\n'.join(util.readfile(logfile).splitlines())
   330         except IOError as inst:
   330         except IOError as inst:
   331             raise util.Abort(_("can't read commit message '%s': %s") %
   331             raise error.Abort(_("can't read commit message '%s': %s") %
   332                              (logfile, inst.strerror))
   332                              (logfile, inst.strerror))
   333     return message
   333     return message
   334 
   334 
   335 def mergeeditform(ctxorbool, baseformname):
   335 def mergeeditform(ctxorbool, baseformname):
   336     """return appropriate editform name (referencing a committemplate)
   336     """return appropriate editform name (referencing a committemplate)
   385     limit = opts.get('limit')
   385     limit = opts.get('limit')
   386     if limit:
   386     if limit:
   387         try:
   387         try:
   388             limit = int(limit)
   388             limit = int(limit)
   389         except ValueError:
   389         except ValueError:
   390             raise util.Abort(_('limit must be a positive integer'))
   390             raise error.Abort(_('limit must be a positive integer'))
   391         if limit <= 0:
   391         if limit <= 0:
   392             raise util.Abort(_('limit must be positive'))
   392             raise error.Abort(_('limit must be positive'))
   393     else:
   393     else:
   394         limit = None
   394         limit = None
   395     return limit
   395     return limit
   396 
   396 
   397 def makefilename(repo, pat, node, desc=None,
   397 def makefilename(repo, pat, node, desc=None,
   435                 c = expander[c]()
   435                 c = expander[c]()
   436             newname.append(c)
   436             newname.append(c)
   437             i += 1
   437             i += 1
   438         return ''.join(newname)
   438         return ''.join(newname)
   439     except KeyError as inst:
   439     except KeyError as inst:
   440         raise util.Abort(_("invalid format spec '%%%s' in output filename") %
   440         raise error.Abort(_("invalid format spec '%%%s' in output filename") %
   441                          inst.args[0])
   441                          inst.args[0])
   442 
   442 
   443 def makefileobj(repo, pat, node=None, desc=None, total=None,
   443 def makefileobj(repo, pat, node=None, desc=None, total=None,
   444                 seqno=None, revwidth=None, mode='wb', modemap=None,
   444                 seqno=None, revwidth=None, mode='wb', modemap=None,
   445                 pathname=None):
   445                 pathname=None):
   493             msg = _('cannot specify filename with --changelog or --manifest')
   493             msg = _('cannot specify filename with --changelog or --manifest')
   494         elif not repo:
   494         elif not repo:
   495             msg = _('cannot specify --changelog or --manifest or --dir '
   495             msg = _('cannot specify --changelog or --manifest or --dir '
   496                     'without a repository')
   496                     'without a repository')
   497     if msg:
   497     if msg:
   498         raise util.Abort(msg)
   498         raise error.Abort(msg)
   499 
   499 
   500     r = None
   500     r = None
   501     if repo:
   501     if repo:
   502         if cl:
   502         if cl:
   503             r = repo.unfiltered().changelog
   503             r = repo.unfiltered().changelog
   504         elif dir:
   504         elif dir:
   505             if 'treemanifest' not in repo.requirements:
   505             if 'treemanifest' not in repo.requirements:
   506                 raise util.Abort(_("--dir can only be used on repos with "
   506                 raise error.Abort(_("--dir can only be used on repos with "
   507                                    "treemanifest enabled"))
   507                                    "treemanifest enabled"))
   508             dirlog = repo.dirlog(file_)
   508             dirlog = repo.dirlog(file_)
   509             if len(dirlog):
   509             if len(dirlog):
   510                 r = dirlog
   510                 r = dirlog
   511         elif mf:
   511         elif mf:
   516                 r = filelog
   516                 r = filelog
   517     if not r:
   517     if not r:
   518         if not file_:
   518         if not file_:
   519             raise error.CommandError(cmd, _('invalid arguments'))
   519             raise error.CommandError(cmd, _('invalid arguments'))
   520         if not os.path.isfile(file_):
   520         if not os.path.isfile(file_):
   521             raise util.Abort(_("revlog '%s' not found") % file_)
   521             raise error.Abort(_("revlog '%s' not found") % file_)
   522         r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
   522         r = revlog.revlog(scmutil.opener(os.getcwd(), audit=False),
   523                           file_[:-2] + ".i")
   523                           file_[:-2] + ".i")
   524     return r
   524     return r
   525 
   525 
   526 def copy(ui, repo, pats, opts, rename=False):
   526 def copy(ui, repo, pats, opts, rename=False):
   714                     res = lambda p: dest
   714                     res = lambda p: dest
   715         return res
   715         return res
   716 
   716 
   717     pats = scmutil.expandpats(pats)
   717     pats = scmutil.expandpats(pats)
   718     if not pats:
   718     if not pats:
   719         raise util.Abort(_('no source or destination specified'))
   719         raise error.Abort(_('no source or destination specified'))
   720     if len(pats) == 1:
   720     if len(pats) == 1:
   721         raise util.Abort(_('no destination specified'))
   721         raise error.Abort(_('no destination specified'))
   722     dest = pats.pop()
   722     dest = pats.pop()
   723     destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
   723     destdirexists = os.path.isdir(dest) and not os.path.islink(dest)
   724     if not destdirexists:
   724     if not destdirexists:
   725         if len(pats) > 1 or matchmod.patkind(pats[0]):
   725         if len(pats) > 1 or matchmod.patkind(pats[0]):
   726             raise util.Abort(_('with multiple sources, destination must be an '
   726             raise error.Abort(_('with multiple sources, destination must be an '
   727                                'existing directory'))
   727                                'existing directory'))
   728         if util.endswithsep(dest):
   728         if util.endswithsep(dest):
   729             raise util.Abort(_('destination %s is not a directory') % dest)
   729             raise error.Abort(_('destination %s is not a directory') % dest)
   730 
   730 
   731     tfn = targetpathfn
   731     tfn = targetpathfn
   732     if after:
   732     if after:
   733         tfn = targetpathafterfn
   733         tfn = targetpathafterfn
   734     copylist = []
   734     copylist = []
   736         srcs = walkpat(pat)
   736         srcs = walkpat(pat)
   737         if not srcs:
   737         if not srcs:
   738             continue
   738             continue
   739         copylist.append((tfn(pat, dest, srcs), srcs))
   739         copylist.append((tfn(pat, dest, srcs), srcs))
   740     if not copylist:
   740     if not copylist:
   741         raise util.Abort(_('no files to copy'))
   741         raise error.Abort(_('no files to copy'))
   742 
   742 
   743     errors = 0
   743     errors = 0
   744     for targetpath, srcs in copylist:
   744     for targetpath, srcs in copylist:
   745         for abssrc, relsrc, exact in srcs:
   745         for abssrc, relsrc, exact in srcs:
   746             if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
   746             if copyfile(abssrc, relsrc, targetpath(abssrc), exact):
   784                     break
   784                     break
   785             def condfn():
   785             def condfn():
   786                 return not os.path.exists(lockpath)
   786                 return not os.path.exists(lockpath)
   787             pid = util.rundetached(runargs, condfn)
   787             pid = util.rundetached(runargs, condfn)
   788             if pid < 0:
   788             if pid < 0:
   789                 raise util.Abort(_('child process failed to start'))
   789                 raise error.Abort(_('child process failed to start'))
   790             writepid(pid)
   790             writepid(pid)
   791         finally:
   791         finally:
   792             try:
   792             try:
   793                 os.unlink(lockpath)
   793                 os.unlink(lockpath)
   794             except OSError as e:
   794             except OSError as e:
   906 
   906 
   907         if len(parents) == 1:
   907         if len(parents) == 1:
   908             parents.append(repo[nullid])
   908             parents.append(repo[nullid])
   909         if opts.get('exact'):
   909         if opts.get('exact'):
   910             if not nodeid or not p1:
   910             if not nodeid or not p1:
   911                 raise util.Abort(_('not a Mercurial patch'))
   911                 raise error.Abort(_('not a Mercurial patch'))
   912             p1 = repo[p1]
   912             p1 = repo[p1]
   913             p2 = repo[p2 or nullid]
   913             p2 = repo[p2 or nullid]
   914         elif p2:
   914         elif p2:
   915             try:
   915             try:
   916                 p1 = repo[p1]
   916                 p1 = repo[p1]
   944             try:
   944             try:
   945                 patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
   945                 patch.patch(ui, repo, tmpname, strip=strip, prefix=prefix,
   946                             files=files, eolmode=None, similarity=sim / 100.0)
   946                             files=files, eolmode=None, similarity=sim / 100.0)
   947             except patch.PatchError as e:
   947             except patch.PatchError as e:
   948                 if not partial:
   948                 if not partial:
   949                     raise util.Abort(str(e))
   949                     raise error.Abort(str(e))
   950                 if partial:
   950                 if partial:
   951                     rejects = True
   951                     rejects = True
   952 
   952 
   953             files = list(files)
   953             files = list(files)
   954             if opts.get('no_commit'):
   954             if opts.get('no_commit'):
   991                 files = set()
   991                 files = set()
   992                 try:
   992                 try:
   993                     patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
   993                     patch.patchrepo(ui, repo, p1, store, tmpname, strip, prefix,
   994                                     files, eolmode=None)
   994                                     files, eolmode=None)
   995                 except patch.PatchError as e:
   995                 except patch.PatchError as e:
   996                     raise util.Abort(str(e))
   996                     raise error.Abort(str(e))
   997                 if opts.get('exact'):
   997                 if opts.get('exact'):
   998                     editor = None
   998                     editor = None
   999                 else:
   999                 else:
  1000                     editor = getcommiteditor(editform='import.bypass')
  1000                     editor = getcommiteditor(editform='import.bypass')
  1001                 memctx = context.makememctx(repo, (p1.node(), p2.node()),
  1001                 memctx = context.makememctx(repo, (p1.node(), p2.node()),
  1010         if opts.get('exact') and opts.get('no_commit'):
  1010         if opts.get('exact') and opts.get('no_commit'):
  1011             # --exact with --no-commit is still useful in that it does merge
  1011             # --exact with --no-commit is still useful in that it does merge
  1012             # and branch bits
  1012             # and branch bits
  1013             ui.warn(_("warning: can't check exact import with --no-commit\n"))
  1013             ui.warn(_("warning: can't check exact import with --no-commit\n"))
  1014         elif opts.get('exact') and hex(n) != nodeid:
  1014         elif opts.get('exact') and hex(n) != nodeid:
  1015             raise util.Abort(_('patch is damaged or loses information'))
  1015             raise error.Abort(_('patch is damaged or loses information'))
  1016         if n:
  1016         if n:
  1017             # i18n: refers to a short changeset id
  1017             # i18n: refers to a short changeset id
  1018             msg = _('created %s') % short(n)
  1018             msg = _('created %s') % short(n)
  1019         return (msg, n, rejects)
  1019         return (msg, n, rejects)
  1020     finally:
  1020     finally:
  1498                 if not self.footer:
  1498                 if not self.footer:
  1499                     self.footer = templater.stringify(
  1499                     self.footer = templater.stringify(
  1500                         self.t(self._parts['footer'], **props))
  1500                         self.t(self._parts['footer'], **props))
  1501         except KeyError as inst:
  1501         except KeyError as inst:
  1502             msg = _("%s: no key named '%s'")
  1502             msg = _("%s: no key named '%s'")
  1503             raise util.Abort(msg % (self.t.mapfile, inst.args[0]))
  1503             raise error.Abort(msg % (self.t.mapfile, inst.args[0]))
  1504         except SyntaxError as inst:
  1504         except SyntaxError as inst:
  1505             raise util.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
  1505             raise error.Abort('%s: %s' % (self.t.mapfile, inst.args[0]))
  1506 
  1506 
  1507 def gettemplate(ui, tmpl, style):
  1507 def gettemplate(ui, tmpl, style):
  1508     """
  1508     """
  1509     Find the template matching the given template spec or style.
  1509     Find the template matching the given template spec or style.
  1510     """
  1510     """
  1561 
  1561 
  1562     try:
  1562     try:
  1563         t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
  1563         t = changeset_templater(ui, repo, matchfn, opts, tmpl, mapfile,
  1564                                 buffered)
  1564                                 buffered)
  1565     except SyntaxError as inst:
  1565     except SyntaxError as inst:
  1566         raise util.Abort(inst.args[0])
  1566         raise error.Abort(inst.args[0])
  1567     return t
  1567     return t
  1568 
  1568 
  1569 def showmarker(ui, marker):
  1569 def showmarker(ui, marker):
  1570     """utility function to display obsolescence marker in a readable way
  1570     """utility function to display obsolescence marker in a readable way
  1571 
  1571 
  1601         if rev in results:
  1601         if rev in results:
  1602             ui.status(_("found revision %s from %s\n") %
  1602             ui.status(_("found revision %s from %s\n") %
  1603                       (rev, util.datestr(results[rev])))
  1603                       (rev, util.datestr(results[rev])))
  1604             return str(rev)
  1604             return str(rev)
  1605 
  1605 
  1606     raise util.Abort(_("revision matching date not found"))
  1606     raise error.Abort(_("revision matching date not found"))
  1607 
  1607 
  1608 def increasingwindows(windowsize=8, sizelimit=512):
  1608 def increasingwindows(windowsize=8, sizelimit=512):
  1609     while True:
  1609     while True:
  1610         yield windowsize
  1610         yield windowsize
  1611         if windowsize < sizelimit:
  1611         if windowsize < sizelimit:
  1656     def iterfiles():
  1656     def iterfiles():
  1657         pctx = repo['.']
  1657         pctx = repo['.']
  1658         for filename in match.files():
  1658         for filename in match.files():
  1659             if follow:
  1659             if follow:
  1660                 if filename not in pctx:
  1660                 if filename not in pctx:
  1661                     raise util.Abort(_('cannot follow file not in parent '
  1661                     raise error.Abort(_('cannot follow file not in parent '
  1662                                        'revision: "%s"') % filename)
  1662                                        'revision: "%s"') % filename)
  1663                 yield filename, pctx[filename].filenode()
  1663                 yield filename, pctx[filename].filenode()
  1664             else:
  1664             else:
  1665                 yield filename, None
  1665                 yield filename, None
  1666         for filename_node in copies:
  1666         for filename_node in copies:
  1671         if not len(filelog):
  1671         if not len(filelog):
  1672             if node is None:
  1672             if node is None:
  1673                 # A zero count may be a directory or deleted file, so
  1673                 # A zero count may be a directory or deleted file, so
  1674                 # try to find matching entries on the slow path.
  1674                 # try to find matching entries on the slow path.
  1675                 if follow:
  1675                 if follow:
  1676                     raise util.Abort(
  1676                     raise error.Abort(
  1677                         _('cannot follow nonexistent file: "%s"') % file_)
  1677                         _('cannot follow nonexistent file: "%s"') % file_)
  1678                 raise FileWalkError("Cannot walk via filelog")
  1678                 raise FileWalkError("Cannot walk via filelog")
  1679             else:
  1679             else:
  1680                 continue
  1680                 continue
  1681 
  1681 
  1802     if slowpath:
  1802     if slowpath:
  1803         # We have to read the changelog to match filenames against
  1803         # We have to read the changelog to match filenames against
  1804         # changed files
  1804         # changed files
  1805 
  1805 
  1806         if follow:
  1806         if follow:
  1807             raise util.Abort(_('can only follow copies/renames for explicit '
  1807             raise error.Abort(_('can only follow copies/renames for explicit '
  1808                                'filenames'))
  1808                                'filenames'))
  1809 
  1809 
  1810         # The slow path checks files modified in every changeset.
  1810         # The slow path checks files modified in every changeset.
  1811         # This is really slow on large repos, so compute the set lazily.
  1811         # This is really slow on large repos, so compute the set lazily.
  1812         class lazywantedset(object):
  1812         class lazywantedset(object):
  1974                 # take the slow path.
  1974                 # take the slow path.
  1975                 if os.path.exists(repo.wjoin(f)):
  1975                 if os.path.exists(repo.wjoin(f)):
  1976                     slowpath = True
  1976                     slowpath = True
  1977                     continue
  1977                     continue
  1978                 else:
  1978                 else:
  1979                     raise util.Abort(_('cannot follow file not in parent '
  1979                     raise error.Abort(_('cannot follow file not in parent '
  1980                                        'revision: "%s"') % f)
  1980                                        'revision: "%s"') % f)
  1981             filelog = repo.file(f)
  1981             filelog = repo.file(f)
  1982             if not filelog:
  1982             if not filelog:
  1983                 # A zero count may be a directory or deleted file, so
  1983                 # A zero count may be a directory or deleted file, so
  1984                 # try to find matching entries on the slow path.
  1984                 # try to find matching entries on the slow path.
  1985                 if follow:
  1985                 if follow:
  1986                     raise util.Abort(
  1986                     raise error.Abort(
  1987                         _('cannot follow nonexistent file: "%s"') % f)
  1987                         _('cannot follow nonexistent file: "%s"') % f)
  1988                 slowpath = True
  1988                 slowpath = True
  1989 
  1989 
  1990         # We decided to fall back to the slowpath because at least one
  1990         # We decided to fall back to the slowpath because at least one
  1991         # of the paths was not a file. Check to see if at least one of them
  1991         # of the paths was not a file. Check to see if at least one of them
  2205                  graphmod.asciiedges, getrenamed, filematcher)
  2205                  graphmod.asciiedges, getrenamed, filematcher)
  2206 
  2206 
  2207 def checkunsupportedgraphflags(pats, opts):
  2207 def checkunsupportedgraphflags(pats, opts):
  2208     for op in ["newest_first"]:
  2208     for op in ["newest_first"]:
  2209         if op in opts and opts[op]:
  2209         if op in opts and opts[op]:
  2210             raise util.Abort(_("-G/--graph option is incompatible with --%s")
  2210             raise error.Abort(_("-G/--graph option is incompatible with --%s")
  2211                              % op.replace("_", "-"))
  2211                              % op.replace("_", "-"))
  2212 
  2212 
  2213 def graphrevs(repo, nodes, opts):
  2213 def graphrevs(repo, nodes, opts):
  2214     limit = loglimit(opts)
  2214     limit = loglimit(opts)
  2215     nodes.reverse()
  2215     nodes.reverse()
  2483 
  2483 
  2484     # extract addremove carefully -- this function can be called from a command
  2484     # extract addremove carefully -- this function can be called from a command
  2485     # that doesn't support addremove
  2485     # that doesn't support addremove
  2486     if opts.get('addremove'):
  2486     if opts.get('addremove'):
  2487         if scmutil.addremove(repo, matcher, "", opts) != 0:
  2487         if scmutil.addremove(repo, matcher, "", opts) != 0:
  2488             raise util.Abort(
  2488             raise error.Abort(
  2489                 _("failed to mark all new/missing files as added/removed"))
  2489                 _("failed to mark all new/missing files as added/removed"))
  2490 
  2490 
  2491     return commitfunc(ui, repo, message, matcher, opts)
  2491     return commitfunc(ui, repo, message, matcher, opts)
  2492 
  2492 
  2493 def amend(ui, repo, commitfunc, old, extra, pats, opts):
  2493 def amend(ui, repo, commitfunc, old, extra, pats, opts):
  2717     os.chdir(olddir)
  2717     os.chdir(olddir)
  2718 
  2718 
  2719     if finishdesc:
  2719     if finishdesc:
  2720         text = finishdesc(text)
  2720         text = finishdesc(text)
  2721     if not text.strip():
  2721     if not text.strip():
  2722         raise util.Abort(_("empty commit message"))
  2722         raise error.Abort(_("empty commit message"))
  2723 
  2723 
  2724     return text
  2724     return text
  2725 
  2725 
  2726 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
  2726 def buildcommittemplate(repo, ctx, subs, extramsg, tmpl):
  2727     ui = repo.ui
  2727     ui = repo.ui
  2728     tmpl, mapfile = gettemplate(ui, tmpl, None)
  2728     tmpl, mapfile = gettemplate(ui, tmpl, None)
  2729 
  2729 
  2730     try:
  2730     try:
  2731         t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
  2731         t = changeset_templater(ui, repo, None, {}, tmpl, mapfile, False)
  2732     except SyntaxError as inst:
  2732     except SyntaxError as inst:
  2733         raise util.Abort(inst.args[0])
  2733         raise error.Abort(inst.args[0])
  2734 
  2734 
  2735     for k, v in repo.ui.configitems('committemplate'):
  2735     for k, v in repo.ui.configitems('committemplate'):
  2736         if k != 'changeset':
  2736         if k != 'changeset':
  2737             t.t.cache[k] = v
  2737             t.t.cache[k] = v
  2738 
  2738 
  3095             # Revert the subrepos on the revert list
  3095             # Revert the subrepos on the revert list
  3096             for sub in targetsubs:
  3096             for sub in targetsubs:
  3097                 try:
  3097                 try:
  3098                     wctx.sub(sub).revert(ctx.substate[sub], *pats, **opts)
  3098                     wctx.sub(sub).revert(ctx.substate[sub], *pats, **opts)
  3099                 except KeyError:
  3099                 except KeyError:
  3100                     raise util.Abort("subrepository '%s' does not exist in %s!"
  3100                     raise error.Abort("subrepository '%s' does not exist in %s!"
  3101                                       % (sub, short(ctx.node())))
  3101                                       % (sub, short(ctx.node())))
  3102     finally:
  3102     finally:
  3103         wlock.release()
  3103         wlock.release()
  3104 
  3104 
  3105 def _revertprefetch(repo, ctx, *files):
  3105 def _revertprefetch(repo, ctx, *files):
  3166             chunks = recordfilter(repo.ui, originalchunks)
  3166             chunks = recordfilter(repo.ui, originalchunks)
  3167             if reversehunks:
  3167             if reversehunks:
  3168                 chunks = patch.reversehunks(chunks)
  3168                 chunks = patch.reversehunks(chunks)
  3169 
  3169 
  3170         except patch.PatchError as err:
  3170         except patch.PatchError as err:
  3171             raise util.Abort(_('error parsing patch: %s') % err)
  3171             raise error.Abort(_('error parsing patch: %s') % err)
  3172 
  3172 
  3173         newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
  3173         newlyaddedandmodifiedfiles = newandmodified(chunks, originalchunks)
  3174         # Apply changes
  3174         # Apply changes
  3175         fp = cStringIO.StringIO()
  3175         fp = cStringIO.StringIO()
  3176         for c in chunks:
  3176         for c in chunks:
  3179         fp.seek(0)
  3179         fp.seek(0)
  3180         if dopatch:
  3180         if dopatch:
  3181             try:
  3181             try:
  3182                 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
  3182                 patch.internalpatch(repo.ui, repo, fp, 1, eolmode=None)
  3183             except patch.PatchError as err:
  3183             except patch.PatchError as err:
  3184                 raise util.Abort(str(err))
  3184                 raise error.Abort(str(err))
  3185         del fp
  3185         del fp
  3186     else:
  3186     else:
  3187         for f in actions['revert'][0]:
  3187         for f in actions['revert'][0]:
  3188             checkout(f)
  3188             checkout(f)
  3189             if normal:
  3189             if normal:
  3300     '''
  3300     '''
  3301     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3301     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3302         if commit and allowcommit:
  3302         if commit and allowcommit:
  3303             continue
  3303             continue
  3304         if repo.vfs.exists(f):
  3304         if repo.vfs.exists(f):
  3305             raise util.Abort(msg, hint=hint)
  3305             raise error.Abort(msg, hint=hint)
  3306 
  3306 
  3307 def clearunfinished(repo):
  3307 def clearunfinished(repo):
  3308     '''Check for unfinished operations (as above), and clear the ones
  3308     '''Check for unfinished operations (as above), and clear the ones
  3309     that are clearable.
  3309     that are clearable.
  3310     '''
  3310     '''
  3311     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3311     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3312         if not clearable and repo.vfs.exists(f):
  3312         if not clearable and repo.vfs.exists(f):
  3313             raise util.Abort(msg, hint=hint)
  3313             raise error.Abort(msg, hint=hint)
  3314     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3314     for f, clearable, allowcommit, msg, hint in unfinishedstates:
  3315         if clearable and repo.vfs.exists(f):
  3315         if clearable and repo.vfs.exists(f):
  3316             util.unlink(repo.join(f))
  3316             util.unlink(repo.join(f))
  3317 
  3317 
  3318 class dirstateguard(object):
  3318 class dirstateguard(object):
  3347 
  3347 
  3348     def close(self):
  3348     def close(self):
  3349         if not self._active: # already inactivated
  3349         if not self._active: # already inactivated
  3350             msg = (_("can't close already inactivated backup: %s")
  3350             msg = (_("can't close already inactivated backup: %s")
  3351                    % self._filename)
  3351                    % self._filename)
  3352             raise util.Abort(msg)
  3352             raise error.Abort(msg)
  3353 
  3353 
  3354         self._repo.vfs.unlink(self._filename)
  3354         self._repo.vfs.unlink(self._filename)
  3355         self._active = False
  3355         self._active = False
  3356         self._closed = True
  3356         self._closed = True
  3357 
  3357 
  3366     def release(self):
  3366     def release(self):
  3367         if not self._closed:
  3367         if not self._closed:
  3368             if not self._active: # already inactivated
  3368             if not self._active: # already inactivated
  3369                 msg = (_("can't release already inactivated backup: %s")
  3369                 msg = (_("can't release already inactivated backup: %s")
  3370                        % self._filename)
  3370                        % self._filename)
  3371                 raise util.Abort(msg)
  3371                 raise error.Abort(msg)
  3372             self._abort()
  3372             self._abort()
  3373 
  3373 
  3374 _bundlecompspecs = {'none': None,
  3374 _bundlecompspecs = {'none': None,
  3375                     'bzip2': 'BZ',
  3375                     'bzip2': 'BZ',
  3376                     'gzip': 'GZ',
  3376                     'gzip': 'GZ',
  3400     elif spec in _bundlecompspecs:
  3400     elif spec in _bundlecompspecs:
  3401         comp = spec
  3401         comp = spec
  3402     elif spec in _bundleversionspecs:
  3402     elif spec in _bundleversionspecs:
  3403         version = spec
  3403         version = spec
  3404     else:
  3404     else:
  3405         raise util.Abort(_('unknown bundle type specified with --type'))
  3405         raise error.Abort(_('unknown bundle type specified with --type'))
  3406 
  3406 
  3407     if comp is None:
  3407     if comp is None:
  3408         comp = 'BZ'
  3408         comp = 'BZ'
  3409     else:
  3409     else:
  3410         try:
  3410         try:
  3411             comp = _bundlecompspecs[comp]
  3411             comp = _bundlecompspecs[comp]
  3412         except KeyError:
  3412         except KeyError:
  3413             raise util.Abort(_('unknown bundle type specified with --type'))
  3413             raise error.Abort(_('unknown bundle type specified with --type'))
  3414 
  3414 
  3415     if version is None:
  3415     if version is None:
  3416         version = '01'
  3416         version = '01'
  3417         if 'generaldelta' in repo.requirements:
  3417         if 'generaldelta' in repo.requirements:
  3418             version = '02'
  3418             version = '02'
  3419     else:
  3419     else:
  3420         try:
  3420         try:
  3421             version = _bundleversionspecs[version]
  3421             version = _bundleversionspecs[version]
  3422         except KeyError:
  3422         except KeyError:
  3423             raise util.Abort(_('unknown bundle type specified with --type'))
  3423             raise error.Abort(_('unknown bundle type specified with --type'))
  3424 
  3424 
  3425     return version, comp
  3425     return version, comp