public static final int LEN_SHORTLOG = 78;\r
\r
public static final int LEN_SHORTLOG_REFS = 60;\r
+ \r
+ public static final int LEN_FILESTORE_META_MIN = 125;\r
+ \r
+ public static final int LEN_FILESTORE_META_MAX = 146;\r
\r
public static final String DEFAULT_BRANCH = "default";\r
\r
import java.util.Date;
import java.util.List;
import java.util.NoSuchElementException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import com.gitblit.Constants;
/**
* A FilestoreModel represents a file stored outside a repository but referenced by the repository using a unique objectID
private static final long serialVersionUID = 1L;
+ private static final String metaRegexText = new StringBuilder()
+ .append("version\\shttps://git-lfs.github.com/spec/v1\\s+")
+ .append("oid\\ssha256:(" + Constants.REGEX_SHA256 + ")\\s+")
+ .append("size\\s([0-9]+)")
+ .toString();
+
+ private static final Pattern metaRegex = Pattern.compile(metaRegexText);
+
+ private static final int metaRegexIndexSHA = 1;
+
+ private static final int metaRegexIndexSize = 2;
+
public final String oid;
private Long size;
//Access Control
private List<String> repositories;
+ public FilestoreModel(String id, long definedSize) {
+ oid = id;
+ size = definedSize;
+ status = Status.ReferenceOnly;
+ }
+
public FilestoreModel(String id, long expectedSize, UserModel user, String repo) {
oid = id;
size = expectedSize;
repositories.add(repo);
}
+ /*
+ * Attempts to create a FilestoreModel from the given meta string
+ *
+ * @return A valid FilestoreModel if successful, otherwise null
+ */
+ public static FilestoreModel fromMetaString(String meta) {
+
+ Matcher m = metaRegex.matcher(meta);
+
+ if (m.find()) {
+ try
+ {
+ final Long size = Long.parseLong(m.group(metaRegexIndexSize));
+ final String sha = m.group(metaRegexIndexSHA);
+ return new FilestoreModel(sha, size);
+ } catch (Exception e) {
+ //Fail silent - it is not a valid filestore item
+ }
+ }
+
+ return null;
+ }
+
public synchronized long getSize() {
return size;
}
}
public synchronized void addRepository(String repo) {
- if (!repositories.contains(repo)) {
- repositories.add(repo);
- }
+ if (status != Status.ReferenceOnly) {
+ if (!repositories.contains(repo)) {
+ repositories.add(repo);
+ }
+ }
}
public synchronized void removeRepository(String repo) {
- repositories.remove(repo);
+ if (status != Status.ReferenceOnly) {
+ repositories.remove(repo);
+ }
}
public synchronized boolean isInRepositoryList(List<String> repoList) {
- for (String name : repositories) {
- if (repoList.contains(name)) {
- return true;
+ if (status != Status.ReferenceOnly) {
+ for (String name : repositories) {
+ if (repoList.contains(name)) {
+ return true;
+ }
}
}
return false;
public static enum Status {
+ ReferenceOnly(-42),
+
Deleted(-30),
AuthenticationRequired(-20),
*/\r
package com.gitblit.models;\r
\r
+import java.io.IOException;\r
import java.io.Serializable;\r
\r
import org.eclipse.jgit.diff.DiffEntry;\r
import org.eclipse.jgit.diff.DiffEntry.ChangeType;\r
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;\r
+import org.eclipse.jgit.errors.MissingObjectException;\r
+import org.eclipse.jgit.lib.Constants;\r
import org.eclipse.jgit.lib.FileMode;\r
+import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.revwalk.RevWalk;\r
+\r
+import com.gitblit.manager.FilestoreManager;\r
+import com.gitblit.utils.JGitUtils;\r
\r
/**\r
* PathModel is a serializable model class that represents a file or a folder,\r
\r
public final String name;\r
public final String path;\r
+ private final FilestoreModel filestoreItem;\r
public final long size;\r
public final int mode;\r
public final String objectId;\r
public final String commitId;\r
public boolean isParentPath;\r
-\r
- public PathModel(String name, String path, long size, int mode, String objectId, String commitId) {\r
+ \r
+ public PathModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId, String commitId) {\r
this.name = name;\r
this.path = path;\r
- this.size = size;\r
+ this.filestoreItem = filestoreItem;\r
+ this.size = (filestoreItem == null) ? size : filestoreItem.getSize();\r
this.mode = mode;\r
this.objectId = objectId;\r
this.commitId = commitId;\r
|| FileMode.EXECUTABLE_FILE.equals(mode)\r
|| (FileMode.MISSING.equals(mode) && !isSymlink() && !isSubmodule() && !isTree());\r
}\r
+ \r
+ public boolean isFilestoreItem() {\r
+ return filestoreItem != null;\r
+ }\r
+ \r
+ public String getFilestoreOid() {\r
+ if (filestoreItem != null) {\r
+ return filestoreItem.oid;\r
+ }\r
+ \r
+ return null;\r
+ }\r
\r
@Override\r
public int hashCode() {\r
\r
public int deletions;\r
\r
- public PathChangeModel(String name, String path, long size, int mode, String objectId,\r
+ public PathChangeModel(String name, String path, FilestoreModel filestoreItem, long size, int mode, String objectId,\r
String commitId, ChangeType type) {\r
- super(name, path, size, mode, objectId, commitId);\r
+ super(name, path, filestoreItem, size, mode, objectId, commitId);\r
this.changeType = type;\r
}\r
\r
return super.equals(o);\r
}\r
\r
- public static PathChangeModel from(DiffEntry diff, String commitId) {\r
+ public static PathChangeModel from(DiffEntry diff, String commitId, Repository repository) {\r
PathChangeModel pcm;\r
+ FilestoreModel filestoreItem = null;\r
+ long size = 0;\r
+\r
+ if (repository != null) {\r
+ try (RevWalk revWalk = new RevWalk(repository)) {\r
+ size = revWalk.getObjectReader().getObjectSize(diff.getNewId().toObjectId(), Constants.OBJ_BLOB);\r
+ \r
+ if (JGitUtils.isPossibleFilestoreItem(size)) {\r
+ filestoreItem = JGitUtils.getFilestoreItem(revWalk.getObjectReader().open(diff.getNewId().toObjectId()));\r
+ }\r
+ } catch (Exception e) {\r
+ e.printStackTrace();\r
+ }\r
+ }\r
+ \r
if (diff.getChangeType().equals(ChangeType.DELETE)) {\r
- pcm = new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff\r
+ pcm = new PathChangeModel(diff.getOldPath(), diff.getOldPath(), filestoreItem, size, diff\r
.getNewMode().getBits(), diff.getOldId().name(), commitId, diff\r
.getChangeType());\r
} else if (diff.getChangeType().equals(ChangeType.RENAME)) {\r
- pcm = new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff\r
+ pcm = new PathChangeModel(diff.getOldPath(), diff.getNewPath(), filestoreItem, size, diff\r
.getNewMode().getBits(), diff.getNewId().name(), commitId, diff\r
.getChangeType());\r
} else {\r
- pcm = new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff\r
+ pcm = new PathChangeModel(diff.getNewPath(), diff.getNewPath(), filestoreItem, size, diff\r
.getNewMode().getBits(), diff.getNewId().name(), commitId, diff\r
.getChangeType());\r
}\r
/**\r
* Allows authentication header to be altered based on the action requested\r
* Default is WWW-Authenticate\r
+ * @param httpRequest\r
* @param action\r
* @return authentication type header\r
*/\r
- protected String getAuthenticationHeader(String action) {\r
+ protected String getAuthenticationHeader(HttpServletRequest httpRequest, String action) {\r
return "WWW-Authenticate";\r
}\r
\r
logger.info(MessageFormat.format("ARF: CREATE CHALLENGE {0}", fullUrl));\r
}\r
\r
- httpResponse.setHeader(getAuthenticationHeader(urlRequestType), CHALLENGE);\r
+ httpResponse.setHeader(getAuthenticationHeader(httpRequest, urlRequestType), CHALLENGE);\r
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);\r
return;\r
} else {\r
if (runtimeManager.isDebugMode()) {\r
logger.info(MessageFormat.format("ARF: CHALLENGE {0}", fullUrl));\r
}\r
- httpResponse.setHeader(getAuthenticationHeader(urlRequestType), CHALLENGE);\r
+ httpResponse.setHeader(getAuthenticationHeader(httpRequest, urlRequestType), CHALLENGE);\r
httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED);\r
return;\r
} else {\r
\r
import com.google.inject.Inject;\r
import com.google.inject.Singleton;\r
+\r
import javax.servlet.ServletException;\r
import javax.servlet.http.HttpServlet;\r
import javax.servlet.http.HttpServletResponse;\r
import com.gitblit.Constants;\r
import com.gitblit.IStoredSettings;\r
import com.gitblit.Keys;\r
+import com.gitblit.manager.IFilestoreManager;\r
import com.gitblit.manager.IRepositoryManager;\r
import com.gitblit.utils.CompressionUtils;\r
import com.gitblit.utils.JGitUtils;\r
private IStoredSettings settings;\r
\r
private IRepositoryManager repositoryManager;\r
+ \r
+ private IFilestoreManager filestoreManager;\r
\r
public static enum Format {\r
zip(".zip"), tar(".tar"), gz(".tar.gz"), xz(".tar.xz"), bzip2(".tar.bzip2");\r
}\r
\r
@Inject\r
- public DownloadZipServlet(IStoredSettings settings, IRepositoryManager repositoryManager) {\r
+ public DownloadZipServlet(IStoredSettings settings, IRepositoryManager repositoryManager, IFilestoreManager filestoreManager) {\r
this.settings = settings;\r
this.repositoryManager = repositoryManager;\r
+ this.filestoreManager = filestoreManager;\r
}\r
\r
/**\r
response.setHeader("Pragma", "no-cache");\r
response.setDateHeader("Expires", 0);\r
\r
+ \r
try {\r
switch (format) {\r
case zip:\r
- CompressionUtils.zip(r, basePath, objectId, response.getOutputStream());\r
+ CompressionUtils.zip(r, filestoreManager, basePath, objectId, response.getOutputStream());\r
break;\r
case tar:\r
- CompressionUtils.tar(r, basePath, objectId, response.getOutputStream());\r
+ CompressionUtils.tar(r, filestoreManager, basePath, objectId, response.getOutputStream());\r
break;\r
case gz:\r
- CompressionUtils.gz(r, basePath, objectId, response.getOutputStream());\r
+ CompressionUtils.gz(r, filestoreManager, basePath, objectId, response.getOutputStream());\r
break;\r
case xz:\r
- CompressionUtils.xz(r, basePath, objectId, response.getOutputStream());\r
+ CompressionUtils.xz(r, filestoreManager, basePath, objectId, response.getOutputStream());\r
break;\r
case bzip2:\r
- CompressionUtils.bzip2(r, basePath, objectId, response.getOutputStream());\r
+ CompressionUtils.bzip2(r, filestoreManager, basePath, objectId, response.getOutputStream());\r
break;\r
}\r
\r
}
} else {
response.setStatus(responseObject.error.code);
- serialize(response, responseObject.error);
+
+ if (isMetaRequest) {
+ serialize(response, responseObject.error);
+ }
}
};
}\r
\r
/**\r
- * Analyze the url and returns the action of the request. Return values are\r
- * either "/git-receive-pack" or "/git-upload-pack".\r
+ * Analyze the url and returns the action of the request. Return values are:\r
+ * "/git-receive-pack", "/git-upload-pack" or "/info/lfs".\r
*\r
* @param serverUrl\r
* @return action of the request\r
\r
/**\r
* Git lfs action uses an alternative authentication header, \r
+ * dependent on the viewing method.\r
* \r
+ * @param httpRequest\r
* @param action\r
* @return\r
*/\r
@Override\r
- protected String getAuthenticationHeader(String action) {\r
+ protected String getAuthenticationHeader(HttpServletRequest httpRequest, String action) {\r
\r
if (action.equals(gitLfs)) {\r
- return "LFS-Authenticate";\r
+ if (hasContentInRequestHeader(httpRequest, "Accept", FilestoreServlet.GIT_LFS_META_MIME)) {\r
+ return "LFS-Authenticate";\r
+ }\r
}\r
\r
- return super.getAuthenticationHeader(action);\r
+ return super.getAuthenticationHeader(httpRequest, action);\r
}\r
\r
/**\r
if (pathEntries.get(0).path.indexOf('/') > -1) {
// we are in a subdirectory, add parent directory link
String pp = URLEncoder.encode(requestedPath, Constants.ENCODING);
- pathEntries.add(0, new PathModel("..", pp + "/..", 0, FileMode.TREE.getBits(), null, null));
+ pathEntries.add(0, new PathModel("..", pp + "/..", null, 0, FileMode.TREE.getBits(), null, null));
}
}
package com.gitblit.utils;\r
\r
import java.io.ByteArrayOutputStream;\r
+import java.io.EOFException;\r
+import java.io.File;\r
+import java.io.FileInputStream;\r
import java.io.IOException;\r
import java.io.OutputStream;\r
import java.text.MessageFormat;\r
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;\r
import org.apache.commons.compress.compressors.CompressorException;\r
import org.apache.commons.compress.compressors.CompressorStreamFactory;\r
+import org.apache.commons.io.IOUtils;\r
import org.eclipse.jgit.lib.Constants;\r
import org.eclipse.jgit.lib.FileMode;\r
import org.eclipse.jgit.lib.MutableObjectId;\r
+import org.eclipse.jgit.lib.ObjectId;\r
import org.eclipse.jgit.lib.ObjectLoader;\r
import org.eclipse.jgit.lib.ObjectReader;\r
import org.eclipse.jgit.lib.Repository;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
+import com.gitblit.GitBlit;\r
+import com.gitblit.manager.IFilestoreManager;\r
+import com.gitblit.models.FilestoreModel;\r
+import com.gitblit.models.FilestoreModel.Status;\r
+\r
/**\r
* Collection of static methods for retrieving information from a repository.\r
*\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- public static boolean zip(Repository repository, String basePath, String objectId,\r
+ public static boolean zip(Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
RevCommit commit = JGitUtils.getCommit(repository, objectId);\r
if (commit == null) {\r
continue;\r
}\r
tw.getObjectId(id, 0);\r
-\r
+ \r
+ ObjectLoader loader = repository.open(id);\r
+ \r
ZipArchiveEntry entry = new ZipArchiveEntry(tw.getPathString());\r
- entry.setSize(reader.getObjectSize(id, Constants.OBJ_BLOB));\r
+\r
+ FilestoreModel filestoreItem = null;\r
+ \r
+ if (JGitUtils.isPossibleFilestoreItem(loader.getSize())) {\r
+ filestoreItem = JGitUtils.getFilestoreItem(tw.getObjectReader().open(id));\r
+ }\r
+\r
+ final long size = (filestoreItem == null) ? loader.getSize() : filestoreItem.getSize(); \r
+\r
+ entry.setSize(size);\r
entry.setComment(commit.getName());\r
entry.setUnixMode(mode.getBits());\r
entry.setTime(modified);\r
zos.putArchiveEntry(entry);\r
+ \r
+ if (filestoreItem == null) {\r
+ //Copy repository stored file\r
+ loader.copyTo(zos);\r
+ } else {\r
+ //Copy filestore file\r
+ try (FileInputStream streamIn = new FileInputStream(filestoreManager.getStoragePath(filestoreItem.oid))) {\r
+ IOUtils.copyLarge(streamIn, zos);\r
+ } catch (Throwable e) {\r
+ LOGGER.error(MessageFormat.format("Failed to archive filestore item {0}", filestoreItem.oid), e);\r
+\r
+ //Handle as per other errors \r
+ throw e; \r
+ }\r
+ }\r
\r
- ObjectLoader ldr = repository.open(id);\r
- ldr.copyTo(zos);\r
zos.closeArchiveEntry();\r
}\r
zos.finish();\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- public static boolean tar(Repository repository, String basePath, String objectId,\r
+ public static boolean tar(Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
- return tar(null, repository, basePath, objectId, os);\r
+ return tar(null, repository, filestoreManager, basePath, objectId, os);\r
}\r
\r
/**\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- public static boolean gz(Repository repository, String basePath, String objectId,\r
+ public static boolean gz(Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
- return tar(CompressorStreamFactory.GZIP, repository, basePath, objectId, os);\r
+ return tar(CompressorStreamFactory.GZIP, repository, filestoreManager, basePath, objectId, os);\r
}\r
\r
/**\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- public static boolean xz(Repository repository, String basePath, String objectId,\r
+ public static boolean xz(Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
- return tar(CompressorStreamFactory.XZ, repository, basePath, objectId, os);\r
+ return tar(CompressorStreamFactory.XZ, repository, filestoreManager, basePath, objectId, os);\r
}\r
\r
/**\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- public static boolean bzip2(Repository repository, String basePath, String objectId,\r
+ public static boolean bzip2(Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
\r
- return tar(CompressorStreamFactory.BZIP2, repository, basePath, objectId, os);\r
+ return tar(CompressorStreamFactory.BZIP2, repository, filestoreManager, basePath, objectId, os);\r
}\r
\r
/**\r
* @return true if repository was successfully zipped to supplied output\r
* stream\r
*/\r
- private static boolean tar(String algorithm, Repository repository, String basePath, String objectId,\r
+ private static boolean tar(String algorithm, Repository repository, IFilestoreManager filestoreManager, String basePath, String objectId,\r
OutputStream os) {\r
RevCommit commit = JGitUtils.getCommit(repository, objectId);\r
if (commit == null) {\r
if (mode == FileMode.GITLINK || mode == FileMode.TREE) {\r
continue;\r
}\r
+ \r
tw.getObjectId(id, 0);\r
\r
ObjectLoader loader = repository.open(id);\r
TarArchiveEntry entry = new TarArchiveEntry(tw.getPathString());\r
entry.setMode(mode.getBits());\r
entry.setModTime(modified);\r
- entry.setSize(loader.getSize());\r
+\r
+ FilestoreModel filestoreItem = null;\r
+ \r
+ if (JGitUtils.isPossibleFilestoreItem(loader.getSize())) {\r
+ filestoreItem = JGitUtils.getFilestoreItem(tw.getObjectReader().open(id));\r
+ }\r
+\r
+ final long size = (filestoreItem == null) ? loader.getSize() : filestoreItem.getSize(); \r
+\r
+ entry.setSize(size);\r
tos.putArchiveEntry(entry);\r
- loader.copyTo(tos);\r
+ \r
+ if (filestoreItem == null) {\r
+ //Copy repository stored file\r
+ loader.copyTo(tos);\r
+ } else {\r
+ //Copy filestore file\r
+ try (FileInputStream streamIn = new FileInputStream(filestoreManager.getStoragePath(filestoreItem.oid))) {\r
+\r
+ IOUtils.copyLarge(streamIn, tos);\r
+ } catch (Throwable e) {\r
+ LOGGER.error(MessageFormat.format("Failed to archive filestore item {0}", filestoreItem.oid), e);\r
+\r
+ //Handle as per other errors \r
+ throw e; \r
+ }\r
+ }\r
+ \r
tos.closeArchiveEntry();\r
}\r
}\r
import org.eclipse.jgit.diff.DiffEntry;\r
import org.eclipse.jgit.diff.DiffFormatter;\r
import org.eclipse.jgit.diff.RawText;\r
+import org.eclipse.jgit.lib.Repository;\r
import org.eclipse.jgit.util.io.NullOutputStream;\r
\r
import com.gitblit.models.PathModel.PathChangeModel;\r
\r
private PathChangeModel path;\r
\r
- public DiffStatFormatter(String commitId) {\r
+ public DiffStatFormatter(String commitId, Repository repository) {\r
super(NullOutputStream.INSTANCE);\r
- diffStat = new DiffStat(commitId);\r
+ diffStat = new DiffStat(commitId, repository);\r
}\r
\r
@Override\r
public final List<PathChangeModel> paths = new ArrayList<PathChangeModel>();\r
\r
private final String commitId;\r
+ \r
+ private final Repository repository;\r
\r
- public DiffStat(String commitId) {\r
+ public DiffStat(String commitId, Repository repository) {\r
this.commitId = commitId;\r
+ this.repository = repository;\r
}\r
\r
public PathChangeModel addPath(DiffEntry entry) {\r
- PathChangeModel pcm = PathChangeModel.from(entry, commitId);\r
+ PathChangeModel pcm = PathChangeModel.from(entry, commitId, repository);\r
paths.add(pcm);\r
return pcm;\r
}\r
DiffFormatter df;\r
switch (outputType) {\r
case HTML:\r
- df = new GitBlitDiffFormatter(commit.getName(), path, handler, tabLength);\r
+ df = new GitBlitDiffFormatter(commit.getName(), repository, path, handler, tabLength);\r
break;\r
case PLAIN:\r
default:\r
DiffStat stat = null;\r
try {\r
RawTextComparator cmp = RawTextComparator.DEFAULT;\r
- DiffStatFormatter df = new DiffStatFormatter(commit.getName());\r
+ DiffStatFormatter df = new DiffStatFormatter(commit.getName(), repository);\r
df.setRepository(repository);\r
df.setDiffComparator(cmp);\r
df.setDetectRenames(true);\r
import org.eclipse.jgit.diff.DiffEntry.ChangeType;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.diff.RawText;
+import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.util.RawParseUtils;
import com.gitblit.models.PathModel.PathChangeModel;
}
- public GitBlitDiffFormatter(String commitId, String path, BinaryDiffHandler handler, int tabLength) {
+ public GitBlitDiffFormatter(String commitId, Repository repository, String path, BinaryDiffHandler handler, int tabLength) {
super(new DiffOutputStream());
this.os = (DiffOutputStream) getOutputStream();
this.os.setFormatter(this, handler);
- this.diffStat = new DiffStat(commitId);
+ this.diffStat = new DiffStat(commitId, repository);
this.tabLength = tabLength;
// If we have a full commitdiff, install maxima to avoid generating a super-long diff listing that
// will only tax the browser too much.
import java.util.List;\r
import java.util.Map;\r
import java.util.Map.Entry;\r
+import java.util.regex.Matcher;\r
import java.util.regex.Pattern;\r
\r
import org.apache.commons.io.filefilter.TrueFileFilter;\r
import org.eclipse.jgit.diff.RawTextComparator;\r
import org.eclipse.jgit.errors.ConfigInvalidException;\r
import org.eclipse.jgit.errors.IncorrectObjectTypeException;\r
+import org.eclipse.jgit.errors.LargeObjectException;\r
import org.eclipse.jgit.errors.MissingObjectException;\r
import org.eclipse.jgit.errors.StopWalkException;\r
import org.eclipse.jgit.lib.BlobBasedConfig;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
+import com.gitblit.GitBlit;\r
import com.gitblit.GitBlitException;\r
+import com.gitblit.manager.GitblitManager;\r
+import com.gitblit.models.FilestoreModel;\r
import com.gitblit.models.GitNote;\r
import com.gitblit.models.PathModel;\r
import com.gitblit.models.PathModel.PathChangeModel;\r
import com.gitblit.models.RefModel;\r
import com.gitblit.models.SubmoduleModel;\r
+import com.gitblit.servlet.FilestoreServlet;\r
import com.google.common.base.Strings;\r
\r
/**\r
tw.setRecursive(true);\r
tw.addTree(commit.getTree());\r
while (tw.next()) {\r
- list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw\r
- .getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(),\r
+ long size = 0;\r
+ FilestoreModel filestoreItem = null;\r
+ ObjectId objectId = tw.getObjectId(0);\r
+ \r
+ try {\r
+ if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {\r
+\r
+ size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB);\r
+\r
+ if (isPossibleFilestoreItem(size)) {\r
+ filestoreItem = getFilestoreItem(tw.getObjectReader().open(objectId));\r
+ }\r
+ }\r
+ } catch (Throwable t) {\r
+ error(t, null, "failed to retrieve blob size for " + tw.getPathString());\r
+ }\r
+ \r
+ list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(),filestoreItem, size, tw\r
+ .getRawMode(0), objectId.getName(), commit.getId().getName(),\r
ChangeType.ADD));\r
}\r
tw.close();\r
} else {\r
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());\r
- DiffStatFormatter df = new DiffStatFormatter(commit.getName());\r
+ DiffStatFormatter df = new DiffStatFormatter(commit.getName(), repository);\r
df.setRepository(repository);\r
df.setDiffComparator(RawTextComparator.DEFAULT);\r
df.setDetectRenames(true);\r
List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());\r
for (DiffEntry diff : diffs) {\r
// create the path change model\r
- PathChangeModel pcm = PathChangeModel.from(diff, commit.getName());\r
-\r
- if (calculateDiffStat) {\r
+ PathChangeModel pcm = PathChangeModel.from(diff, commit.getName(), repository);\r
+ \r
+ if (calculateDiffStat) {\r
// update file diffstats\r
df.format(diff);\r
PathChangeModel pathStat = df.getDiffStat().getPath(pcm.path);\r
\r
List<DiffEntry> diffEntries = df.scan(startCommit.getTree(), endCommit.getTree());\r
for (DiffEntry diff : diffEntries) {\r
- PathChangeModel pcm = PathChangeModel.from(diff, endCommit.getName());\r
+ PathChangeModel pcm = PathChangeModel.from(diff, endCommit.getName(), repository);\r
list.add(pcm);\r
}\r
Collections.sort(list);\r
private static PathModel getPathModel(TreeWalk tw, String basePath, RevCommit commit) {\r
String name;\r
long size = 0;\r
+ \r
if (StringUtils.isEmpty(basePath)) {\r
name = tw.getPathString();\r
} else {\r
name = tw.getPathString().substring(basePath.length() + 1);\r
}\r
ObjectId objectId = tw.getObjectId(0);\r
+ FilestoreModel filestoreItem = null;\r
+ \r
try {\r
if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {\r
+\r
size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB);\r
+\r
+ if (isPossibleFilestoreItem(size)) {\r
+ filestoreItem = getFilestoreItem(tw.getObjectReader().open(objectId));\r
+ }\r
}\r
} catch (Throwable t) {\r
error(t, null, "failed to retrieve blob size for " + tw.getPathString());\r
}\r
- return new PathModel(name, tw.getPathString(), size, tw.getFileMode(0).getBits(),\r
+ return new PathModel(name, tw.getPathString(), filestoreItem, size, tw.getFileMode(0).getBits(),\r
objectId.getName(), commit.getName());\r
}\r
+ \r
+ public static boolean isPossibleFilestoreItem(long size) {\r
+ return ( (size >= com.gitblit.Constants.LEN_FILESTORE_META_MIN) \r
+ && (size <= com.gitblit.Constants.LEN_FILESTORE_META_MAX));\r
+ }\r
+ \r
+ /**\r
+ * \r
+ * @return Representative FilestoreModel if valid, otherwise null\r
+ */\r
+ public static FilestoreModel getFilestoreItem(ObjectLoader obj){\r
+ try {\r
+ final byte[] blob = obj.getCachedBytes(com.gitblit.Constants.LEN_FILESTORE_META_MAX);\r
+ final String meta = new String(blob, "UTF-8");\r
+ \r
+ return FilestoreModel.fromMetaString(meta);\r
+\r
+ } catch (LargeObjectException e) {\r
+ //Intentionally failing silent\r
+ } catch (Exception e) {\r
+ error(e, null, "failed to retrieve filestoreItem " + obj.toString());\r
+ }\r
+ \r
+ return null;\r
+ }\r
\r
/**\r
* Returns a path model by path string\r
throws IOException {\r
\r
long size = 0;\r
+ FilestoreModel filestoreItem = null;\r
TreeWalk tw = TreeWalk.forPath(repo, path, commit.getTree());\r
String pathString = path;\r
\r
- if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {\r
- size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB);\r
- pathString = PathUtils.getLastPathComponent(pathString);\r
-\r
- } else if (tw.isSubtree()) {\r
+ if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {\r
\r
- // do not display dirs that are behind in the path\r
- if (!Strings.isNullOrEmpty(filter)) {\r
- pathString = path.replaceFirst(filter + "/", "");\r
- }\r
+ pathString = PathUtils.getLastPathComponent(pathString);\r
+ \r
+ size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB);\r
+ \r
+ if (isPossibleFilestoreItem(size)) {\r
+ filestoreItem = getFilestoreItem(tw.getObjectReader().open(tw.getObjectId(0)));\r
+ }\r
+ } else if (tw.isSubtree()) {\r
\r
- // remove the last slash from path in displayed link\r
- if (pathString != null && pathString.charAt(pathString.length()-1) == '/') {\r
- pathString = pathString.substring(0, pathString.length()-1);\r
- }\r
+ // do not display dirs that are behind in the path\r
+ if (!Strings.isNullOrEmpty(filter)) {\r
+ pathString = path.replaceFirst(filter + "/", "");\r
}\r
\r
- return new PathModel(pathString, tw.getPathString(), size, tw.getFileMode(0).getBits(),\r
- tw.getObjectId(0).getName(), commit.getName());\r
+ // remove the last slash from path in displayed link\r
+ if (pathString != null && pathString.charAt(pathString.length()-1) == '/') {\r
+ pathString = pathString.substring(0, pathString.length()-1);\r
+ }\r
+ }\r
\r
+ return new PathModel(pathString, tw.getPathString(), filestoreItem, size, tw.getFileMode(0).getBits(),\r
+ tw.getObjectId(0).getName(), commit.getName());\r
\r
}\r
\r
}\r
return new MergeResult(MergeStatus.FAILED, null);\r
}\r
+ \r
+ \r
+ /**\r
+ * Returns the LFS URL for the given oid \r
+ * Currently assumes that the Gitblit Filestore is used \r
+ *\r
+ * @param baseURL\r
+ * @param repository name\r
+ * @param oid of lfs item\r
+ * @return the lfs item URL\r
+ */\r
+ public static String getLfsRepositoryUrl(String baseURL, String repositoryName, String oid) {\r
+ \r
+ if (baseURL.length() > 0 && baseURL.charAt(baseURL.length() - 1) == '/') {\r
+ baseURL = baseURL.substring(0, baseURL.length() - 1);\r
+ }\r
+ \r
+ return baseURL + com.gitblit.Constants.R_PATH \r
+ + repositoryName + "/" \r
+ + com.gitblit.Constants.R_LFS \r
+ + "objects/" + oid;\r
+ \r
+ }\r
}\r
import org.apache.wicket.behavior.SimpleAttributeModifier;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
+import org.apache.wicket.markup.html.link.ExternalLink;\r
import org.apache.wicket.markup.repeater.Item;\r
import org.apache.wicket.markup.repeater.data.DataView;\r
import org.apache.wicket.markup.repeater.data.ListDataProvider;\r
final BlameType activeBlameType = BlameType.get(blameTypeParam);\r
\r
RevCommit commit = getCommit();\r
-\r
- add(new BookmarkablePageLink<Void>("blobLink", BlobPage.class,\r
- WicketUtils.newPathParameter(repositoryName, objectId, blobPath)));\r
+ \r
+ PathModel pathModel = null;\r
+ \r
+ List<PathModel> paths = JGitUtils.getFilesInPath(getRepository(), StringUtils.getRootPath(blobPath), commit);\r
+ for (PathModel path : paths) {\r
+ if (path.path.equals(blobPath)) {\r
+ pathModel = path;\r
+ break;\r
+ }\r
+ }\r
+ \r
+ if (pathModel == null) {\r
+ final String notFound = MessageFormat.format("Blame page failed to find {0} in {1} @ {2}",\r
+ blobPath, repositoryName, objectId);\r
+ logger.error(notFound);\r
+ add(new Label("annotation").setVisible(false));\r
+ add(new Label("missingBlob", missingBlob(blobPath, commit)).setEscapeModelStrings(false));\r
+ return;\r
+ }\r
+ \r
+ if (pathModel.isFilestoreItem()) {\r
+ String rawUrl = JGitUtils.getLfsRepositoryUrl(getContextUrl(), repositoryName, pathModel.getFilestoreOid());\r
+ add(new ExternalLink("blobLink", rawUrl));\r
+ } else {\r
+ add(new BookmarkablePageLink<Void>("blobLink", BlobPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, objectId, blobPath))); \r
+ }\r
+ \r
add(new BookmarkablePageLink<Void>("commitLink", CommitPage.class,\r
WicketUtils.newObjectParameter(repositoryName, objectId)));\r
add(new BookmarkablePageLink<Void>("commitDiffLink", CommitDiffPage.class,\r
final DateFormat df = new SimpleDateFormat(format);\r
df.setTimeZone(getTimeZone());\r
\r
- PathModel pathModel = null;\r
- List<PathModel> paths = JGitUtils.getFilesInPath(getRepository(), StringUtils.getRootPath(blobPath), commit);\r
- for (PathModel path : paths) {\r
- if (path.path.equals(blobPath)) {\r
- pathModel = path;\r
- break;\r
- }\r
- }\r
+ \r
\r
- if (pathModel == null) {\r
- final String notFound = MessageFormat.format("Blame page failed to find {0} in {1} @ {2}",\r
- blobPath, repositoryName, objectId);\r
- logger.error(notFound);\r
- add(new Label("annotation").setVisible(false));\r
- add(new Label("missingBlob", missingBlob(blobPath, commit)).setEscapeModelStrings(false));\r
- return;\r
- }\r
+ \r
\r
add(new Label("missingBlob").setVisible(false));\r
\r
<td class="changeType"><span wicket:id="changeType">[change type]</span></td> \r
<td class="path"><span wicket:id="pathName">[commit path]</span></td> \r
<td class="hidden-phone rightAlign">\r
+ <span wicket:id="filestore" style="margin-right:20px;" class="aui-lozenge aui-lozenge-moved"></span>\r
<span class="hidden-tablet" style="padding-right:20px;" wicket:id="diffStat"></span>\r
<span class="link">\r
<span class="hidden-tablet"><a wicket:id="patch"><wicket:message key="gb.patch"></wicket:message></a> | </span><a wicket:id="view"><wicket:message key="gb.view"></wicket:message></a><span class="hidden-tablet"> | <a wicket:id="raw"><wicket:message key="gb.raw"></wicket:message></a></span> | <a wicket:id="blame"><wicket:message key="gb.blame"></wicket:message></a> | <a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a>\r
@Override
public void populateItem(final Item<PathChangeModel> item) {
final PathChangeModel entry = item.getModelObject();
+ final String filestoreItemUrl = entry.isFilestoreItem() ? JGitUtils.getLfsRepositoryUrl(getContextUrl(), repositoryName, entry.getFilestoreOid()) : null;
+
Label changeType = new Label("changeType", "");
WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);
setChangeTypeTooltip(changeType, entry.changeType);
boolean hasSubmodule = false;
String submodulePath = null;
+
if (entry.isTree()) {
// tree
item.add(new LinkPanel("pathName", null, entry.path, TreePage.class,
item.add(new LinkPanel("pathName", "list", entry.path + " @ " + getShortObjectId(submoduleId), "#n" + entry.objectId));
} else {
// add relative link
- item.add(new LinkPanel("pathName", "list", entry.path, "#n" + entry.objectId));
+ item.add(new LinkPanel("pathName", "list", entry.path, entry.isFilestoreItem() ? filestoreItemUrl : "#n" + entry.objectId));
}
// quick links
if (entry.isSubmodule()) {
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));
+
item.add(new ExternalLink("raw", "").setEnabled(false));
// submodule
item.add(new ExternalLink("patch", "").setEnabled(false));
.newPathParameter(repositoryName, entry.commitId, entry.path))
.setEnabled(!entry.changeType.equals(ChangeType.ADD)
&& !entry.changeType.equals(ChangeType.DELETE)));
- item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
- .newPathParameter(repositoryName, entry.commitId, entry.path))
- .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
- String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path);
- item.add(new ExternalLink("raw", rawUrl)
- .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
+
+ if (entry.isFilestoreItem()) {
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(true));
+
+ item.add(new ExternalLink("view", filestoreItemUrl));
+ item.add(new ExternalLink("raw", filestoreItemUrl));
+ } else {
+
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));
+
+ item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils
+ .newPathParameter(repositoryName, entry.commitId, entry.path))
+ .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
+
+ item.add(new ExternalLink("raw", RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path))
+ .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));
+ }
+
item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils
.newPathParameter(repositoryName, entry.commitId, entry.path))
.setEnabled(!entry.changeType.equals(ChangeType.ADD)
<table class="pretty">\r
<tr wicket:id="changedPath">\r
<td class="changeType"><span wicket:id="changeType">[change type]</span></td>\r
- <td class="path"><span wicket:id="pathName">[commit path]</span></td> \r
+ <td class="path"><span wicket:id="pathName">[commit path]</span></td> \r
<td class="hidden-phone rightAlign">\r
+ <span wicket:id="filestore" style="margin-right:20px;" class="aui-lozenge aui-lozenge-moved"></span>\r
<span class="hidden-tablet" style="padding-right:20px;" wicket:id="diffStat"></span>\r
<span class="link">\r
<a wicket:id="diff"><wicket:message key="gb.diff"></wicket:message></a> | <span class="hidden-tablet"><a wicket:id="view"><wicket:message key="gb.view"></wicket:message></a> | <a wicket:id="raw"><wicket:message key="gb.raw"></wicket:message></a> | </span><a wicket:id="blame"><wicket:message key="gb.blame"></wicket:message></a> | <a wicket:id="history"><wicket:message key="gb.history"></wicket:message></a>\r
@Override\r
public void populateItem(final Item<PathChangeModel> item) {\r
final PathChangeModel entry = item.getModelObject();\r
+ final String filestoreItemUrl = entry.isFilestoreItem() ? JGitUtils.getLfsRepositoryUrl(getContextUrl(), repositoryName, entry.getFilestoreOid()) : null;\r
+ \r
Label changeType = new Label("changeType", "");\r
WicketUtils.setChangeTypeCssClass(changeType, entry.changeType);\r
setChangeTypeTooltip(changeType, entry.changeType);\r
path = JGitUtils.getStringContent(getRepository(), getCommit().getTree(), path);\r
displayPath = entry.path + " -> " + path;\r
}\r
- item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,\r
- WicketUtils\r
- .newPathParameter(repositoryName, entry.commitId, path)));\r
+ \r
+ if (entry.isFilestoreItem()) {\r
+ item.add(new LinkPanel("pathName", "list", entry.path, filestoreItemUrl));\r
+ } else {\r
+ item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, entry.commitId, path)));\r
+ }\r
}\r
\r
\r
if (entry.isSubmodule()) {\r
item.add(new ExternalLink("raw", "").setEnabled(false));\r
\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
+ \r
// submodule\r
item.add(new BookmarkablePageLink<Void>("diff", BlobDiffPage.class, WicketUtils\r
.newPathParameter(repositoryName, entry.commitId, entry.path))\r
.newPathParameter(repositoryName, entry.commitId, entry.path))\r
.setEnabled(!entry.changeType.equals(ChangeType.ADD)\r
&& !entry.changeType.equals(ChangeType.DELETE)));\r
- item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils\r
- .newPathParameter(repositoryName, entry.commitId, entry.path))\r
- .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));\r
- String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path);\r
- item.add(new ExternalLink("raw", rawUrl)\r
- .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));\r
+ \r
+ if (entry.isFilestoreItem()) {\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(true));\r
+ \r
+ item.add(new ExternalLink("view", filestoreItemUrl));\r
+ item.add(new ExternalLink("raw", filestoreItemUrl));\r
+ } else {\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
+ \r
+ item.add(new BookmarkablePageLink<Void>("view", BlobPage.class, WicketUtils\r
+ .newPathParameter(repositoryName, entry.commitId, entry.path))\r
+ .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));\r
+ String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, entry.commitId, entry.path);\r
+ item.add(new ExternalLink("raw", rawUrl)\r
+ .setEnabled(!entry.changeType.equals(ChangeType.DELETE)));\r
+ }\r
item.add(new BookmarkablePageLink<Void>("blame", BlamePage.class, WicketUtils\r
.newPathParameter(repositoryName, entry.commitId, entry.path))\r
.setEnabled(!entry.changeType.equals(ChangeType.ADD)\r
import com.gitblit.wicket.CacheControl;
import com.gitblit.wicket.FilestoreUI;
import com.gitblit.wicket.GitBlitWebSession;
-import com.gitblit.wicket.RequiresAdminRole;
import com.gitblit.wicket.WicketUtils;
import com.gitblit.wicket.CacheControl.LastModified;
<table style="width:100%" class="pretty">\r
<tr wicket:id="changedPath">\r
<td class="hidden-phone icon"><img wicket:id="pathIcon" /></td>\r
- <td><span wicket:id="pathName"></span></td> \r
+ <td><span wicket:id="pathName"></span></td>\r
+ <td class="hidden-phone filestore"><span wicket:id="filestore" class="aui-lozenge aui-lozenge-moved"></span></td>\r
<td class="hidden-phone size"><span wicket:id="pathSize">[path size]</span></td>\r
<td class="hidden-phone mode"><span wicket:id="pathPermissions">[path permissions]</span></td>\r
<td class="treeLinks"><span wicket:id="pathLinks">[path links]</span></td>\r
if (path.lastIndexOf('/') > -1) {\r
parentPath = path.substring(0, path.lastIndexOf('/'));\r
}\r
- PathModel model = new PathModel("..", parentPath, 0, FileMode.TREE.getBits(), null, objectId);\r
+ PathModel model = new PathModel("..", parentPath, null, 0, FileMode.TREE.getBits(), null, objectId);\r
model.isParentPath = true;\r
paths.add(0, model);\r
}\r
\r
final String id = getBestCommitId(commit);\r
+ \r
final ByteFormat byteFormat = new ByteFormat();\r
final String baseUrl = WicketUtils.getGitblitURL(getRequest());\r
\r
@Override\r
public void populateItem(final Item<PathModel> item) {\r
PathModel entry = item.getModelObject();\r
+ \r
item.add(new Label("pathPermissions", JGitUtils.getPermissionsFromMode(entry.mode)));\r
+ \r
if (entry.isParentPath) {\r
// parent .. path\r
item.add(WicketUtils.newBlankImage("pathIcon"));\r
item.add(new LinkPanel("pathName", null, entry.name, TreePage.class,\r
WicketUtils\r
.newPathParameter(repositoryName, id, entry.path)));\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
item.add(new Label("pathLinks", ""));\r
} else {\r
if (entry.isTree()) {\r
WicketUtils.newPathParameter(repositoryName, id,\r
entry.path)));\r
\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
+\r
// links\r
Fragment links = new Fragment("pathLinks", "treeLinks", this);\r
links.add(new BookmarkablePageLink<Void>("tree", TreePage.class,\r
getShortObjectId(submoduleId), TreePage.class,\r
WicketUtils.newPathParameter(submodulePath, submoduleId, "")).setEnabled(hasSubmodule));\r
\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
+ \r
Fragment links = new Fragment("pathLinks", "submoduleLinks", this);\r
links.add(new BookmarkablePageLink<Void>("view", SummaryPage.class,\r
WicketUtils.newRepositoryParameter(submodulePath)).setEnabled(hasSubmodule));\r
}\r
item.add(WicketUtils.getFileImage("pathIcon", entry.name));\r
item.add(new Label("pathSize", byteFormat.format(entry.size)));\r
- item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,\r
- WicketUtils.newPathParameter(repositoryName, id,\r
- path)));\r
-\r
+ \r
// links\r
Fragment links = new Fragment("pathLinks", "blobLinks", this);\r
- links.add(new BookmarkablePageLink<Void>("view", BlobPage.class,\r
- WicketUtils.newPathParameter(repositoryName, id,\r
- path)));\r
- String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, id, path);\r
- links.add(new ExternalLink("raw", rawUrl));\r
+ \r
+ if (entry.isFilestoreItem()) {\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(true));\r
+ \r
+ final String filestoreItemUrl = JGitUtils.getLfsRepositoryUrl(getContextUrl(), repositoryName, entry.getFilestoreOid());\r
+ \r
+ item.add(new LinkPanel("pathName", "list", displayPath, filestoreItemUrl));\r
+ links.add(new ExternalLink("view", filestoreItemUrl));\r
+ links.add(new ExternalLink("raw", filestoreItemUrl));\r
+ \r
+ } else {\r
+ item.add(new Label("filestore", getString("gb.filestore")).setVisible(false));\r
+ \r
+ item.add(new LinkPanel("pathName", "list", displayPath, BlobPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, id,\r
+ path)));\r
+ \r
+ links.add(new BookmarkablePageLink<Void>("view", BlobPage.class,\r
+ WicketUtils.newPathParameter(repositoryName, id,\r
+ path)));\r
+ String rawUrl = RawServlet.asLink(getContextUrl(), repositoryName, id, path);\r
+ links.add(new ExternalLink("raw", rawUrl));\r
+ }\r
+ \r
links.add(new BookmarkablePageLink<Void>("blame", BlamePage.class,\r
WicketUtils.newPathParameter(repositoryName, id,\r
path)));\r
tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));\r
while (tw.next()) {\r
if (tw.getPathString().equals(path)) {\r
- matchingPath = new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw\r
+ matchingPath = new PathChangeModel(tw.getPathString(), tw.getPathString(), null, 0, tw\r
.getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(),\r
ChangeType.MODIFY);\r
}\r
padding-right:15px;\r
}\r
\r
+td.filestore {\r
+ text-align: right;\r
+ width:1em;\r
+ padding-right:15px;\r
+}\r
+\r
td.size {\r
text-align: right;\r
width: 8em; \r
\r
@Test\r
public void testZip() throws Exception {\r
- assertFalse(CompressionUtils.zip(null, null, null, null));\r
+ assertFalse(CompressionUtils.zip(null, null, null, null, null));\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
File zipFileA = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip");\r
FileOutputStream fosA = new FileOutputStream(zipFileA);\r
- boolean successA = CompressionUtils.zip(repository, null, Constants.HEAD, fosA);\r
+ boolean successA = CompressionUtils.zip(repository, null, null, Constants.HEAD, fosA);\r
fosA.close();\r
\r
File zipFileB = new File(GitBlitSuite.REPOSITORIES, "helloworld-java.zip");\r
FileOutputStream fosB = new FileOutputStream(zipFileB);\r
- boolean successB = CompressionUtils.zip(repository, "java.java", Constants.HEAD, fosB);\r
+ boolean successB = CompressionUtils.zip(repository, null, "java.java", Constants.HEAD, fosB);\r
fosB.close();\r
\r
repository.close();\r