mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-06 05:25:50 +01:00
(refs #303)Submodule support
This commit is contained in:
@@ -95,7 +95,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
} map { objectId =>
|
} map { objectId =>
|
||||||
if(raw){
|
if(raw){
|
||||||
// Download
|
// Download
|
||||||
defining(JGitUtil.getContent(git, objectId, false).get){ bytes =>
|
defining(JGitUtil.getContentFromId(git, objectId, false).get){ bytes =>
|
||||||
contentType = FileUtil.getContentType(path, bytes)
|
contentType = FileUtil.getContentType(path, bytes)
|
||||||
bytes
|
bytes
|
||||||
}
|
}
|
||||||
@@ -103,7 +103,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
// Viewer
|
// Viewer
|
||||||
val large = FileUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize)
|
val large = FileUtil.isLarge(git.getRepository.getObjectDatabase.open(objectId).getSize)
|
||||||
val viewer = if(FileUtil.isImage(path)) "image" else if(large) "large" else "other"
|
val viewer = if(FileUtil.isImage(path)) "image" else if(large) "large" else "other"
|
||||||
val bytes = if(viewer == "other") JGitUtil.getContent(git, objectId, false) else None
|
val bytes = if(viewer == "other") JGitUtil.getContentFromId(git, objectId, false) else None
|
||||||
|
|
||||||
val content = if(viewer == "other"){
|
val content = if(viewer == "other"){
|
||||||
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
if(bytes.isDefined && FileUtil.isText(bytes.get)){
|
||||||
@@ -208,7 +208,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
while(walk.next){
|
while(walk.next){
|
||||||
val name = walk.getPathString
|
val name = walk.getPathString
|
||||||
val mode = walk.getFileMode(0)
|
val mode = walk.getFileMode(0)
|
||||||
if(mode != FileMode.TREE){
|
if(mode == FileMode.REGULAR_FILE){
|
||||||
walk.getObjectId(objectId, 0)
|
walk.getObjectId(objectId, 0)
|
||||||
val entry = new ZipEntry(name)
|
val entry = new ZipEntry(name)
|
||||||
val loader = reader.open(objectId)
|
val loader = reader.open(objectId)
|
||||||
@@ -277,7 +277,8 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
|||||||
val readme = files.find { file =>
|
val readme = files.find { file =>
|
||||||
readmeFiles.contains(file.name.toLowerCase)
|
readmeFiles.contains(file.name.toLowerCase)
|
||||||
}.map { file =>
|
}.map { file =>
|
||||||
file -> StringUtil.convertFromByteArray(JGitUtil.getContent(Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get)
|
file -> StringUtil.convertFromByteArray(JGitUtil.getContentFromId(
|
||||||
|
Git.open(getRepositoryDir(repository.owner, repository.name)), file.id, true).get)
|
||||||
}
|
}
|
||||||
|
|
||||||
repo.html.files(revision, repository,
|
repo.html.files(revision, repository,
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ RepositorySearchService { self: IssuesService =>
|
|||||||
val list = new ListBuffer[(String, String)]
|
val list = new ListBuffer[(String, String)]
|
||||||
|
|
||||||
while (treeWalk.next()) {
|
while (treeWalk.next()) {
|
||||||
if(treeWalk.getFileMode(0) != FileMode.TREE){
|
if(treeWalk.getFileMode(0) == FileMode.REGULAR_FILE){
|
||||||
JGitUtil.getContent(git, treeWalk.getObjectId(0), false).foreach { bytes =>
|
JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).foreach { bytes =>
|
||||||
if(FileUtil.isText(bytes)){
|
if(FileUtil.isText(bytes)){
|
||||||
val text = StringUtil.convertFromByteArray(bytes)
|
val text = StringUtil.convertFromByteArray(bytes)
|
||||||
val lowerText = text.toLowerCase
|
val lowerText = text.toLowerCase
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ trait WikiService {
|
|||||||
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
} else {
|
} else {
|
||||||
created = false
|
created = false
|
||||||
updated = JGitUtil.getContent(git, tree.getEntryObjectId, true).map(new String(_, "UTF-8") != content).getOrElse(false)
|
updated = JGitUtil.getContentFromId(git, tree.getEntryObjectId, true).map(new String(_, "UTF-8") != content).getOrElse(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -268,35 +268,35 @@ trait WikiService {
|
|||||||
*/
|
*/
|
||||||
def deleteWikiPage(owner: String, repository: String, pageName: String,
|
def deleteWikiPage(owner: String, repository: String, pageName: String,
|
||||||
committer: String, mailAddress: String, message: String): Unit = {
|
committer: String, mailAddress: String, message: String): Unit = {
|
||||||
LockUtil.lock(s"${owner}/${repository}/wiki"){
|
LockUtil.lock(s"${owner}/${repository}/wiki"){
|
||||||
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
|
using(Git.open(Directory.getWikiRepositoryDir(owner, repository))){ git =>
|
||||||
val builder = DirCache.newInCore.builder()
|
val builder = DirCache.newInCore.builder()
|
||||||
val inserter = git.getRepository.newObjectInserter()
|
val inserter = git.getRepository.newObjectInserter()
|
||||||
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
val headId = git.getRepository.resolve(Constants.HEAD + "^{commit}")
|
||||||
var removed = false
|
var removed = false
|
||||||
|
|
||||||
using(new RevWalk(git.getRepository)){ revWalk =>
|
using(new RevWalk(git.getRepository)){ revWalk =>
|
||||||
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
||||||
val index = treeWalk.addTree(revWalk.parseTree(headId))
|
val index = treeWalk.addTree(revWalk.parseTree(headId))
|
||||||
treeWalk.setRecursive(true)
|
treeWalk.setRecursive(true)
|
||||||
while(treeWalk.next){
|
while(treeWalk.next){
|
||||||
val path = treeWalk.getPathString
|
val path = treeWalk.getPathString
|
||||||
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
val tree = treeWalk.getTree(index, classOf[CanonicalTreeParser])
|
||||||
if(path != pageName + ".md"){
|
if(path != pageName + ".md"){
|
||||||
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
builder.add(JGitUtil.createDirCacheEntry(path, tree.getEntryFileMode, tree.getEntryObjectId))
|
||||||
} else {
|
} else {
|
||||||
removed = true
|
removed = true
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(removed){
|
if(removed){
|
||||||
builder.finish()
|
builder.finish()
|
||||||
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer, mailAddress, message)
|
JGitUtil.createNewCommit(git, inserter, headId, builder.getDirCache.writeTree(inserter), committer, mailAddress, message)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import org.slf4j.LoggerFactory
|
|||||||
|
|
||||||
import javax.servlet.ServletConfig
|
import javax.servlet.ServletConfig
|
||||||
import javax.servlet.ServletContext
|
import javax.servlet.ServletContext
|
||||||
import javax.servlet.http.HttpServletRequest
|
import javax.servlet.http.{HttpServletResponse, HttpServletRequest}
|
||||||
import util.{StringUtil, Keys, JGitUtil, Directory}
|
import util.{StringUtil, Keys, JGitUtil, Directory}
|
||||||
import util.ControlUtil._
|
import util.ControlUtil._
|
||||||
import util.Implicits._
|
import util.Implicits._
|
||||||
@@ -23,7 +23,7 @@ import util.JGitUtil.CommitInfo
|
|||||||
* This servlet provides only Git repository functionality.
|
* This servlet provides only Git repository functionality.
|
||||||
* Authentication is provided by [[servlet.BasicAuthenticationFilter]].
|
* Authentication is provided by [[servlet.BasicAuthenticationFilter]].
|
||||||
*/
|
*/
|
||||||
class GitRepositoryServlet extends GitServlet {
|
class GitRepositoryServlet extends GitServlet with SystemSettingsService {
|
||||||
|
|
||||||
private val logger = LoggerFactory.getLogger(classOf[GitRepositoryServlet])
|
private val logger = LoggerFactory.getLogger(classOf[GitRepositoryServlet])
|
||||||
|
|
||||||
@@ -47,7 +47,19 @@ class GitRepositoryServlet extends GitServlet {
|
|||||||
|
|
||||||
super.init(config)
|
super.init(config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override def service(req: HttpServletRequest, res: HttpServletResponse): Unit = {
|
||||||
|
val agent = req.getHeader("USER-AGENT")
|
||||||
|
if(agent == null || !agent.startsWith("git/")){
|
||||||
|
// redirect for browsers
|
||||||
|
val paths = req.getRequestURI.split("/")
|
||||||
|
val baseUrl = loadSystemSettings().baseUrl.getOrElse(req.getServletContext.getContextPath)
|
||||||
|
res.sendRedirect(baseUrl + "/" + paths.dropRight(1).last + "/" + paths.last.replaceFirst("\\.git$", ""))
|
||||||
|
} else {
|
||||||
|
// response for git client
|
||||||
|
super.service(req, res)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GitBucketReceivePackFactory extends ReceivePackFactory[HttpServletRequest] with SystemSettingsService {
|
class GitBucketReceivePackFactory extends ReceivePackFactory[HttpServletRequest] with SystemSettingsService {
|
||||||
|
|||||||
@@ -11,17 +11,20 @@ import org.eclipse.jgit.revwalk.filter._
|
|||||||
import org.eclipse.jgit.treewalk._
|
import org.eclipse.jgit.treewalk._
|
||||||
import org.eclipse.jgit.treewalk.filter._
|
import org.eclipse.jgit.treewalk.filter._
|
||||||
import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
import org.eclipse.jgit.diff.DiffEntry.ChangeType
|
||||||
import org.eclipse.jgit.errors.MissingObjectException
|
import org.eclipse.jgit.errors.{ConfigInvalidException, MissingObjectException}
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
import org.eclipse.jgit.api.errors.NoHeadException
|
import org.eclipse.jgit.api.errors.NoHeadException
|
||||||
import service.RepositoryService
|
import service.RepositoryService
|
||||||
import org.eclipse.jgit.dircache.DirCacheEntry
|
import org.eclipse.jgit.dircache.DirCacheEntry
|
||||||
|
import org.slf4j.LoggerFactory
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides complex JGit operations.
|
* Provides complex JGit operations.
|
||||||
*/
|
*/
|
||||||
object JGitUtil {
|
object JGitUtil {
|
||||||
|
|
||||||
|
private val logger = LoggerFactory.getLogger(JGitUtil.getClass)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The repository data.
|
* The repository data.
|
||||||
*
|
*
|
||||||
@@ -45,9 +48,10 @@ object JGitUtil {
|
|||||||
* @param commitId the last commit id
|
* @param commitId the last commit id
|
||||||
* @param committer the last committer name
|
* @param committer the last committer name
|
||||||
* @param mailAddress the committer's mail address
|
* @param mailAddress the committer's mail address
|
||||||
|
* @param linkUrl the url of submodule
|
||||||
*/
|
*/
|
||||||
case class FileInfo(id: ObjectId, isDirectory: Boolean, name: String, time: Date, message: String, commitId: String,
|
case class FileInfo(id: ObjectId, isDirectory: Boolean, name: String, time: Date, message: String, commitId: String,
|
||||||
committer: String, mailAddress: String)
|
committer: String, mailAddress: String, linkUrl: Option[String])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The commit data.
|
* The commit data.
|
||||||
@@ -104,6 +108,15 @@ object JGitUtil {
|
|||||||
*/
|
*/
|
||||||
case class TagInfo(name: String, time: Date, id: String)
|
case class TagInfo(name: String, time: Date, id: String)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The submodule data
|
||||||
|
*
|
||||||
|
* @param name the module name
|
||||||
|
* @param path the path in the repository
|
||||||
|
* @param url the repository url of this module
|
||||||
|
*/
|
||||||
|
case class SubmoduleInfo(name: String, path: String, url: String)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns RevCommit from the commit or tag id.
|
* Returns RevCommit from the commit or tag id.
|
||||||
*
|
*
|
||||||
@@ -162,7 +175,7 @@ object JGitUtil {
|
|||||||
* @return HTML of the file list
|
* @return HTML of the file list
|
||||||
*/
|
*/
|
||||||
def getFileList(git: Git, revision: String, path: String = "."): List[FileInfo] = {
|
def getFileList(git: Git, revision: String, path: String = "."): List[FileInfo] = {
|
||||||
val list = new scala.collection.mutable.ListBuffer[(ObjectId, FileMode, String, String)]
|
val list = new scala.collection.mutable.ListBuffer[(ObjectId, FileMode, String, String, Option[String])]
|
||||||
|
|
||||||
using(new RevWalk(git.getRepository)){ revWalk =>
|
using(new RevWalk(git.getRepository)){ revWalk =>
|
||||||
val objectId = git.getRepository.resolve(revision)
|
val objectId = git.getRepository.resolve(revision)
|
||||||
@@ -195,22 +208,28 @@ object JGitUtil {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
while (treeWalk.next()) {
|
while (treeWalk.next()) {
|
||||||
list.append((treeWalk.getObjectId(0), treeWalk.getFileMode(0), treeWalk.getPathString, treeWalk.getNameString))
|
// submodule
|
||||||
|
val linkUrl = if(treeWalk.getFileMode(0) == FileMode.GITLINK){
|
||||||
|
getSubmodules(git, revCommit.getTree).find(_.path == treeWalk.getPathString).map(_.url)
|
||||||
|
} else None
|
||||||
|
|
||||||
|
list.append((treeWalk.getObjectId(0), treeWalk.getFileMode(0), treeWalk.getPathString, treeWalk.getNameString, linkUrl))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val commits = getLatestCommitFromPaths(git, list.toList.map(_._3), revision)
|
val commits = getLatestCommitFromPaths(git, list.toList.map(_._3), revision)
|
||||||
list.map { case (objectId, fileMode, path, name) =>
|
list.map { case (objectId, fileMode, path, name, linkUrl) =>
|
||||||
FileInfo(
|
FileInfo(
|
||||||
objectId,
|
objectId,
|
||||||
fileMode == FileMode.TREE,
|
fileMode == FileMode.TREE || fileMode == FileMode.GITLINK,
|
||||||
name,
|
name,
|
||||||
commits(path).getCommitterIdent.getWhen,
|
commits(path).getCommitterIdent.getWhen,
|
||||||
commits(path).getShortMessage,
|
commits(path).getShortMessage,
|
||||||
commits(path).getName,
|
commits(path).getName,
|
||||||
commits(path).getCommitterIdent.getName,
|
commits(path).getCommitterIdent.getName,
|
||||||
commits(path).getCommitterIdent.getEmailAddress)
|
commits(path).getCommitterIdent.getEmailAddress,
|
||||||
|
linkUrl)
|
||||||
}.sortWith { (file1, file2) =>
|
}.sortWith { (file1, file2) =>
|
||||||
(file1.isDirectory, file2.isDirectory) match {
|
(file1.isDirectory, file2.isDirectory) match {
|
||||||
case (true , false) => true
|
case (true , false) => true
|
||||||
@@ -325,27 +344,6 @@ object JGitUtil {
|
|||||||
}.toMap
|
}.toMap
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get object content of the given id as String from the Git repository.
|
|
||||||
*
|
|
||||||
* @param git the Git object
|
|
||||||
* @param id the object id
|
|
||||||
* @param large if false then returns None for the large file
|
|
||||||
* @return the object or None if object does not exist
|
|
||||||
*/
|
|
||||||
def getContent(git: Git, id: ObjectId, large: Boolean): Option[Array[Byte]] = try {
|
|
||||||
val loader = git.getRepository.getObjectDatabase.open(id)
|
|
||||||
if(large == false && FileUtil.isLarge(loader.getSize)){
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
using(git.getRepository.getObjectDatabase){ db =>
|
|
||||||
Some(db.open(id).getBytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
case e: MissingObjectException => None
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the tuple of diff of the given commit and the previous commit id.
|
* Returns the tuple of diff of the given commit and the previous commit id.
|
||||||
*/
|
*/
|
||||||
@@ -377,7 +375,7 @@ object JGitUtil {
|
|||||||
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None, None)
|
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None, None)
|
||||||
} else {
|
} else {
|
||||||
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None,
|
DiffInfo(ChangeType.ADD, null, treeWalk.getPathString, None,
|
||||||
JGitUtil.getContent(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray))
|
JGitUtil.getContentFromId(git, treeWalk.getObjectId(0), false).filter(FileUtil.isText).map(convertFromByteArray))
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
(buffer.toList, None)
|
(buffer.toList, None)
|
||||||
@@ -400,8 +398,8 @@ object JGitUtil {
|
|||||||
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, None, None)
|
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath, None, None)
|
||||||
} else {
|
} else {
|
||||||
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath,
|
DiffInfo(diff.getChangeType, diff.getOldPath, diff.getNewPath,
|
||||||
JGitUtil.getContent(git, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
|
JGitUtil.getContentFromId(git, diff.getOldId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray),
|
||||||
JGitUtil.getContent(git, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray))
|
JGitUtil.getContentFromId(git, diff.getNewId.toObjectId, false).filter(FileUtil.isText).map(convertFromByteArray))
|
||||||
}
|
}
|
||||||
}.toList
|
}.toList
|
||||||
}
|
}
|
||||||
@@ -494,4 +492,73 @@ object JGitUtil {
|
|||||||
newHeadId.getName
|
newHeadId.getName
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read submodule information from .gitmodules
|
||||||
|
*/
|
||||||
|
def getSubmodules(git: Git, tree: RevTree): List[SubmoduleInfo] = {
|
||||||
|
val repository = git.getRepository
|
||||||
|
getContentFromPath(git, tree, ".gitmodules", true).map { bytes =>
|
||||||
|
(try {
|
||||||
|
val config = new BlobBasedConfig(repository.getConfig(), bytes)
|
||||||
|
config.getSubsections("submodule").asScala.map { module =>
|
||||||
|
val path = config.getString("submodule", module, "path")
|
||||||
|
val url = config.getString("submodule", module, "url")
|
||||||
|
SubmoduleInfo(module, path, url)
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
case e: ConfigInvalidException => {
|
||||||
|
logger.error("Failed to load .gitmodules file for " + repository.getDirectory(), e)
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
}).toList
|
||||||
|
} getOrElse Nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object content of the given path as byte array from the Git repository.
|
||||||
|
*
|
||||||
|
* @param git the Git object
|
||||||
|
* @param revTree the rev tree
|
||||||
|
* @param path the path
|
||||||
|
* @param fetchLargeFile if false then returns None for the large file
|
||||||
|
* @return the byte array of content or None if object does not exist
|
||||||
|
*/
|
||||||
|
def getContentFromPath(git: Git, revTree: RevTree, path: String, fetchLargeFile: Boolean): Option[Array[Byte]] = {
|
||||||
|
@scala.annotation.tailrec
|
||||||
|
def getPathObjectId(path: String, walk: TreeWalk): Option[ObjectId] = walk.next match {
|
||||||
|
case true if(walk.getPathString == path) => Some(walk.getObjectId(0))
|
||||||
|
case true => getPathObjectId(path, walk)
|
||||||
|
case false => None
|
||||||
|
}
|
||||||
|
|
||||||
|
using(new TreeWalk(git.getRepository)){ treeWalk =>
|
||||||
|
treeWalk.addTree(revTree)
|
||||||
|
treeWalk.setRecursive(true)
|
||||||
|
getPathObjectId(path, treeWalk)
|
||||||
|
} flatMap { objectId =>
|
||||||
|
getContentFromId(git, objectId, fetchLargeFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get object content of the given object id as byte array from the Git repository.
|
||||||
|
*
|
||||||
|
* @param git the Git object
|
||||||
|
* @param id the object id
|
||||||
|
* @param fetchLargeFile if false then returns None for the large file
|
||||||
|
* @return the byte array of content or None if object does not exist
|
||||||
|
*/
|
||||||
|
def getContentFromId(git: Git, id: ObjectId, fetchLargeFile: Boolean): Option[Array[Byte]] = try {
|
||||||
|
val loader = git.getRepository.getObjectDatabase.open(id)
|
||||||
|
if(fetchLargeFile == false && FileUtil.isLarge(loader.getSize)){
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
using(git.getRepository.getObjectDatabase){ db =>
|
||||||
|
Some(db.open(id).getBytes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
case e: MissingObjectException => None
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,14 +55,22 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<td width="16">
|
<td width="16">
|
||||||
@if(file.isDirectory){
|
@if(file.isDirectory){
|
||||||
<img src="@assets/common/images/folder.png"/>
|
@if(file.linkUrl.isDefined){
|
||||||
|
<img src="@assets/common/images/folder_link.png"/>
|
||||||
|
} else {
|
||||||
|
<img src="@assets/common/images/folder.png"/>
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
<img src="@assets/common/images/file.png"/>
|
<img src="@assets/common/images/file.png"/>
|
||||||
}
|
}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@if(file.isDirectory){
|
@if(file.isDirectory){
|
||||||
<a href="@url(repository)/tree@{(encodeRefName(branch) :: pathList).mkString("/", "/", "/")}@file.name">@file.name</a>
|
@if(file.linkUrl.isDefined){
|
||||||
|
<a href="@file.linkUrl">@file.name</a>
|
||||||
|
} else {
|
||||||
|
<a href="@url(repository)/tree@{(encodeRefName(branch) :: pathList).mkString("/", "/", "/")}@file.name">@file.name</a>
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
<a href="@url(repository)/blob@{(encodeRefName(branch) :: pathList).mkString("/", "/", "/")}@file.name">@file.name</a>
|
<a href="@url(repository)/blob@{(encodeRefName(branch) :: pathList).mkString("/", "/", "/")}@file.name">@file.name</a>
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
src/main/webapp/assets/common/images/folder_link.png
Normal file
BIN
src/main/webapp/assets/common/images/folder_link.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 785 B |
Reference in New Issue
Block a user