Compute LFS attributes on top commit

In the previous version, the LFS attributes were read for the latest
commit of the file. This is not the way, a git client handles LFS files.
Therefore we switch to the way, the native git client works and read the
attributes from the commit of the command.
This commit is contained in:
Rene Pfeuffer
2019-12-13 14:41:36 +01:00
parent 8410e7e679
commit 5e47ef0323
2 changed files with 42 additions and 34 deletions

View File

@@ -745,6 +745,10 @@ 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);
return getLfsPointer(repo, treeWalk, attributes);
}
public static Optional<LfsPointer> getLfsPointer(org.eclipse.jgit.lib.Repository repo, TreeWalk treeWalk, Attributes attributes) throws IOException {
Attribute filter = attributes.get("filter");
if (filter != null && "lfs".equals(filter.getValue())) {
ObjectId blobId = treeWalk.getObjectId(0);

View File

@@ -39,6 +39,7 @@ import com.google.common.base.Stopwatch;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.eclipse.jgit.attributes.Attributes;
import org.eclipse.jgit.lfs.LfsPointer;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
@@ -50,6 +51,7 @@ import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.eclipse.jgit.util.LfsFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.NotFoundException;
@@ -186,8 +188,20 @@ public class GitBrowseCommand extends AbstractGitCommand
if (!file.isDirectory() &&!request.isDisableLastCommit())
{
file.setPartialResult(true);
RevCommit commit;
try (RevWalk walk = new RevWalk(repo)) {
commit = walk.parseCommit(revId);
}
Optional<LfsPointer> lfsPointer = getLfsPointer(repo, path, commit, treeWalk);
if (lfsPointer.isPresent()) {
setFileLengthFromLfsBlob(lfsPointer.get(), file);
} else {
file.setLength(loader.getSize());
}
executor.execute(
new CompleteFileInformation(path, revId, repo, treeWalk, file, loader, request),
new CompleteFileInformation(path, revId, repo, file, request),
new AbortFileInformation(request)
);
}
@@ -315,22 +329,40 @@ public class GitBrowseCommand extends AbstractGitCommand
return null;
}
private Optional<LfsPointer> getLfsPointer(org.eclipse.jgit.lib.Repository repo, String path, RevCommit commit, TreeWalk treeWalk) {
try {
Attributes attributes = LfsFactory.getAttributesForPath(repo, path, commit);
return GitUtil.getLfsPointer(repo, treeWalk, attributes);
} catch (IOException e) {
throw new InternalRepositoryException(repository, "could not read lfs pointer", e);
}
}
private void setFileLengthFromLfsBlob(LfsPointer lfsPointer, FileObject file) {
BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository);
String oid = lfsPointer.getOid().getName();
Blob blob = lfsBlobStore.get(oid);
if (blob == null) {
logger.error("lfs blob for lob id {} not found in lfs store of repository {}", oid, repository.getNamespaceAndName());
file.setLength(-1);
} else {
file.setLength(blob.getSize());
}
}
private class CompleteFileInformation implements Consumer<SyncAsyncExecutor.ExecutionType> {
private final String path;
private final ObjectId revId;
private final org.eclipse.jgit.lib.Repository repo;
private final TreeWalk treeWalk;
private final FileObject file;
private final ObjectLoader loader;
private final BrowseCommandRequest request;
public CompleteFileInformation(String path, ObjectId revId, org.eclipse.jgit.lib.Repository repo, TreeWalk treeWalk, FileObject file, ObjectLoader loader, BrowseCommandRequest request) {
public CompleteFileInformation(String path, ObjectId revId, org.eclipse.jgit.lib.Repository repo, FileObject file, BrowseCommandRequest request) {
this.path = path;
this.revId = revId;
this.repo = repo;
this.treeWalk = treeWalk;
this.file = file;
this.loader = loader;
this.request = request;
}
@@ -342,15 +374,7 @@ public class GitBrowseCommand extends AbstractGitCommand
Optional<RevCommit> commit = getLatestCommit(repo, revId, path);
Optional<LfsPointer> lfsPointer = commit.flatMap(this::getLfsPointer);
synchronized (asyncMonitor) {
if (lfsPointer.isPresent()) {
setFileLengthFromLfsBlob(lfsPointer.get());
} else {
file.setLength(loader.getSize());
}
file.setPartialResult(false);
if (commit.isPresent()) {
applyValuesFromCommit(executionType, commit.get());
@@ -377,18 +401,6 @@ public class GitBrowseCommand extends AbstractGitCommand
}
}
private void setFileLengthFromLfsBlob(LfsPointer lfsPointer) {
BlobStore lfsBlobStore = lfsBlobStoreFactory.getLfsBlobStore(repository);
String oid = lfsPointer.getOid().getName();
Blob blob = lfsBlobStore.get(oid);
if (blob == null) {
logger.error("lfs blob for lob id {} not found in lfs store of repository {}", oid, repository.getNamespaceAndName());
file.setLength(-1);
} else {
file.setLength(blob.getSize());
}
}
private void applyValuesFromCommit(SyncAsyncExecutor.ExecutionType executionType, RevCommit commit) {
file.setLastModified(GitUtil.getCommitTime(commit));
file.setDescription(commit.getShortMessage());
@@ -396,14 +408,6 @@ public class GitBrowseCommand extends AbstractGitCommand
updateCache(request);
}
}
private Optional<LfsPointer> getLfsPointer(RevCommit commit) {
try {
return GitUtil.getLfsPointer(repo, path, commit, treeWalk);
} catch (IOException e) {
throw new InternalRepositoryException(repository, "could not read lfs pointer", e);
}
}
}
private class AbortFileInformation implements Runnable {