diff mercurial/exchange.py @ 45156:c26335fa4225

exchange: check actually missing revs for obsolete / unstable revs (issue6372) The previous code was using `outgoing.ancestorsof`, which was originally called `outgoing.missingheads` although not containing the missing heads. This confusion was probably the reason why the buggy code was written. The actually outgoing changesets are stored in `outgoing.missing`. By checking all outgoing changesets, we avoid the problem and can show the list of all obsolete or unstable changesets, which is more helpful for the user.
author Manuel Jacob <me@manueljacob.de>
date Fri, 17 Jul 2020 08:21:31 +0200
parents c93dd9d9f1e6
children 6063c1857d0a
line wrap: on
line diff
--- a/mercurial/exchange.py	Fri Jul 17 07:59:20 2020 +0200
+++ b/mercurial/exchange.py	Fri Jul 17 08:21:31 2020 +0200
@@ -905,27 +905,32 @@
         # if repo.obsstore == False --> no obsolete
         # then, save the iteration
         if unfi.obsstore:
-            # this message are here for 80 char limit reason
-            mso = _(b"push includes obsolete changeset: %s!")
-            mspd = _(b"push includes phase-divergent changeset: %s!")
-            mscd = _(b"push includes content-divergent changeset: %s!")
-            mst = {
-                b"orphan": _(b"push includes orphan changeset: %s!"),
-                b"phase-divergent": mspd,
-                b"content-divergent": mscd,
-            }
-            # If we are to push if there is at least one
-            # obsolete or unstable changeset in missing, at
-            # least one of the missinghead will be obsolete or
-            # unstable. So checking heads only is ok
-            for node in outgoing.ancestorsof:
+            obsoletes = []
+            unstables = []
+            for node in outgoing.missing:
                 ctx = unfi[node]
                 if ctx.obsolete():
-                    raise error.Abort(mso % ctx)
+                    obsoletes.append(ctx)
                 elif ctx.isunstable():
-                    # TODO print more than one instability in the abort
-                    # message
-                    raise error.Abort(mst[ctx.instabilities()[0]] % ctx)
+                    unstables.append(ctx)
+            if obsoletes or unstables:
+                msg = b""
+                if obsoletes:
+                    msg += _(b"push includes obsolete changesets:\n")
+                    msg += b"\n".join(b'  %s' % ctx for ctx in obsoletes)
+                if unstables:
+                    if msg:
+                        msg += b"\n"
+                    msg += _(b"push includes unstable changesets:\n")
+                    msg += b"\n".join(
+                        b'  %s (%s)'
+                        % (
+                            ctx,
+                            b", ".join(_(ins) for ins in ctx.instabilities()),
+                        )
+                        for ctx in unstables
+                    )
+                raise error.Abort(msg)
 
         discovery.checkheads(pushop)
     return True