From patchwork Fri Aug 15 00:05:32 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [STABLE] discovery: prevent crash on unknown remote heads with old repo (issue4337) From: Pierre-Yves David X-Patchwork-Id: 5403 Message-Id: To: mercurial-devel@selenic.com Cc: Pierre-Yves David Date: Thu, 14 Aug 2014 17:05:32 -0700 # HG changeset patch # User Pierre-Yves David # 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. 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))