Patchwork transplant: properly skip empty changeset (issue4423)

login
register
mail settings
Submitter Pierre-Yves David
Date Jan. 9, 2015, 5:55 a.m.
Message ID <85766f010b8a1d93d13b.1420782941@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/7400/
State Accepted
Headers show

Comments

Pierre-Yves David - Jan. 9, 2015, 5:55 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1420781772 28800
#      Thu Jan 08 21:36:12 2015 -0800
# Node ID 85766f010b8a1d93d13babc6f4dbb3d031eb4f84
# Parent  bb3ee61cfaa1d3f085c7577f48f566a0f31a6985
transplant: properly skip empty changeset (issue4423)

If resolving a merge conflict result in an empty changesets, we now properly
skip the changeset instead of crashing.

Original patch from Robert Collins <robertc@robertcollins.net>.
Augie Fackler - Jan. 9, 2015, 3:08 p.m.
On Thu, Jan 08, 2015 at 09:55:41PM -0800, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1420781772 28800
> #      Thu Jan 08 21:36:12 2015 -0800
> # Node ID 85766f010b8a1d93d13babc6f4dbb3d031eb4f84
> # Parent  bb3ee61cfaa1d3f085c7577f48f566a0f31a6985
> transplant: properly skip empty changeset (issue4423)

Queued this, thanks.

Many thanks for picking this up and finishing it off - I kept meaning
to but never got the round tuits.

>
> If resolving a merge conflict result in an empty changesets, we now properly
> skip the changeset instead of crashing.
>
> Original patch from Robert Collins <robertc@robertcollins.net>.
>
> diff --git a/hgext/transplant.py b/hgext/transplant.py
> --- a/hgext/transplant.py
> +++ b/hgext/transplant.py
> @@ -299,12 +299,16 @@ class transplanter(object):
>
>      def resume(self, repo, source, opts):
>          '''recover last transaction and apply remaining changesets'''
>          if os.path.exists(os.path.join(self.path, 'journal')):
>              n, node = self.recover(repo, source, opts)
> -            self.ui.status(_('%s transplanted as %s\n') % (short(node),
> -                                                           short(n)))
> +            if n:
> +                self.ui.status(_('%s transplanted as %s\n') % (short(node),
> +                                                               short(n)))
> +            else:
> +                self.ui.status(_('%s skipped due to empty diff\n')
> +                               % (short(node),))
>          seriespath = os.path.join(self.path, 'series')
>          if not os.path.exists(seriespath):
>              self.transplants.write()
>              return
>          nodes, merges = self.readseries()
> @@ -341,16 +345,20 @@ class transplanter(object):
>                  raise util.Abort(
>                      _('working dir not at transplant parent %s') %
>                                   revlog.hex(parent))
>              if merge:
>                  repo.setparents(p1, parents[1])
> -            n = repo.commit(message, user, date, extra=extra,
> -                            editor=self.getcommiteditor())
> -            if not n:
> -                raise util.Abort(_('commit failed'))
> -            if not merge:
> -                self.transplants.set(n, node)
> +            modified, added, removed, deleted = repo.status()[:4]
> +            if merge or modified or added or removed or deleted:
> +                n = repo.commit(message, user, date, extra=extra,
> +                                editor=self.getcommiteditor())
> +                if not n:
> +                    raise util.Abort(_('commit failed'))
> +                if not merge:
> +                    self.transplants.set(n, node)
> +            else:
> +                n = None
>              self.unlog()
>
>              return n, node
>          finally:
>              wlock.release()
> diff --git a/tests/test-transplant.t b/tests/test-transplant.t
> --- a/tests/test-transplant.t
> +++ b/tests/test-transplant.t
> @@ -766,10 +766,26 @@ test transplanting a patch turning into
>    $ hg ci -Am addb2 b
>    $ hg transplant -s ../binarysource 2
>    searching for changes
>    applying 7a7d57e15850
>    skipping emptied changeset 7a7d57e15850
> +
> +Test empty result in --continue
> +
> +  $ hg transplant -s ../binarysource 1
> +  searching for changes
> +  applying 645035761929
> +  file b already exists
> +  1 out of 1 hunks FAILED -- saving rejects to file b.rej
> +  patch failed to apply
> +  abort: fix up the merge and run hg transplant --continue
> +  [255]
> +  $ hg status
> +  ? b.rej
> +  $ hg transplant --continue
> +  645035761929 skipped due to empty diff
> +
>    $ cd ..
>
>  Explicitly kill daemons to let the test exit on Windows
>
>    $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel

Patch

diff --git a/hgext/transplant.py b/hgext/transplant.py
--- a/hgext/transplant.py
+++ b/hgext/transplant.py
@@ -299,12 +299,16 @@  class transplanter(object):
 
     def resume(self, repo, source, opts):
         '''recover last transaction and apply remaining changesets'''
         if os.path.exists(os.path.join(self.path, 'journal')):
             n, node = self.recover(repo, source, opts)
-            self.ui.status(_('%s transplanted as %s\n') % (short(node),
-                                                           short(n)))
+            if n:
+                self.ui.status(_('%s transplanted as %s\n') % (short(node),
+                                                               short(n)))
+            else:
+                self.ui.status(_('%s skipped due to empty diff\n')
+                               % (short(node),))
         seriespath = os.path.join(self.path, 'series')
         if not os.path.exists(seriespath):
             self.transplants.write()
             return
         nodes, merges = self.readseries()
@@ -341,16 +345,20 @@  class transplanter(object):
                 raise util.Abort(
                     _('working dir not at transplant parent %s') %
                                  revlog.hex(parent))
             if merge:
                 repo.setparents(p1, parents[1])
-            n = repo.commit(message, user, date, extra=extra,
-                            editor=self.getcommiteditor())
-            if not n:
-                raise util.Abort(_('commit failed'))
-            if not merge:
-                self.transplants.set(n, node)
+            modified, added, removed, deleted = repo.status()[:4]
+            if merge or modified or added or removed or deleted:
+                n = repo.commit(message, user, date, extra=extra,
+                                editor=self.getcommiteditor())
+                if not n:
+                    raise util.Abort(_('commit failed'))
+                if not merge:
+                    self.transplants.set(n, node)
+            else:
+                n = None
             self.unlog()
 
             return n, node
         finally:
             wlock.release()
diff --git a/tests/test-transplant.t b/tests/test-transplant.t
--- a/tests/test-transplant.t
+++ b/tests/test-transplant.t
@@ -766,10 +766,26 @@  test transplanting a patch turning into 
   $ hg ci -Am addb2 b
   $ hg transplant -s ../binarysource 2
   searching for changes
   applying 7a7d57e15850
   skipping emptied changeset 7a7d57e15850
+
+Test empty result in --continue
+
+  $ hg transplant -s ../binarysource 1
+  searching for changes
+  applying 645035761929
+  file b already exists
+  1 out of 1 hunks FAILED -- saving rejects to file b.rej
+  patch failed to apply
+  abort: fix up the merge and run hg transplant --continue
+  [255]
+  $ hg status
+  ? b.rej
+  $ hg transplant --continue
+  645035761929 skipped due to empty diff
+
   $ cd ..
 
 Explicitly kill daemons to let the test exit on Windows
 
   $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS