--- a/mercurial/commands.py Sat Aug 12 15:01:46 2006 -0700
+++ b/mercurial/commands.py Sat Aug 12 15:43:38 2006 -0700
@@ -1,6 +1,6 @@
# commands.py - command processing for mercurial
#
-# Copyright 2005 Matt Mackall <mpm@selenic.com>
+# Copyright 2005, 2006 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
@@ -10,9 +10,9 @@
from i18n import gettext as _
demandload(globals(), "os re sys signal shutil imp urllib pdb")
demandload(globals(), "fancyopts ui hg util lock revlog templater bundlerepo")
-demandload(globals(), "fnmatch mdiff difflib random signal tempfile time")
+demandload(globals(), "fnmatch mdiff difflib patch random signal tempfile time")
demandload(globals(), "traceback errno socket version struct atexit sets bz2")
-demandload(globals(), "archival cStringIO changegroup email.Parser")
+demandload(globals(), "archival cStringIO changegroup")
demandload(globals(), "hgweb.server sshserver")
class UnknownCommand(Exception):
@@ -633,7 +633,7 @@
ui.write(_("Mercurial Distributed SCM (version %s)\n")
% version.get_version())
ui.status(_(
- "\nCopyright (C) 2005 Matt Mackall <mpm@selenic.com>\n"
+ "\nCopyright (C) 2005, 2006 Matt Mackall <mpm@selenic.com>\n"
"This is free software; see the source for copying conditions. "
"There is NO\nwarranty; "
"not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
@@ -1333,9 +1333,9 @@
rev = repo.lookup(rev)
change = repo.changelog.read(rev)
n = change[0]
- files = repo.manifest.readflags(n)
+ files = repo.manifest.read(n)
wlock = repo.wlock()
- repo.dirstate.rebuild(rev, files.iteritems())
+ repo.dirstate.rebuild(rev, files)
def debugcheckstate(ui, repo):
"""validate the correctness of the current dirstate"""
@@ -1843,84 +1843,23 @@
d = opts["base"]
strip = opts["strip"]
- mailre = re.compile(r'(?:From |[\w-]+:)')
-
- # attempt to detect the start of a patch
- # (this heuristic is borrowed from quilt)
- diffre = re.compile(r'^(?:Index:[ \t]|diff[ \t]|RCS file: |' +
- 'retrieving revision [0-9]+(\.[0-9]+)*$|' +
- '(---|\*\*\*)[ \t])', re.MULTILINE)
-
wlock = repo.wlock()
lock = repo.lock()
- for patch in patches:
- pf = os.path.join(d, patch)
-
- message = None
- user = None
- date = None
- hgpatch = False
-
- p = email.Parser.Parser()
+ for p in patches:
+ pf = os.path.join(d, p)
+
if pf == '-':
- msg = p.parse(sys.stdin)
ui.status(_("applying patch from stdin\n"))
+ tmpname, message, user, date = patch.extract(ui, sys.stdin)
else:
- msg = p.parse(file(pf))
- ui.status(_("applying %s\n") % patch)
-
- fd, tmpname = tempfile.mkstemp(prefix='hg-patch-')
- tmpfp = os.fdopen(fd, 'w')
+ ui.status(_("applying %s\n") % p)
+ tmpname, message, user, date = patch.extract(ui, file(pf))
+
+ if tmpname is None:
+ raise util.Abort(_('no diffs found'))
+
try:
- message = msg['Subject']
- if message:
- message = message.replace('\n\t', ' ')
- ui.debug('Subject: %s\n' % message)
- user = msg['From']
- if user:
- ui.debug('From: %s\n' % user)
- diffs_seen = 0
- ok_types = ('text/plain', 'text/x-diff', 'text/x-patch')
- for part in msg.walk():
- content_type = part.get_content_type()
- ui.debug('Content-Type: %s\n' % content_type)
- if content_type not in ok_types:
- continue
- payload = part.get_payload(decode=True)
- m = diffre.search(payload)
- if m:
- ui.debug(_('found patch at byte %d\n') % m.start(0))
- diffs_seen += 1
- hgpatch = False
- fp = cStringIO.StringIO()
- if message:
- fp.write(message)
- fp.write('\n')
- for line in payload[:m.start(0)].splitlines():
- if line.startswith('# HG changeset patch'):
- ui.debug(_('patch generated by hg export\n'))
- hgpatch = True
- # drop earlier commit message content
- fp.seek(0)
- fp.truncate()
- elif hgpatch:
- if line.startswith('# User '):
- user = line[7:]
- ui.debug('From: %s\n' % user)
- elif line.startswith("# Date "):
- date = line[7:]
- if not line.startswith('# '):
- fp.write(line)
- fp.write('\n')
- message = fp.getvalue()
- if tmpfp:
- tmpfp.write(payload)
- if not payload.endswith('\n'):
- tmpfp.write('\n')
- elif not diffs_seen and message and content_type == 'text/plain':
- message += '\n' + payload
-
if opts['message']:
# pickup the cmdline msg
message = opts['message']
@@ -1932,17 +1871,45 @@
message = None
ui.debug(_('message:\n%s\n') % message)
- tmpfp.close()
- if not diffs_seen:
- raise util.Abort(_('no diffs found'))
-
- files = util.patch(strip, tmpname, ui, cwd=repo.root)
+ files = patch.patch(strip, tmpname, ui, cwd=repo.root)
+ removes = []
if len(files) > 0:
- cfiles = files
+ cfiles = files.keys()
+ copies = []
+ copts = {'after': False, 'force': False}
cwd = repo.getcwd()
if cwd:
- cfiles = [util.pathto(cwd, f) for f in files]
+ cfiles = [util.pathto(cwd, f) for f in files.keys()]
+ for f in files:
+ ctype, gp = files[f]
+ if ctype == 'RENAME':
+ copies.append((gp.oldpath, gp.path, gp.copymod))
+ removes.append(gp.oldpath)
+ elif ctype == 'COPY':
+ copies.append((gp.oldpath, gp.path, gp.copymod))
+ elif ctype == 'DELETE':
+ removes.append(gp.path)
+ for src, dst, after in copies:
+ absdst = os.path.join(repo.root, dst)
+ if not after and os.path.exists(absdst):
+ raise util.Abort(_('patch creates existing file %s') % dst)
+ if cwd:
+ src, dst = [util.pathto(cwd, f) for f in (src, dst)]
+ copts['after'] = after
+ errs, copied = docopy(ui, repo, (src, dst), copts, wlock=wlock)
+ if errs:
+ raise util.Abort(errs)
+ if removes:
+ repo.remove(removes, True, wlock=wlock)
+ for f in files:
+ ctype, gp = files[f]
+ if gp and gp.mode:
+ x = gp.mode & 0100 != 0
+ dst = os.path.join(repo.root, gp.path)
+ util.set_exec(dst, x)
addremove_lock(ui, repo, cfiles, {}, wlock=wlock)
+ files = files.keys()
+ files.extend([r for r in removes if r not in files])
repo.commit(files, message, user, date, wlock=wlock, lock=lock)
finally:
os.unlink(tmpname)
@@ -2178,12 +2145,12 @@
else:
n = repo.manifest.tip()
m = repo.manifest.read(n)
- mf = repo.manifest.readflags(n)
files = m.keys()
files.sort()
for f in files:
- ui.write("%40s %3s %s\n" % (hex(m[f]), mf[f] and "755" or "644", f))
+ ui.write("%40s %3s %s\n" % (hex(m[f]),
+ m.execf(f) and "755" or "644", f))
def merge(ui, repo, node=None, force=None, branch=None):
"""Merge working directory with another revision