diff --git a/default.nix b/default.nix --- a/default.nix +++ b/default.nix @@ -226,8 +226,8 @@ let rhodecode-testdata-src = sources.rhodecode-testdata or ( pkgs.fetchhg { url = "https://code.rhodecode.com/upstream/rc_testdata"; - rev = "v0.9.0"; - sha256 = "0k0ccb7cncd6mmzwckfbr6l7fsymcympwcm948qc3i0f0m6bbg1y"; + rev = "v0.10.0"; + sha256 = "0zn9swwvx4vgw4qn8q3ri26vvzgrxn15x6xnjrysi1bwmz01qjl0"; }); # Apply all overrides and fix the final package set diff --git a/rhodecode/controllers/files.py b/rhodecode/controllers/files.py --- a/rhodecode/controllers/files.py +++ b/rhodecode/controllers/files.py @@ -223,6 +223,8 @@ class FilesController(BaseRepoController c.file_author = True c.file_tree = '' if c.file.is_file(): + c.lf_node = c.file.get_largefile_node() + c.file_source_page = 'true' c.file_last_commit = c.file.last_commit if c.file.size < self.cut_off_limit_file: @@ -343,6 +345,14 @@ class FilesController(BaseRepoController commit = self.__get_commit_or_redirect(revision, repo_name) file_node = self.__get_filenode_or_redirect(repo_name, commit, f_path) + if request.GET.get('lf'): + # only if lf get flag is passed, we download this file + # as LFS/Largefile + lf_node = file_node.get_largefile_node() + if lf_node: + # overwrite our pointer with the REAL large-file + file_node = lf_node + response.content_disposition = 'attachment; filename=%s' % \ safe_str(f_path.split(Repository.NAME_SEP)[-1]) diff --git a/rhodecode/lib/vcs/backends/base.py b/rhodecode/lib/vcs/backends/base.py --- a/rhodecode/lib/vcs/backends/base.py +++ b/rhodecode/lib/vcs/backends/base.py @@ -893,9 +893,10 @@ class BaseCommit(object): def get_largefile_node(self, path): """ - Returns the path to largefile from Mercurial storage. + Returns the path to largefile from Mercurial/Git-lfs storage. + or None if it's not a largefile node """ - raise NotImplementedError + return None def archive_repo(self, file_path, kind='tgz', subrepos=None, prefix=None, write_metadata=False, mtime=None): diff --git a/rhodecode/lib/vcs/backends/git/commit.py b/rhodecode/lib/vcs/backends/git/commit.py --- a/rhodecode/lib/vcs/backends/git/commit.py +++ b/rhodecode/lib/vcs/backends/git/commit.py @@ -39,7 +39,7 @@ from rhodecode.lib.vcs.exceptions import from rhodecode.lib.vcs.nodes import ( FileNode, DirNode, NodeKind, RootNode, SubModuleNode, ChangedFileNodesGenerator, AddedFileNodesGenerator, - RemovedFileNodesGenerator) + RemovedFileNodesGenerator, LargeFileNode) class GitCommit(base.BaseCommit): @@ -423,6 +423,17 @@ class GitCommit(base.BaseCommit): self.nodes[path] = node return self.nodes[path] + def get_largefile_node(self, path): + id_, _ = self._get_id_for_path(path) + pointer_spec = self._remote.is_large_file(id_) + + if pointer_spec: + # content of that file regular FileNode is the hash of largefile + file_id = pointer_spec.get('oid_hash') + if self._remote.in_largefiles_store(file_id): + lf_path = self._remote.store_path(file_id) + return LargeFileNode(lf_path, commit=self, org_path=path) + @LazyProperty def affected_files(self): """ diff --git a/rhodecode/lib/vcs/backends/hg/commit.py b/rhodecode/lib/vcs/backends/hg/commit.py --- a/rhodecode/lib/vcs/backends/hg/commit.py +++ b/rhodecode/lib/vcs/backends/hg/commit.py @@ -312,18 +312,18 @@ class MercurialCommit(base.BaseCommit): return self.nodes[path] def get_largefile_node(self, path): - path = os.path.join(LARGEFILE_PREFIX, path) if self._remote.is_large_file(path): # content of that file regular FileNode is the hash of largefile file_id = self.get_file_content(path).strip() - if self._remote.in_store(file_id): - path = self._remote.store_path(file_id) - return LargeFileNode(path, commit=self) + + if self._remote.in_largefiles_store(file_id): + lf_path = self._remote.store_path(file_id) + return LargeFileNode(lf_path, commit=self, org_path=path) elif self._remote.in_user_cache(file_id): - path = self._remote.store_path(file_id) + lf_path = self._remote.store_path(file_id) self._remote.link(file_id, path) - return LargeFileNode(path, commit=self) + return LargeFileNode(lf_path, commit=self, org_path=path) @LazyProperty def _submodules(self): 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 @@ -22,7 +22,7 @@ Module holding everything related to vcs nodes, with vcs2 architecture. """ - +import os import stat from zope.cachedescriptors.property import Lazy as LazyProperty @@ -547,9 +547,8 @@ class FileNode(Node): create special instance of LargeFileNode which can get content from LF store. """ - if self.commit and self.path.startswith(LARGEFILE_PREFIX): - largefile_path = self.path.split(LARGEFILE_PREFIX)[-1].lstrip('/') - return self.commit.get_largefile_node(largefile_path) + if self.commit: + return self.commit.get_largefile_node(self.path) def lines(self, count_empty=False): all_lines, empty_lines = 0, 0 @@ -765,15 +764,37 @@ class SubModuleNode(Node): class LargeFileNode(FileNode): + def __init__(self, path, url=None, commit=None, alias=None, org_path=None): + self.path = path + self.org_path = org_path + self.kind = NodeKind.LARGEFILE + self.alias = alias + def _validate_path(self, path): """ we override check since the LargeFileNode path is system absolute """ + pass + def __repr__(self): + return '<%s %r>' % (self.__class__.__name__, self.path) + + @LazyProperty + def size(self): + return os.stat(self.path).st_size + + @LazyProperty def raw_bytes(self): if self.commit: with open(self.path, 'rb') as f: content = f.read() else: content = self._content - return content \ No newline at end of file + return content + + @LazyProperty + def name(self): + """ + Overwrites name to be the org lf path + """ + return self.org_path diff --git a/rhodecode/templates/files/files_source.mako b/rhodecode/templates/files/files_source.mako --- a/rhodecode/templates/files/files_source.mako +++ b/rhodecode/templates/files/files_source.mako @@ -4,6 +4,9 @@