Patchwork [STABLE] discovery: prevent crash on unknown remote heads with old repo (issue4337)

login
register
mail settings
Submitter Pierre-Yves David
Date Aug. 15, 2014, 12:05 a.m.
Message ID <f06241705e67a5d9c825.1408061132@marginatus.alto.octopoid.net>
Download mbox | patch
Permalink /patch/5403/
State Accepted
Headers show

Comments

Pierre-Yves David - Aug. 15, 2014, 12:05 a.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@fb.com>
# Date 1408058801 25200
#      Thu Aug 14 16:26:41 2014 -0700
# Branch stable
# Node ID f06241705e67a5d9c8254d8dc565e2f7c2015521
# Parent  989c16c1b050a314e136675ca9ac73a90d13da2a
discovery: prevent crash on unknown remote heads with old repo (issue4337)

When a remote is not capable of the `branchmap` wireproto command, with denote
incoming heads with None. This lead to a crash in the code in charge of
displaying the list of unknown remote heads.

We now properly detect this case and display a shorter message in this case.

The reason for this  `set([None])` value is now documented.
Matt Mackall - Aug. 15, 2014, 3:04 a.m.
On Thu, 2014-08-14 at 17:05 -0700, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@fb.com>
> # Date 1408058801 25200
> #      Thu Aug 14 16:26:41 2014 -0700
> # Branch stable
> # Node ID f06241705e67a5d9c8254d8dc565e2f7c2015521
> # Parent  989c16c1b050a314e136675ca9ac73a90d13da2a
> discovery: prevent crash on unknown remote heads with old repo (issue4337)

Queued for stable, thanks.

Patch

diff --git a/mercurial/discovery.py b/mercurial/discovery.py
--- a/mercurial/discovery.py
+++ b/mercurial/discovery.py
@@ -215,10 +215,11 @@  def _oldheadssummary(repo, remoteheads, 
     # - another element of outgoing.missing
     # - nullrev
     # This explains why the new head are very simple to compute.
     r = repo.set('heads(%ln + %ln)', oldheads, outgoing.missing)
     newheads = list(c.node() for c in r)
+    # set some unsynced head to issue the "unsynced changes" warning
     unsynced = inc and set([None]) or set()
     return {None: (oldheads, newheads, unsynced)}
 
 def checkheads(repo, remote, outgoing, remoteheads, newbranch=False, inc=False,
                newbookmarks=[]):
@@ -311,16 +312,22 @@  def checkheads(repo, remote, outgoing, r
                         newhs.add(nh)
         else:
             newhs = candidate_newhs
         unsynced = sorted(h for h in unsyncedheads if h not in discardedheads)
         if unsynced:
-            if len(unsynced) <= 4 or repo.ui.verbose:
+            if None in unsynced:
+                # old remote, no heads data
+                heads = None
+            elif len(unsynced) <= 4 or repo.ui.verbose:
                 heads = ' '.join(short(h) for h in unsynced)
             else:
                 heads = (' '.join(short(h) for h in unsynced[:4]) +
                          ' ' + _("and %s others") % (len(unsynced) - 4))
-            if branch is None:
+            if heads is None:
+                repo.ui.status(_("remote has heads that are "
+                                 "not known locally\n"))
+            elif branch is None:
                 repo.ui.status(_("remote has heads that are "
                                  "not known locally: %s\n") % heads)
             else:
                 repo.ui.status(_("remote has heads on branch '%s' that are "
                                  "not known locally: %s\n") % (branch, heads))