mirror of
https://github.com/scm-manager/scm-manager.git
synced 2026-01-01 05:09:50 +01:00
Get correct sizes for lfs files
This commit is contained in:
@@ -42,7 +42,10 @@ import com.google.common.collect.Multimap;
|
||||
import org.eclipse.jgit.api.FetchCommand;
|
||||
import org.eclipse.jgit.api.Git;
|
||||
import org.eclipse.jgit.api.errors.GitAPIException;
|
||||
import org.eclipse.jgit.attributes.Attribute;
|
||||
import org.eclipse.jgit.attributes.Attributes;
|
||||
import org.eclipse.jgit.diff.DiffFormatter;
|
||||
import org.eclipse.jgit.lfs.LfsPointer;
|
||||
import org.eclipse.jgit.lib.AnyObjectId;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
@@ -55,6 +58,7 @@ import org.eclipse.jgit.transport.FetchResult;
|
||||
import org.eclipse.jgit.transport.RefSpec;
|
||||
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.eclipse.jgit.util.LfsFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.ContextEntry;
|
||||
@@ -65,10 +69,12 @@ import sonia.scm.web.GitUserAgentProvider;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Optional.empty;
|
||||
import static java.util.Optional.of;
|
||||
|
||||
//~--- JDK imports ------------------------------------------------------------
|
||||
@@ -731,6 +737,20 @@ public final class GitUtil
|
||||
}
|
||||
}
|
||||
|
||||
public static Optional<LfsPointer> getLfsPointer(org.eclipse.jgit.lib.Repository repo, String path, RevCommit commit, TreeWalk treeWalk) throws IOException {
|
||||
Attributes attributes = LfsFactory.getAttributesForPath(repo, path, commit);
|
||||
|
||||
Attribute filter = attributes.get("filter");
|
||||
if (filter != null && "lfs".equals(filter.getValue())) {
|
||||
ObjectId blobId = treeWalk.getObjectId(0);
|
||||
try (InputStream is = repo.open(blobId, Constants.OBJ_BLOB).openStream()) {
|
||||
return of(LfsPointer.parseLfsPointer(is));
|
||||
}
|
||||
} else {
|
||||
return empty();
|
||||
}
|
||||
}
|
||||
|
||||
//~--- methods --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
||||
@@ -38,6 +38,7 @@ package sonia.scm.repository.spi;
|
||||
import com.google.common.base.Strings;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.eclipse.jgit.lfs.LfsPointer;
|
||||
import org.eclipse.jgit.lib.Constants;
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.lib.ObjectLoader;
|
||||
@@ -57,6 +58,8 @@ import sonia.scm.repository.GitSubModuleParser;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.repository.Repository;
|
||||
import sonia.scm.repository.SubRepository;
|
||||
import sonia.scm.store.Blob;
|
||||
import sonia.scm.store.BlobStore;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.lfs.LfsBlobStoreFactory;
|
||||
|
||||
@@ -65,6 +68,7 @@ import java.io.IOException;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
@@ -170,7 +174,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
* @throws IOException
|
||||
*/
|
||||
private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo,
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk)
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk)
|
||||
throws IOException {
|
||||
|
||||
FileObject file = new FileObject();
|
||||
@@ -198,7 +202,6 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
ObjectLoader loader = repo.open(treeWalk.getObjectId(0));
|
||||
|
||||
file.setDirectory(loader.getType() == Constants.OBJ_TREE);
|
||||
file.setLength(loader.getSize());
|
||||
|
||||
// don't show message and date for directories to improve performance
|
||||
if (!file.isDirectory() &&!request.isDisableLastCommit())
|
||||
@@ -206,6 +209,16 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
logger.trace("fetch last commit for {} at {}", path, revId.getName());
|
||||
RevCommit commit = getLatestCommit(repo, revId, path);
|
||||
|
||||
Optional<LfsPointer> lfsPointer = GitUtil.getLfsPointer(repo, path, commit, treeWalk);
|
||||
|
||||
if (lfsPointer.isPresent()) {
|
||||
BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository);
|
||||
Blob blob = lfsBlobStore.get(lfsPointer.get().getOid().getName());
|
||||
file.setLength(blob.getSize());
|
||||
} else {
|
||||
file.setLength(loader.getSize());
|
||||
}
|
||||
|
||||
if (commit != null)
|
||||
{
|
||||
file.setLastModified(GitUtil.getCommitTime(commit));
|
||||
@@ -235,7 +248,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
* @return
|
||||
*/
|
||||
private RevCommit getLatestCommit(org.eclipse.jgit.lib.Repository repo,
|
||||
ObjectId revId, String path)
|
||||
ObjectId revId, String path)
|
||||
{
|
||||
RevCommit result = null;
|
||||
RevWalk walk = null;
|
||||
@@ -342,7 +355,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
}
|
||||
|
||||
private FileObject findFirstMatch(org.eclipse.jgit.lib.Repository repo,
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException {
|
||||
BrowseCommandRequest request, ObjectId revId, TreeWalk treeWalk) throws IOException {
|
||||
String[] pathElements = request.getPath().split("/");
|
||||
int currentDepth = 0;
|
||||
int limit = pathElements.length;
|
||||
@@ -367,7 +380,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
@SuppressWarnings("unchecked")
|
||||
private Map<String,
|
||||
SubRepository> getSubRepositories(org.eclipse.jgit.lib.Repository repo,
|
||||
ObjectId revision)
|
||||
ObjectId revision)
|
||||
throws IOException {
|
||||
if (logger.isDebugEnabled())
|
||||
{
|
||||
@@ -392,7 +405,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
}
|
||||
|
||||
private SubRepository getSubRepository(org.eclipse.jgit.lib.Repository repo,
|
||||
ObjectId revId, String path)
|
||||
ObjectId revId, String path)
|
||||
throws IOException {
|
||||
Map<String, SubRepository> subRepositories = subrepositoryCache.get(revId);
|
||||
|
||||
@@ -413,7 +426,7 @@ public class GitBrowseCommand extends AbstractGitCommand
|
||||
}
|
||||
|
||||
//~--- fields ---------------------------------------------------------------
|
||||
|
||||
|
||||
/** sub repository cache */
|
||||
private final Map<ObjectId, Map<String, SubRepository>> subrepositoryCache = Maps.newHashMap();
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.GitUtil;
|
||||
import sonia.scm.store.Blob;
|
||||
import sonia.scm.store.BlobStore;
|
||||
import sonia.scm.util.IOUtil;
|
||||
import sonia.scm.util.Util;
|
||||
import sonia.scm.web.lfs.LfsBlobStoreFactory;
|
||||
@@ -59,6 +60,7 @@ import java.io.FilterInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
import static sonia.scm.ContextEntry.ContextBuilder.entity;
|
||||
import static sonia.scm.NotFoundException.notFound;
|
||||
@@ -126,29 +128,27 @@ public class GitCatCommand extends AbstractGitCommand implements CatCommand {
|
||||
treeWalk.setFilter(PathFilter.create(path));
|
||||
|
||||
if (treeWalk.next() && treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) {
|
||||
Attributes attributes = LfsFactory.getAttributesForPath(repo, path, entry);
|
||||
|
||||
Attribute filter = attributes.get("filter");
|
||||
if (filter != null && "lfs".equals(filter.getValue())) {
|
||||
return loadFromLfsStore(repo, treeWalk, revWalk);
|
||||
Optional<LfsPointer> lfsPointer = GitUtil.getLfsPointer(repo, path, entry, treeWalk);
|
||||
if (lfsPointer.isPresent()) {
|
||||
return loadFromLfsStore(treeWalk, revWalk, lfsPointer.get());
|
||||
} else {
|
||||
return loadFromGit(repo, treeWalk, revWalk);
|
||||
}
|
||||
|
||||
ObjectId blobId = treeWalk.getObjectId(0);
|
||||
ObjectLoader loader = repo.open(blobId);
|
||||
|
||||
return new GitObjectLoaderWrapper(loader, treeWalk, revWalk);
|
||||
} else {
|
||||
throw notFound(entity("Path", path).in("Revision", revId.getName()).in(repository));
|
||||
}
|
||||
}
|
||||
|
||||
private Loader loadFromLfsStore(Repository repo, TreeWalk treeWalk, RevWalk revWalk) throws IOException {
|
||||
private Loader loadFromGit(Repository repo, TreeWalk treeWalk, RevWalk revWalk) throws IOException {
|
||||
ObjectId blobId = treeWalk.getObjectId(0);
|
||||
LfsPointer lfsPointer;
|
||||
try (InputStream is = repo.open(blobId, Constants.OBJ_BLOB).openStream()) {
|
||||
lfsPointer = LfsPointer.parseLfsPointer(is);
|
||||
}
|
||||
Blob blob = lfsBlobStoreFactory.getLfsBlobStore(repository).get(lfsPointer.getOid().getName());
|
||||
ObjectLoader loader = repo.open(blobId);
|
||||
|
||||
return new GitObjectLoaderWrapper(loader, treeWalk, revWalk);
|
||||
}
|
||||
|
||||
private Loader loadFromLfsStore(TreeWalk treeWalk, RevWalk revWalk, LfsPointer lfsPointer) throws IOException {
|
||||
BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository);
|
||||
Blob blob = lfsBlobStore.get(lfsPointer.getOid().getName());
|
||||
GitUtil.release(revWalk);
|
||||
GitUtil.release(treeWalk);
|
||||
return new BlobLoader(blob);
|
||||
|
||||
Reference in New Issue
Block a user