[core] mercurial 2.0 support (closes #84549)

  • keep support for mercurial 1.6.4 (intermediate versions may not work)
  • change/file context parents stuff is already done in mercurial.
  • new features are not integrated
authorAlain Leufroy <alain.leufroy@logilab.fr>
changeset06ee39817550
branchdefault
phasepublic
hiddenno
parent revision#80a177693edc [hg patches] Dedicate a module to patch Mercurial (closes #75296)
child revision#b3a3bf6de071 [cosmetic] remove superfluous hash-bangs and the entry point in ``hgviewlib/application.py`` (closes #78002)
files modified by this revision
hgviewlib/hggraph.py
hgviewlib/hgpatches/__init__.py
hgviewlib/qt4/hgrepoviewer.py
setup.py
# HG changeset patch
# User Alain Leufroy <alain.leufroy@logilab.fr>
# Date 1321911704 -3600
# Mon Nov 21 22:41:44 2011 +0100
# Node ID 06ee398175507bee7ecbb894560e60673ad75702
# Parent 80a177693edc167b09feb7ec8b42a566f3519dc9
[core] mercurial 2.0 support (closes #84549)

* keep support for mercurial 1.6.4 (intermediate versions may not work)
* change/file context parents stuff is already done in mercurial.
* new features are not integrated

diff --git a/hgviewlib/hggraph.py b/hgviewlib/hggraph.py
@@ -31,27 +31,35 @@
1  from hgviewlib.util import tounicode, isbfile
2  from hgviewlib.config import HgConfig
3 
4  def diff(repo, ctx1, ctx2=None, files=None):
5      """
6 -    Compute the diff of files between 2 changectx
7 +    Compute the diff of ``files`` between the 2 contexts ``ctx1`` and ``ctx2``.
8 +
9 +    :Note: context may be a changectx or a filectx.
10 +
11 +    * If ``ctx2`` is None, the parent of ``ctx1`` is used. If ``ctx1`` is a
12 +      file ctx, the parent is the first ancestor that contains modification
13 +      on the given file
14 +    * If ``files`` is None, return the diff for all files.
15 +
16      """
17      if ctx2 is None:
18 -        ctx2 = ctx1.parents()[0]
19 +        ctx2 = ctx1.p1()
20      if files is None:
21 -        m = match.always(repo.root, repo.getcwd())
22 +        matchfn = match.always(repo.root, repo.getcwd())
23      else:
24 -        m = match.exact(repo.root, repo.getcwd(), files)
25 +        matchfn = match.exact(repo.root, repo.getcwd(), files)
26      # try/except for the sake of hg compatibility (API changes between
27      # 1.0 and 1.1)
28      try:
29          out = StringIO()
30 -        patch.diff(repo, ctx2.node(), ctx1.node(), match=m, fp=out)
31 +        patch.diff(repo, ctx2.node(), ctx1.node(), match=matchfn, fp=out)
32          diffdata = out.getvalue()
33      except:
34          diffdata = '\n'.join(patch.diff(repo, ctx2.node(), ctx1.node(),
35 -                                        match=m))
36 +                                        match=matchfn))
37      # XXX how to deal diff encodings?
38      try:
39          diffdata = unicode(diffdata, "utf-8")
40      except UnicodeError:
41          # XXX use a default encoding from config?
@@ -453,13 +461,11 @@
42              elif flag == "=" or isinstance(mode, int):
43                  flag = "="
44                  if isinstance(mode, int):
45                      parentctx = self.repo.changectx(mode)
46                  else:
47 -                    parent = self.fileparent(filename, rev)
48 -                    parentctx = self.repo.changectx(parent)
49 -                # return the diff but the 3 first lines
50 +                    parentctx = self.repo[self._fileparent(fctx)]
51                  data = diff(self.repo, ctx, parentctx, files=[filename])
52                  data = u'\n'.join(data.splitlines()[3:])
53              elif flag == '':
54                  data = ''
55              else: # file renamed
@@ -475,23 +481,18 @@
56                      data = newdata
57                      flag = "+"
58                  data = u'\n'.join(tounicode(elt) for elt in data)
59          return flag, data
60 
61 +    def _fileparent(self, fctx):
62 +        try:
63 +            return fctx.p1().rev()
64 +        except IndexError: # reach bottom
65 +            return -1
66 +
67      def fileparent(self, filename, rev):
68 -        if rev is not None:
69 -            node = self.repo.changelog.node(rev)
70 -        else:
71 -            node = self.repo.changectx(rev).node()
72 -        for parent in self.nodesdict[rev].parents:
73 -            pnode = self.repo.changelog.node(parent)
74 -            changes = self.repo.status(pnode, node)[:5]
75 -            allchanges = []
76 -            [allchanges.extend(e) for e in changes]
77 -            if filename in allchanges:
78 -                return parent
79 -        return None
80 +        return self._fileparent(self.repo[rev].filectx(filename))
81 
82  class HgRepoListWalker(object):
83      """
84      Graph object to ease hg repo revision tree drawing depending on user's
85      configurations.
diff --git a/hgviewlib/hgpatches/__init__.py b/hgviewlib/hgpatches/__init__.py
@@ -21,5 +21,9 @@
86  from mercurial import changelog, filelog
87  if not hasattr(changelog.changelog, '__len__'):
88      changelog.changelog.__len__ = changelog.changelog.count
89  if not hasattr(filelog.filelog, '__len__'):
90      filelog.filelog.__len__ = filelog.filelog.count
91 +
92 +from mercurial import context
93 +if not hasattr(context.filectx, 'p1'):
94 +    context.filectx.p1 = lambda self: self.parents()[0]
diff --git a/hgviewlib/qt4/hgrepoviewer.py b/hgviewlib/qt4/hgrepoviewer.py
@@ -440,11 +440,11 @@
95      def revision_selected(self, rev):
96          """
97          Callback called when a revision is selected in the revisions table
98          """
99          if self.repomodel.graph:
100 -            ctx = self.repomodel.repo.changectx(rev)
101 +            ctx = self.repomodel.repo[rev]
102              self.textview_status.setContext(ctx)
103              self.textview_header.displayRevision(ctx)
104              self.filelistmodel.setSelectedRev(ctx)
105              if len(self.filelistmodel):
106                  self.tableView_filelist.selectRow(0)
diff --git a/setup.py b/setup.py
@@ -235,11 +235,11 @@
107          scripts = ['win32/hgview_postinstall.py']
108      else:
109          scripts = ['bin/hgview']
110 
111      kwargs['package_dir'] = {modname : modname}
112 -    packages = ['hgviewlib', 'hgext', 'hgviewlib.qt4', 'hgviewlib.curses']
113 +    packages = ['hgviewlib', 'hgext', 'hgviewlib.hgpatches', 'hgviewlib.qt4', 'hgviewlib.curses']
114      kwargs['packages'] = packages
115      return setup(name=distname,
116                   version=version,
117                   license=license,
118                   description=description,