diff --git a/rhodecode/lib/diffs.py b/rhodecode/lib/diffs.py --- a/rhodecode/lib/diffs.py +++ b/rhodecode/lib/diffs.py @@ -33,8 +33,8 @@ from itertools import tee, imap from pylons.i18n.translation import _ from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.nodes import FileNode - +from rhodecode.lib.vcs.nodes import FileNode, SubModuleNode +from rhodecode.lib.helpers import escape from rhodecode.lib.utils import EmptyChangeset @@ -79,9 +79,13 @@ def wrapped_diff(filenode_old, filenode_ 'diff menu to display this diff')) stats = (0, 0) size = 0 - if not diff: - diff = wrap_to_table(_('No changes detected')) + submodules = filter(lambda o: isinstance(o, SubModuleNode), + [filenode_new, filenode_old]) + if submodules: + diff = wrap_to_table(escape('Submodule %r' % submodules[0])) + else: + diff = wrap_to_table(_('No changes detected')) cs1 = filenode_old.changeset.raw_id cs2 = filenode_new.changeset.raw_id @@ -97,6 +101,10 @@ def get_gitdiff(filenode_old, filenode_n """ # make sure we pass in default context context = context or 3 + submodules = filter(lambda o: isinstance(o, SubModuleNode), + [filenode_new, filenode_old]) + if submodules: + return '' for filenode in (filenode_old, filenode_new): if not isinstance(filenode, FileNode): @@ -109,7 +117,6 @@ def get_gitdiff(filenode_old, filenode_n vcs_gitdiff = repo.get_diff(old_raw_id, new_raw_id, filenode_new.path, ignore_whitespace, context) - return vcs_gitdiff diff --git a/rhodecode/lib/vcs/backends/git/changeset.py b/rhodecode/lib/vcs/backends/git/changeset.py --- a/rhodecode/lib/vcs/backends/git/changeset.py +++ b/rhodecode/lib/vcs/backends/git/changeset.py @@ -364,24 +364,31 @@ class GitChangeset(BaseChangeset): path = self._fix_path(path) if not path in self.nodes: try: - id = self._get_id_for_path(path) + id_ = self._get_id_for_path(path) except ChangesetError: raise NodeDoesNotExistError("Cannot find one of parents' " "directories for a given path: %s" % path) - obj = self.repository._repo.get_object(id) - if isinstance(obj, objects.Tree): - if path == '': - node = RootNode(changeset=self) + + als = self.repository.alias + _GL = lambda m: m and objects.S_ISGITLINK(m) + if _GL(self._stat_modes.get(path)): + node = SubModuleNode(path, url=None, changeset=id_, alias=als) + else: + obj = self.repository._repo.get_object(id_) + + if isinstance(obj, objects.Tree): + if path == '': + node = RootNode(changeset=self) + else: + node = DirNode(path, changeset=self) + node._tree = obj + elif isinstance(obj, objects.Blob): + node = FileNode(path, changeset=self) + node._blob = obj else: - node = DirNode(path, changeset=self) - node._tree = obj - elif isinstance(obj, objects.Blob): - node = FileNode(path, changeset=self) - node._blob = obj - else: - raise NodeDoesNotExistError("There is no file nor directory " - "at the given path %r at revision %r" - % (path, self.short_id)) + raise NodeDoesNotExistError("There is no file nor directory " + "at the given path %r at revision %r" + % (path, self.short_id)) # cache node self.nodes[path] = node return self.nodes[path] @@ -423,7 +430,6 @@ class GitChangeset(BaseChangeset): line)) _path = splitted[1].strip() paths.add(_path) - return sorted(paths) @LazyProperty diff --git a/rhodecode/lib/vcs/backends/git/repository.py b/rhodecode/lib/vcs/backends/git/repository.py --- a/rhodecode/lib/vcs/backends/git/repository.py +++ b/rhodecode/lib/vcs/backends/git/repository.py @@ -411,7 +411,7 @@ class GitRepository(BaseRepository): yield self.get_changeset(rev) def get_diff(self, rev1, rev2, path=None, ignore_whitespace=False, - context=3): + context=3): """ Returns (git like) *diff*, as plain text. Shows changes introduced by ``rev2`` since ``rev1``. diff --git a/rhodecode/lib/vcs/nodes.py b/rhodecode/lib/vcs/nodes.py --- a/rhodecode/lib/vcs/nodes.py +++ b/rhodecode/lib/vcs/nodes.py @@ -19,6 +19,7 @@ from rhodecode.lib.vcs.utils.lazy import from rhodecode.lib.vcs.utils import safe_unicode, safe_str from rhodecode.lib.vcs.exceptions import NodeError from rhodecode.lib.vcs.exceptions import RemovedFileNodeError +from rhodecode.lib.utils import EmptyChangeset class NodeKind: @@ -576,16 +577,26 @@ class SubModuleNode(Node): """ represents a SubModule of Git or SubRepo of Mercurial """ + is_binary = False + size = 0 + 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) + # we have to use emptyChangeset here since this can point to svn/git/hg + # submodules we cannot get from repository + self.changeset = EmptyChangeset(str(changeset), alias=alias) self.url = url or self._extract_submodule_url() + def __repr__(self): + return '<%s %r @ %s>' % (self.__class__.__name__, self.path, + self.changeset.short_id) + def _extract_submodule_url(self): if self.alias == 'git': + #TODO: find a way to parse gits submodule file and extract the + # linking URL return self.path if self.alias == 'hg': return self.path @@ -597,4 +608,4 @@ class SubModuleNode(Node): then only last part is returned. """ org = safe_unicode(self.path.rstrip('/').split('/')[-1]) - return u'%s @ %s' % (org, self.changeset[:12]) + return u'%s @ %s' % (org, self.changeset.short_id)