@@ -10,7 +10,8 @@ from rhodecode.lib.vcs.exceptions import
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError
from rhodecode.lib.vcs.exceptions import ImproperArchiveTypeError
from rhodecode.lib.vcs.backends.base import BaseChangeset
from rhodecode.lib.vcs.nodes import FileNode, DirNode, NodeKind, RootNode, RemovedFileNode
from rhodecode.lib.vcs.nodes import FileNode, DirNode, NodeKind, RootNode, \
RemovedFileNode, SubModuleNode
from rhodecode.lib.vcs.utils import safe_unicode
from rhodecode.lib.vcs.utils import date_fromtimestamp
from rhodecode.lib.vcs.utils.lazy import LazyProperty
@@ -329,7 +330,13 @@ class GitChangeset(BaseChangeset):
tree = self.repository._repo[id]
dirnodes = []
filenodes = []
als = self.repository.alias
for name, stat, id in tree.iteritems():
if objects.S_ISGITLINK(stat):
dirnodes.append(SubModuleNode(name, url=None, changeset=id,
alias=als))
continue
obj = self.repository._repo.get_object(id)
if path != '':
obj_path = '/'.join((path, name))
@@ -5,8 +5,9 @@ from rhodecode.lib.vcs.backends.base imp
from rhodecode.lib.vcs.conf import settings
from rhodecode.lib.vcs.exceptions import ChangesetDoesNotExistError, \
ChangesetError, ImproperArchiveTypeError, NodeDoesNotExistError, VCSError
from rhodecode.lib.vcs.nodes import AddedFileNodesGenerator, ChangedFileNodesGenerator, \
DirNode, FileNode, NodeKind, RemovedFileNodesGenerator, RootNode
from rhodecode.lib.vcs.nodes import AddedFileNodesGenerator, \
ChangedFileNodesGenerator, DirNode, FileNode, NodeKind, \
RemovedFileNodesGenerator, RootNode, SubModuleNode
from rhodecode.lib.vcs.utils import safe_str, safe_unicode, date_fromtimestamp
@@ -159,6 +160,13 @@ class MercurialChangeset(BaseChangeset):
" %r" % (self.revision, path))
return self._ctx.filectx(path)
def _extract_submodules(self):
"""
returns a dictionary with submodule information from substate file
of hg repository
return self._ctx.substate
def get_file_mode(self, path):
Returns stat mode of the file at the given ``path``.
@@ -271,17 +279,27 @@ class MercurialChangeset(BaseChangeset):
raise ChangesetError("Directory does not exist for revision %r at "
path = self._fix_path(path)
filenodes = [FileNode(f, changeset=self) for f in self._file_paths
if os.path.dirname(f) == path]
dirs = path == '' and '' or [d for d in self._dir_paths
if d and posixpath.dirname(d) == path]
dirnodes = [DirNode(d, changeset=self) for d in dirs
if os.path.dirname(d) == path]
for k, vals in self._extract_submodules().iteritems():
#vals = url,rev,type
loc = vals[0]
cs = vals[1]
dirnodes.append(SubModuleNode(k, url=loc, changeset=cs,
nodes = dirnodes + filenodes
# cache nodes
for node in nodes:
self.nodes[node.path] = node
nodes.sort()
return nodes
def get_node(self, path):
@@ -8,19 +8,21 @@
:created_on: Apr 8, 2010
:copyright: (c) 2010-2011 by Marcin Kuzminski, Lukasz Balcerzak.
import os
import stat
import posixpath
import mimetypes
from pygments import lexers
from rhodecode.lib.vcs.utils import safe_unicode, safe_str
from rhodecode.lib.vcs.exceptions import NodeError
from rhodecode.lib.vcs.exceptions import RemovedFileNodeError
class NodeKind:
SUBMODULE = -1
DIR = 1
FILE = 2
@@ -209,6 +211,13 @@ class Node(object):
return self.kind == NodeKind.DIR and self.path == ''
def is_submodule(self):
Returns ``True`` if node's kind is ``NodeKind.SUBMODULE``, ``False``
otherwise.
return self.kind == NodeKind.SUBMODULE
@LazyProperty
def added(self):
return self.state is NodeState.ADDED
@@ -561,3 +570,31 @@ class RootNode(DirNode):
def __repr__(self):
return '<%s>' % self.__class__.__name__
class SubModuleNode(Node):
represents a SubModule of Git or SubRepo of Mercurial
def __init__(self, name, url=None, changeset=None, alias=None):
self.path = name
self.kind = NodeKind.SUBMODULE
self.alias = alias
# changeset MUST be STR !! since it can point to non-valid SCM
self.changeset = str(changeset)
self.url = url or self._extract_submodule_url()
def _extract_submodule_url(self):
if self.alias == 'git':
return self.path
if self.alias == 'hg':
def name(self):
Returns name of the node so if its path
then only last part is returned.
org = safe_unicode(self.path.rstrip('/').split('/')[-1])
return u'%s @ %s' % (org, self.changeset[:12])
@@ -2718,6 +2718,14 @@ table.code-browser .browser-dir {
text-align: left;
}
table.code-browser .submodule-dir {
background: url("../images/icons/disconnect.png") no-repeat scroll 3px;
height: 16px;
padding-left: 20px;
.box .search {
clear: both;
overflow: hidden;
@@ -70,7 +70,11 @@
%for cnt,node in enumerate(c.file):
<tr class="parity${cnt%2}">
<td>
${h.link_to(node.name,h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node)+" ypjax-link")}
%if node.is_submodule():
${h.link_to(node.name,node.url or '#',class_="submodule-dir ypjax-link")}
%else:
${h.link_to(node.name, h.url('files_home',repo_name=c.repo_name,revision=c.changeset.raw_id,f_path=h.safe_unicode(node.path)),class_=file_class(node)+" ypjax-link")}
%endif:
</td>
%if node.is_file():
Status change: