--- a/hgext/mq.py Thu Jul 27 19:26:01 2006 +0200
+++ b/hgext/mq.py Fri Jul 28 09:01:13 2006 +0200
@@ -187,8 +187,7 @@
return (err, n)
if n is None:
- self.ui.warn("apply failed for patch %s\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("apply failed for patch %s") % patch)
self.ui.warn("patch didn't work out, merging %s\n" % patch)
@@ -199,17 +198,14 @@
c = repo.changelog.read(rev)
ret = repo.update(rev, allow=True, wlock=wlock)
if ret:
- self.ui.warn("update returned %d\n" % ret)
- sys.exit(1)
+ raise util.Abort(_("update returned %d") % ret)
n = repo.commit(None, c[4], c[1], force=1, wlock=wlock)
if n == None:
- self.ui.warn("repo commit failed\n")
- sys.exit(1)
+ raise util.Abort(_("repo commit failed"))
try:
message, comments, user, date, patchfound = mergeq.readheaders(patch)
except:
- self.ui.warn("Unable to read %s\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("unable to read %s") % patch)
patchf = self.opener(patch, "w")
if comments:
@@ -257,7 +253,7 @@
head = self.qparents(repo)
for patch in series:
- patch = mergeq.lookup(patch)
+ patch = mergeq.lookup(patch, strict=True)
if not patch:
self.ui.warn("patch %s does not exist\n" % patch)
return (1, None)
@@ -280,8 +276,6 @@
# TODO unify with commands.py
if not patchdir:
patchdir = self.path
- pwd = os.getcwd()
- os.chdir(repo.root)
err = 0
if not wlock:
wlock = repo.wlock()
@@ -308,7 +302,8 @@
try:
pp = util.find_in_path('gpatch', os.environ.get('PATH', ''), 'patch')
- f = os.popen("%s -p1 --no-backup-if-mismatch < '%s'" % (pp, pf))
+ f = os.popen("%s -d '%s' -p1 --no-backup-if-mismatch < '%s'" %
+ (pp, repo.root, pf))
except:
self.ui.warn("patch failed, unable to continue (try -v)\n")
err = 1
@@ -356,8 +351,7 @@
wlock=wlock)
if n == None:
- self.ui.warn("repo commit failed\n")
- sys.exit(1)
+ raise util.Abort(_("repo commit failed"))
if update_status:
self.applied.append(revlog.hex(n) + ":" + patch)
@@ -376,18 +370,15 @@
err = 1
break
tr.close()
- os.chdir(pwd)
return (err, n)
def delete(self, repo, patch):
- patch = self.lookup(patch)
+ patch = self.lookup(patch, strict=True)
info = self.isapplied(patch)
if info:
- self.ui.warn("cannot delete applied patch %s\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("cannot delete applied patch %s") % patch)
if patch not in self.series:
- self.ui.warn("patch %s not in series file\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("patch %s not in series file") % patch)
i = self.find_series(patch)
del self.full_series[i]
self.read_series(self.full_series)
@@ -399,26 +390,25 @@
top = revlog.bin(top)
pp = repo.dirstate.parents()
if top not in pp:
- self.ui.warn("queue top not at dirstate parents. top %s dirstate %s %s\n" %( revlog.short(top), revlog.short(pp[0]), revlog.short(pp[1])))
- sys.exit(1)
+ raise util.Abort(_("queue top not at same revision as working directory"))
return top
return None
def check_localchanges(self, repo):
(c, a, r, d, u) = repo.changes(None, None)
if c or a or d or r:
- self.ui.write("Local changes found, refresh first\n")
- sys.exit(1)
+ raise util.Abort(_("local changes found, refresh first"))
def new(self, repo, patch, msg=None, force=None):
+ if os.path.exists(os.path.join(self.path, patch)):
+ raise util.Abort(_('patch "%s" already exists') % patch)
commitfiles = []
(c, a, r, d, u) = repo.changes(None, None)
if c or a or d or r:
if not force:
- raise util.Abort(_("Local changes found, refresh first"))
- else:
- commitfiles = c + a + r
+ raise util.Abort(_("local changes found, refresh first"))
+ commitfiles = c + a + r
self.check_toppatch(repo)
wlock = repo.wlock()
- insert = self.series_end()
+ insert = self.full_series_end()
if msg:
n = repo.commit(commitfiles, "[mq]: %s" % msg, force=True,
wlock=wlock)
@@ -426,8 +416,7 @@
n = repo.commit(commitfiles,
"New patch: %s" % patch, force=True, wlock=wlock)
if n == None:
- self.ui.warn("repo commit failed\n")
- sys.exit(1)
+ raise util.Abort(_("repo commit failed"))
self.full_series[insert:insert] = [patch]
self.applied.append(revlog.hex(n) + ":" + patch)
self.read_series(self.full_series)
@@ -442,7 +431,7 @@
r = self.qrepo()
if r: r.add([patch])
if commitfiles:
- self.refresh(repo, short=True)
+ self.refresh(repo, msg=None, short=True)
def strip(self, repo, rev, update=True, backup="all", wlock=None):
def limitheads(chlog, stop):
@@ -530,6 +519,9 @@
revnum = chlog.rev(rev)
if update:
+ (c, a, r, d, u) = repo.changes(None, None)
+ if c or a or d or r:
+ raise util.Abort(_("local changes found"))
urev = self.qparents(repo, rev)
repo.update(urev, allow=False, force=True, wlock=wlock)
repo.dirstate.write()
@@ -598,25 +590,78 @@
return (i, a[0], a[1])
return None
- def lookup(self, patch):
+ # if the exact patch name does not exist, we try a few
+ # variations. If strict is passed, we try only #1
+ #
+ # 1) a number to indicate an offset in the series file
+ # 2) a unique substring of the patch name was given
+ # 3) patchname[-+]num to indicate an offset in the series file
+ def lookup(self, patch, strict=False):
+ def partial_name(s):
+ count = 0
+ if s in self.series:
+ return s
+ for x in self.series:
+ if s in x:
+ count += 1
+ last = x
+ if count > 1:
+ return None
+ if count:
+ return last
+ if len(self.series) > 0 and len(self.applied) > 0:
+ if s == 'qtip':
+ return self.series[self.series_end()-1]
+ if s == 'qbase':
+ return self.series[0]
+ return None
if patch == None:
return None
- if patch in self.series:
- return patch
+
+ # we don't want to return a partial match until we make
+ # sure the file name passed in does not exist (checked below)
+ res = partial_name(patch)
+ if res and res == patch:
+ return res
+
if not os.path.isfile(os.path.join(self.path, patch)):
try:
sno = int(patch)
except(ValueError, OverflowError):
- self.ui.warn("patch %s not in series\n" % patch)
- sys.exit(1)
- if sno >= len(self.series):
- self.ui.warn("patch number %d is out of range\n" % sno)
- sys.exit(1)
- patch = self.series[sno]
- else:
- self.ui.warn("patch %s not in series\n" % patch)
- sys.exit(1)
- return patch
+ pass
+ else:
+ if sno < len(self.series):
+ patch = self.series[sno]
+ return patch
+ if not strict:
+ # return any partial match made above
+ if res:
+ return res
+ minus = patch.rsplit('-', 1)
+ if len(minus) > 1:
+ res = partial_name(minus[0])
+ if res:
+ i = self.series.index(res)
+ try:
+ off = int(minus[1] or 1)
+ except(ValueError, OverflowError):
+ pass
+ else:
+ if i - off >= 0:
+ return self.series[i - off]
+ plus = patch.rsplit('+', 1)
+ if len(plus) > 1:
+ res = partial_name(plus[0])
+ if res:
+ i = self.series.index(res)
+ try:
+ off = int(plus[1] or 1)
+ except(ValueError, OverflowError):
+ pass
+ else:
+ if i + off < len(self.series):
+ return self.series[i + off]
+ raise util.Abort(_("patch %s not in series") % patch)
def push(self, repo, patch=None, force=False, list=False,
mergeq=None, wlock=None):
@@ -624,10 +669,10 @@
wlock = repo.wlock()
patch = self.lookup(patch)
if patch and self.isapplied(patch):
- self.ui.warn("patch %s is already applied\n" % patch)
+ self.ui.warn(_("patch %s is already applied\n") % patch)
sys.exit(1)
if self.series_end() == len(self.series):
- self.ui.warn("File series fully applied\n")
+ self.ui.warn(_("patch series fully applied\n"))
sys.exit(1)
if not force:
self.check_localchanges(repo)
@@ -654,7 +699,8 @@
self.ui.write("Now at: %s\n" % top)
return ret[0]
- def pop(self, repo, patch=None, force=False, update=True, wlock=None):
+ def pop(self, repo, patch=None, force=False, update=True, all=False,
+ wlock=None):
def getfile(f, rev):
t = repo.file(f).read(rev)
try:
@@ -675,10 +721,9 @@
patch = self.lookup(patch)
info = self.isapplied(patch)
if not info:
- self.ui.warn("patch %s is not applied\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("patch %s is not applied") % patch)
if len(self.applied) == 0:
- self.ui.warn("No patches applied\n")
+ self.ui.warn(_("no patches applied\n"))
sys.exit(1)
if not update:
@@ -695,7 +740,17 @@
self.applied_dirty = 1;
end = len(self.applied)
if not patch:
- info = [len(self.applied) - 1] + self.applied[-1].split(':')
+ if all:
+ popi = 0
+ else:
+ popi = len(self.applied) - 1
+ else:
+ popi = info[0] + 1
+ if popi >= end:
+ self.ui.warn("qpop: %s is already at the top\n" % patch)
+ return
+ info = [ popi ] + self.applied[popi].split(':')
+
start = info[0]
rev = revlog.bin(info[1])
@@ -739,7 +794,7 @@
qp = self.qparents(repo, top)
commands.dodiff(sys.stdout, self.ui, repo, qp, None, files)
- def refresh(self, repo, short=False):
+ def refresh(self, repo, msg=None, short=False):
if len(self.applied) == 0:
self.ui.write("No patches applied\n")
return
@@ -822,10 +877,14 @@
repo.dirstate.update(c, 'n')
repo.dirstate.forget(forget)
- if not message:
- message = "patch queue: %s\n" % patch
+ if not msg:
+ if not message:
+ message = "patch queue: %s\n" % patch
+ else:
+ message = "\n".join(message)
else:
- message = "\n".join(message)
+ message = msg
+
self.strip(repo, top, update=False, backup='strip', wlock=wlock)
n = repo.commit(filelist, message, changes[1], force=1, wlock=wlock)
self.applied[-1] = revlog.hex(n) + ':' + patch
@@ -838,15 +897,14 @@
def init(self, repo, create=False):
if os.path.isdir(self.path):
- raise util.Abort("patch queue directory already exists")
+ raise util.Abort(_("patch queue directory already exists"))
os.mkdir(self.path)
if create:
return self.qrepo(create=True)
def unapplied(self, repo, patch=None):
if patch and patch not in self.series:
- self.ui.warn("%s not in the series file\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("patch %s is not in series file") % patch)
if not patch:
start = self.series_end()
else:
@@ -976,6 +1034,15 @@
self.applied.append(revlog.hex(n) + ":" + '.hg.patches.save.line')
self.applied_dirty = 1
+ def full_series_end(self):
+ if len(self.applied) > 0:
+ (top, p) = self.applied[-1].split(':')
+ end = self.find_series(p)
+ if end == None:
+ return len(self.full_series)
+ return end + 1
+ return 0
+
def series_end(self):
end = 0
if len(self.applied) > 0:
@@ -989,8 +1056,7 @@
def qapplied(self, repo, patch=None):
if patch and patch not in self.series:
- self.ui.warn("%s not in the series file\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("patch %s is not in series file") % patch)
if not patch:
end = len(self.applied)
else:
@@ -1036,8 +1102,8 @@
def qimport(self, repo, files, patch=None, existing=None, force=None):
if len(files) > 1 and patch:
- self.ui.warn("-n option not valid when importing multiple files\n")
- sys.exit(1)
+ raise util.Abort(_('option "-n" not valid when importing multiple '
+ 'files'))
i = 0
added = []
for filename in files:
@@ -1045,25 +1111,22 @@
if not patch:
patch = filename
if not os.path.isfile(os.path.join(self.path, patch)):
- self.ui.warn("patch %s does not exist\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("patch %s does not exist") % patch)
else:
try:
text = file(filename).read()
except IOError:
- self.ui.warn("Unable to read %s\n" % patch)
- sys.exit(1)
+ raise util.Abort(_("unable to read %s") % patch)
if not patch:
patch = os.path.split(filename)[1]
- if not force and os.path.isfile(os.path.join(self.path, patch)):
- self.ui.warn("patch %s already exists\n" % patch)
- sys.exit(1)
+ if not force and os.path.exists(os.path.join(self.path, patch)):
+ raise util.Abort(_('patch "%s" already exists') % patch)
patchf = self.opener(patch, "w")
patchf.write(text)
if patch in self.series:
- self.ui.warn("patch %s is already in the series file\n" % patch)
- sys.exit(1)
- index = self.series_end() + i
+ raise util.Abort(_('patch %s is already in the series file')
+ % patch)
+ index = self.full_series_end() + i
self.full_series[index:index] = [patch]
self.read_series(self.full_series)
self.ui.warn("adding %s to series file\n" % patch)
@@ -1144,14 +1207,16 @@
def new(ui, repo, patch, **opts):
"""create a new patch"""
q = repomap[repo]
- q.new(repo, patch, msg=opts['message'], force=opts['force'])
+ message=commands.logmessage(**opts)
+ q.new(repo, patch, msg=message, force=opts['force'])
q.save_dirty()
return 0
def refresh(ui, repo, **opts):
"""update the current patch"""
q = repomap[repo]
- q.refresh(repo, short=opts['short'])
+ message=commands.logmessage(**opts)
+ q.refresh(repo, msg=message, short=opts['short'])
q.save_dirty()
return 0
@@ -1216,9 +1281,7 @@
localupdate = False
else:
q = repomap[repo]
- if opts['all'] and len(q.applied) > 0:
- patch = q.applied[0].split(':')[1]
- q.pop(repo, patch, force=opts['force'], update=localupdate)
+ q.pop(repo, patch, force=opts['force'], update=localupdate, all=opts['all'])
q.save_dirty()
return 0
@@ -1234,7 +1297,8 @@
def save(ui, repo, **opts):
"""save current queue state"""
q = repomap[repo]
- ret = q.save(repo, msg=opts['message'])
+ message=commands.logmessage(**opts)
+ ret = q.save(repo, msg=message)
if ret:
return ret
q.save_dirty()
@@ -1244,13 +1308,11 @@
newpath = os.path.join(q.basepath, opts['name'])
if os.path.exists(newpath):
if not os.path.isdir(newpath):
- ui.warn("destination %s exists and is not a directory\n" %
- newpath)
- sys.exit(1)
+ raise util.Abort(_('destination %s exists and is not '
+ 'a directory') % newpath)
if not opts['force']:
- ui.warn("destination %s exists, use -f to force\n" %
- newpath)
- sys.exit(1)
+ raise util.Abort(_('destination %s exists, '
+ 'use -f to force') % newpath)
else:
newpath = savename(path)
ui.warn("copy %s to %s\n" % (path, newpath))
@@ -1325,9 +1387,10 @@
'hg qinit [-c]'),
"qnew":
(new,
- [('m', 'message', '', 'commit message'),
+ [('m', 'message', '', _('use <text> as commit message')),
+ ('l', 'logfile', '', _('read the commit message from <file>')),
('f', 'force', None, 'force')],
- 'hg qnew [-m TEXT] [-f] PATCH'),
+ 'hg qnew [-m TEXT] [-l FILE] [-f] PATCH'),
"qnext": (next, [], 'hg qnext'),
"qprev": (prev, [], 'hg qprev'),
"^qpop":
@@ -1346,8 +1409,10 @@
'hg qpush [-f] [-l] [-a] [-m] [-n NAME] [PATCH | INDEX]'),
"^qrefresh":
(refresh,
- [('s', 'short', None, 'short refresh')],
- 'hg qrefresh [-s]'),
+ [('m', 'message', '', _('change commit message with <text>')),
+ ('l', 'logfile', '', _('change commit message with <file> content')),
+ ('s', 'short', None, 'short refresh')],
+ 'hg qrefresh [-m TEXT] [-l FILE] [-s]'),
"qrestore":
(restore,
[('d', 'delete', None, 'delete save entry'),
@@ -1355,12 +1420,13 @@
'hg qrestore [-d] [-u] REV'),
"qsave":
(save,
- [('m', 'message', '', 'commit message'),
+ [('m', 'message', '', _('use <text> as commit message')),
+ ('l', 'logfile', '', _('read the commit message from <file>')),
('c', 'copy', None, 'copy patch directory'),
('n', 'name', '', 'copy directory name'),
('e', 'empty', None, 'clear queue status file'),
('f', 'force', None, 'force copy')],
- 'hg qsave [-m TEXT] [-c] [-n NAME] [-e] [-f]'),
+ 'hg qsave [-m TEXT] [-l FILE] [-c] [-n NAME] [-e] [-f]'),
"qseries":
(series,
[('m', 'missing', None, 'print patches not in series')],