Commits

Yuya Nishihara committed cdf305f

issue 1182

Comments (0)

Files changed (2)

graph-index-lazyload.diff

+# HG changeset patch
+# Date 1382270222 -32400
+# Parent 8d15a5bf8851ed2fce8dab56127b646d93d8962a
+graph: avoid invalid comparison of unapplied patch revision (fixes #1182)
+
+Thanks to the implementation detail of CPython 2.x, where "str_rev < int_rev"
+returns False, Graph.index does not raise TypeError in most cases.  The issue
+#1182 happenes if self.nodes[-1] is an unapplied patch.
+
+This removes invalid comparison between str and int, and makes sure to load
+unapplied patch nodes which are not comparable in build_nodes.
+
+diff --git a/tests/graph_test.py b/tests/graph_test.py
+--- a/tests/graph_test.py
++++ b/tests/graph_test.py
+@@ -2,7 +2,7 @@ import os
+ from nose.tools import *
+ 
+ from mercurial import hg, ui
+-from tortoisehg.hgqt import graph
++from tortoisehg.hgqt import graph, thgrepo
+ 
+ import helpers
+ 
+@@ -43,9 +43,32 @@ def setup():
+     hg.merge('--tool=internal:local', '6')
+     hg.commit('-m', 'bar8')
+ 
++    # Graph.index fetches 10 nodes by default
++    hg = helpers.HgClient(os.path.join(_tmpdir, '20nodes'))
++    hg.init()
++    hg.ftouch('data')
++    hg.add('data')
++    for i in xrange(20):
++        hg.fappend('data', '%d\n' % i)
++        hg.commit('-m', str(i))
++
++    hg = helpers.HgClient(os.path.join(_tmpdir, '20patches'))
++    hg.init()
++    hg.fappend('data', '0\n')
++    hg.commit('-Am', '0')
++    hg.fappend('data', '1\n')
++    hg.commit('-Am', '1')
++    for i in xrange(20):
++        hg.qnew('%d.diff' % i)
++    hg.qpop('-a')
++
+ def openrepo(name):
+     return hg.repository(ui.ui(), os.path.join(_tmpdir, name))
+ 
++# include_mq=True requires thgrepo extension
++def openthgrepo(name):
++    return thgrepo.repository(ui.ui(), os.path.join(_tmpdir, name))
++
+ def buildlinecolortable(grapher):
+     table = {}  # rev: [linecolor, ...]
+     for node in grapher:
+@@ -106,3 +129,26 @@ def test_linecolor_filelog():
+         0: [],
+         }
+     assert_equal(expectedtable, actualtable)
++
++
++def test_graph_index():
++    repo = openrepo('20nodes')
++    grapher = graph.revision_grapher(repo)
++    graphobj = graph.Graph(repo, grapher)
++    assert_equal(0, len(graphobj))
++    assert_equal(0, graphobj.index(None))  # working dir
++    assert_equal(1, graphobj.index(19))
++    assert_equal(20, graphobj.index(0))
++    assert_equal(21, len(graphobj))
++
++def test_graph_index_unapplied_patches():
++    repo = openthgrepo('20patches')
++    grapher = graph.revision_grapher(repo)
++    graphobj = graph.Graph(repo, grapher, include_mq=True)
++    assert_equal(0, len(graphobj))
++    assert_equal(0, graphobj.index('19.diff'))
++    assert_equal(19, graphobj.index('0.diff'))
++    assert_equal(20, graphobj.index(None))  # working dir
++    assert_equal(21, graphobj.index(1))
++    assert_equal(22, graphobj.index(0))
++    assert_equal(23, len(graphobj))
+diff --git a/tortoisehg/hgqt/graph.py b/tortoisehg/hgqt/graph.py
+--- a/tortoisehg/hgqt/graph.py
++++ b/tortoisehg/hgqt/graph.py
+@@ -407,7 +407,8 @@ class Graph(object):
+             self.nodesdict[gnode.rev] = gnode
+             mcol = mcol.union(set([gnode.x]))
+             mcol = mcol.union(set([max(x[:2]) for x in gnode.bottomlines]))
+-            if rev is not None and gnode.rev <= rev:
++            if (rev is not None and isinstance(gnode.rev, int)
++                and gnode.rev <= rev):
+                 rev = None # we reached rev, switching to nnode counter
+             if rev is None:
+                 if nnodes is not None:
+@@ -429,9 +430,12 @@ class Graph(object):
+         return self.grapher is None
+ 
+     def index(self, rev):
+-        if len(self) == 0: # graph is empty, let's build some nodes
+-            self.build_nodes(10)
+-        if rev is not None and len(self) > 0 and rev < self.nodes[-1].rev:
++        if len(self) == 0:
++            # graph is empty, let's build some nodes.  nodes for unapplied
++            # patches are built at once because they don't have comparable
++            # revision numbers, which makes build_nodes() go wrong.
++            self.build_nodes(10, len(self.repo) - 1)
++        if isinstance(rev, int) and len(self) > 0 and rev < self.nodes[-1].rev:
+             self.build_nodes(self.nodes[-1].rev - rev)
+         if rev in self.nodesdict:
+             return self.nodes.index(self.nodesdict[rev])
+graph-index-lazyload.diff
 shelve-avoidsamepatch.diff
 chunks-getfilelistemp.diff
 shelve-selectionchanged.diff
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.