--- a/mercurial/commands.py Sun Feb 07 16:44:55 2010 +0100
+++ b/mercurial/commands.py Sun Feb 07 18:06:52 2010 +0100
@@ -1833,9 +1833,82 @@
d = opts["base"]
strip = opts["strip"]
wlock = lock = None
+
+ def tryone(ui, hunk):
+ tmpname, message, user, date, branch, nodeid, p1, p2 = patch.extract(ui, hunk)
+
+ if not tmpname:
+ return None
+ commitid = _('to working directory')
+
+ try:
+ cmdline_message = cmdutil.logmessage(opts)
+ if cmdline_message:
+ # pickup the cmdline msg
+ message = cmdline_message
+ elif message:
+ # pickup the patch msg
+ message = message.strip()
+ else:
+ # launch the editor
+ message = None
+ ui.debug('message:\n%s\n' % message)
+
+ wp = repo.parents()
+ if opts.get('exact'):
+ if not nodeid or not p1:
+ raise util.Abort(_('not a Mercurial patch'))
+ p1 = repo.lookup(p1)
+ p2 = repo.lookup(p2 or hex(nullid))
+
+ if p1 != wp[0].node():
+ hg.clean(repo, p1)
+ repo.dirstate.setparents(p1, p2)
+ elif p2:
+ try:
+ p1 = repo.lookup(p1)
+ p2 = repo.lookup(p2)
+ if p1 == wp[0].node():
+ repo.dirstate.setparents(p1, p2)
+ except error.RepoError:
+ pass
+ if opts.get('exact') or opts.get('import_branch'):
+ repo.dirstate.setbranch(branch or 'default')
+
+ files = {}
+ try:
+ patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
+ files=files, eolmode=None)
+ finally:
+ files = patch.updatedir(ui, repo, files,
+ similarity=sim / 100.0)
+ if not opts.get('no_commit'):
+ if opts.get('exact'):
+ m = None
+ else:
+ m = cmdutil.matchfiles(repo, files or [])
+ n = repo.commit(message, opts.get('user') or user,
+ opts.get('date') or date, match=m,
+ editor=cmdutil.commiteditor)
+ if opts.get('exact'):
+ if hex(n) != nodeid:
+ repo.rollback()
+ raise util.Abort(_('patch is damaged'
+ ' or loses information'))
+ # Force a dirstate write so that the next transaction
+ # backups an up-do-date file.
+ repo.dirstate.write()
+ if n:
+ commitid = short(n)
+
+ return commitid
+ finally:
+ os.unlink(tmpname)
+
try:
wlock = repo.wlock()
lock = repo.lock()
+ lastcommit = None
for p in patches:
pf = os.path.join(d, p)
@@ -1845,68 +1918,19 @@
else:
ui.status(_("applying %s\n") % p)
pf = url.open(ui, pf)
- data = patch.extract(ui, pf)
- tmpname, message, user, date, branch, nodeid, p1, p2 = data
-
- if tmpname is None:
+
+ haspatch = False
+ for hunk in patch.split(pf):
+ commitid = tryone(ui, hunk)
+ if commitid:
+ haspatch = True
+ if lastcommit:
+ ui.status(_('applied %s\n') % lastcommit)
+ lastcommit = commitid
+
+ if not haspatch:
raise util.Abort(_('no diffs found'))
- try:
- cmdline_message = cmdutil.logmessage(opts)
- if cmdline_message:
- # pickup the cmdline msg
- message = cmdline_message
- elif message:
- # pickup the patch msg
- message = message.strip()
- else:
- # launch the editor
- message = None
- ui.debug('message:\n%s\n' % message)
-
- wp = repo.parents()
- if opts.get('exact'):
- if not nodeid or not p1:
- raise util.Abort(_('not a Mercurial patch'))
- p1 = repo.lookup(p1)
- p2 = repo.lookup(p2 or hex(nullid))
-
- if p1 != wp[0].node():
- hg.clean(repo, p1)
- repo.dirstate.setparents(p1, p2)
- elif p2:
- try:
- p1 = repo.lookup(p1)
- p2 = repo.lookup(p2)
- if p1 == wp[0].node():
- repo.dirstate.setparents(p1, p2)
- except error.RepoError:
- pass
- if opts.get('exact') or opts.get('import_branch'):
- repo.dirstate.setbranch(branch or 'default')
-
- files = {}
- try:
- patch.patch(tmpname, ui, strip=strip, cwd=repo.root,
- files=files, eolmode=None)
- finally:
- files = patch.updatedir(ui, repo, files,
- similarity=sim / 100.0)
- if not opts.get('no_commit'):
- m = cmdutil.matchfiles(repo, files or [])
- n = repo.commit(message, opts.get('user') or user,
- opts.get('date') or date, match=m,
- editor=cmdutil.commiteditor)
- if opts.get('exact'):
- if hex(n) != nodeid:
- repo.rollback()
- raise util.Abort(_('patch is damaged'
- ' or loses information'))
- # Force a dirstate write so that the next transaction
- # backups an up-do-date file.
- repo.dirstate.write()
- finally:
- os.unlink(tmpname)
finally:
release(lock, wlock)