mercurial/commands.py
changeset 10384 832f35386067
parent 10379 a78bfaf988e1
child 10389 6dc25b01e170
--- 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)