# if false, each exported repository must have a .git/git-daemon-export-ok file\r
git.exportAll = true\r
\r
-# Search repositories folder for nested repositories\r
+# Search the repositories folder subfolders for other repositories.\r
+# Repositories MAY NOT be nested (i.e. one repository within another)\r
+# but they may be grouped together in subfolders.\r
# e.g. c:/gitrepos/libraries/mylibrary.git\r
-git.nestedRepositories = true\r
+# c:/gitrepos/libraries/myotherlibrary.git\r
+git.searchRepositoriesSubfolders = true\r
\r
#\r
# Authentication Settings\r
## Git:Blit realm file format: username=password,\#permission,repository1,repository2...\r
-#Tue May 31 11:19:53 EDT 2011\r
+#Thu Jun 02 22:11:15 EDT 2011\r
admin=admin,\#admin\r
\r
public List<String> getRepositoryList() {\r
return JGitUtils.getRepositoryList(repositoriesFolder, exportAll,\r
- storedSettings.getBoolean(Keys.git.nestedRepositories, true));\r
+ storedSettings.getBoolean(Keys.git.searchRepositoriesSubfolders, true));\r
}\r
\r
public Repository getRepository(String repositoryName) {\r
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.models;\r
+\r
+import java.io.Serializable;\r
+\r
+public class GitNote implements Serializable {\r
+\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public String content;\r
+ public RefModel notesRef; \r
+\r
+ public GitNote(RefModel notesRef, String text) {\r
+ this.notesRef = notesRef;\r
+ this.content = text;\r
+ }\r
+}
\ No newline at end of file
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\r
-import com.gitblit.utils.JGitUtils.DiffOutputType;\r
-\r
public class DiffUtils {\r
\r
private static final Logger LOGGER = LoggerFactory.getLogger(DiffUtils.class);\r
\r
+ public static enum DiffOutputType {\r
+ PLAIN, GITWEB, GITBLIT;\r
+\r
+ public static DiffOutputType forName(String name) {\r
+ for (DiffOutputType type : values()) {\r
+ if (type.name().equalsIgnoreCase(name)) {\r
+ return type;\r
+ }\r
+ }\r
+ return null;\r
+ }\r
+ }\r
+\r
public static String getCommitDiff(Repository r, RevCommit commit, DiffOutputType outputType) {\r
return getDiff(r, null, commit, null, outputType);\r
}\r
import java.io.InputStream;\r
import java.io.OutputStream;\r
import java.nio.charset.Charset;\r
-import java.text.ParseException;\r
import java.util.ArrayList;\r
import java.util.Collection;\r
import java.util.Collections;\r
import java.util.Map;\r
import java.util.Map.Entry;\r
import java.util.Set;\r
-import java.util.concurrent.atomic.AtomicInteger;\r
import java.util.zip.ZipEntry;\r
import java.util.zip.ZipOutputStream;\r
\r
import org.eclipse.jgit.lib.PersonIdent;\r
import org.eclipse.jgit.lib.Ref;\r
import org.eclipse.jgit.lib.Repository;\r
+import org.eclipse.jgit.lib.RepositoryCache.FileKey;\r
import org.eclipse.jgit.lib.StoredConfig;\r
import org.eclipse.jgit.revwalk.RevBlob;\r
import org.eclipse.jgit.revwalk.RevCommit;\r
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;\r
import org.eclipse.jgit.treewalk.filter.PathSuffixFilter;\r
import org.eclipse.jgit.treewalk.filter.TreeFilter;\r
+import org.eclipse.jgit.util.FS;\r
import org.eclipse.jgit.util.io.DisabledOutputStream;\r
import org.slf4j.Logger;\r
import org.slf4j.LoggerFactory;\r
\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.TicketModel;\r
-import com.gitblit.models.TicketModel.Comment;\r
\r
public class JGitUtils {\r
\r
static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class);\r
\r
+ public static String getDisplayName(PersonIdent person) {\r
+ if (StringUtils.isEmpty(person.getEmailAddress())) {\r
+ return person.getName();\r
+ }\r
+ final StringBuilder r = new StringBuilder();\r
+ r.append(person.getName());\r
+ r.append(" <");\r
+ r.append(person.getEmailAddress());\r
+ r.append('>');\r
+ return r.toString().trim();\r
+ }\r
+\r
public static Repository createRepository(File repositoriesFolder, String name, boolean bare) {\r
Git git = Git.init().setDirectory(new File(repositoriesFolder, name)).setBare(bare).call();\r
return git.getRepository();\r
}\r
\r
public static List<String> getRepositoryList(File repositoriesFolder, boolean exportAll,\r
- boolean readNested) {\r
+ boolean searchSubfolders) {\r
List<String> list = new ArrayList<String>();\r
- list.addAll(getNestedRepositories(repositoriesFolder, repositoriesFolder, exportAll,\r
- readNested));\r
+ if (repositoriesFolder == null || !repositoriesFolder.exists()) {\r
+ return list;\r
+ }\r
+ list.addAll(getRepositoryList(repositoriesFolder.getAbsolutePath(), repositoriesFolder,\r
+ exportAll, searchSubfolders));\r
Collections.sort(list);\r
return list;\r
}\r
\r
- public static List<String> getNestedRepositories(File repositoriesFolder, File folder,\r
- boolean exportAll, boolean readNested) {\r
+ private static List<String> getRepositoryList(String basePath, File searchFolder,\r
+ boolean exportAll, boolean searchSubfolders) {\r
List<String> list = new ArrayList<String>();\r
- if (folder == null || !folder.exists()) {\r
- return list;\r
- }\r
- String basefile = repositoriesFolder.getAbsolutePath();\r
- for (File file : folder.listFiles()) {\r
- if (file.isDirectory() && !file.getName().equalsIgnoreCase(Constants.DOT_GIT)) {\r
- // if this is a git repository add it to the list\r
- //\r
- // first look for standard folder/.git structure\r
- File gitFolder = new File(file, Constants.DOT_GIT);\r
- boolean isGitRepository = gitFolder.exists() && gitFolder.isDirectory();\r
-\r
- // then look for folder.git/HEAD or folder/HEAD and\r
- // folder/config\r
- if (!isGitRepository) {\r
- if ((file.getName().endsWith(Constants.DOT_GIT_EXT) && new File(file,\r
- Constants.HEAD).exists())\r
- || (new File(file, "config").exists() && new File(file, Constants.HEAD)\r
- .exists())) {\r
- gitFolder = file;\r
- isGitRepository = true;\r
- }\r
- }\r
- boolean exportRepository = isGitRepository\r
- && (exportAll || new File(gitFolder, "git-daemon-export-ok").exists());\r
-\r
- if (exportRepository) {\r
- // determine repository name relative to repositories folder\r
- String filename = file.getAbsolutePath();\r
- String repo = filename.substring(basefile.length()).replace('\\', '/');\r
- if (repo.charAt(0) == '/') {\r
- repo = repo.substring(1);\r
+ for (File file : searchFolder.listFiles()) {\r
+ if (file.isDirectory()) {\r
+ File gitDir = FileKey.resolve(new File(searchFolder, file.getName()), FS.DETECTED);\r
+ if (gitDir != null) {\r
+ boolean exportRepository = exportAll\r
+ || new File(gitDir, "git-daemon-export-ok").exists();\r
+\r
+ if (!exportRepository) {\r
+ continue;\r
}\r
- list.add(repo);\r
- }\r
-\r
- // look for nested repositories\r
- if (readNested) {\r
- list.addAll(getNestedRepositories(repositoriesFolder, file, exportAll,\r
- readNested));\r
+ // determine repository name relative to base path\r
+ String repository = StringUtils.getRelativePath(basePath,\r
+ file.getAbsolutePath());\r
+ list.add(repository);\r
+ } else if (searchSubfolders) {\r
+ // look for repositories in subfolders\r
+ list.addAll(getRepositoryList(basePath, file, exportAll, searchSubfolders));\r
}\r
}\r
}\r
if (StringUtils.isEmpty(branch)) {\r
branch = Constants.HEAD;\r
}\r
+ RevCommit commit = null;\r
try {\r
RevWalk walk = new RevWalk(r);\r
walk.sort(RevSort.REVERSE);\r
RevCommit head = walk.parseCommit(r.resolve(branch));\r
walk.markStart(head);\r
- RevCommit commit = walk.next();\r
+ commit = walk.next();\r
walk.dispose();\r
- return commit;\r
} catch (Throwable t) {\r
LOGGER.error("Failed to determine first commit", t);\r
}\r
- return null;\r
+ return commit;\r
}\r
\r
public static Date getFirstChange(Repository r, String branch) {\r
return getCommitDate(commit);\r
}\r
\r
+ public static Date getCommitDate(RevCommit commit) {\r
+ return new Date(commit.getCommitTime() * 1000L);\r
+ }\r
+\r
public static RevCommit getCommit(Repository r, String objectId) {\r
- RevCommit commit = null;\r
if (!hasCommits(r)) {\r
return null;\r
}\r
+ RevCommit commit = null;\r
try {\r
- if (objectId == null || objectId.trim().length() == 0) {\r
+ if (StringUtils.isEmpty(objectId)) {\r
objectId = Constants.HEAD;\r
}\r
ObjectId object = r.resolve(objectId);\r
return refs;\r
}\r
\r
- public static Map<ObjectId, List<String>> getRefs(Repository r, String baseRef) {\r
- Map<ObjectId, List<String>> refs = new HashMap<ObjectId, List<String>>();\r
- Map<AnyObjectId, Set<Ref>> allRefs = r.getAllRefsByPeeledObjectId();\r
- for (Entry<AnyObjectId, Set<Ref>> setRefs : allRefs.entrySet()) {\r
- List<String> list = new ArrayList<String>();\r
- for (Ref setRef : setRefs.getValue()) {\r
- String name = setRef.getName();\r
- if (name.startsWith(baseRef)) {\r
- list.add(name);\r
- }\r
- }\r
- refs.put(setRefs.getKey().toObjectId(), list);\r
- }\r
- return refs;\r
- }\r
-\r
/**\r
* Lookup an entry stored in a tree, failing if not present.\r
* \r
* @return the parsed object entry at this path\r
* @throws Exception\r
*/\r
- public static RevObject getRevObject(Repository r, final RevTree tree, final String path) {\r
- RevObject ro = null;\r
+ public static byte[] getRawContent(Repository r, RevCommit commit, final String path) {\r
RevWalk rw = new RevWalk(r);\r
TreeWalk tw = new TreeWalk(r);\r
tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));\r
+ byte[] content = null;\r
try {\r
- tw.reset(tree);\r
+ if (commit == null) {\r
+ ObjectId object = r.resolve(Constants.HEAD);\r
+ commit = rw.parseCommit(object);\r
+ }\r
+ tw.reset(commit.getTree());\r
while (tw.next()) {\r
if (tw.isSubtree() && !path.equals(tw.getPathString())) {\r
tw.enterSubtree();\r
}\r
ObjectId entid = tw.getObjectId(0);\r
FileMode entmode = tw.getFileMode(0);\r
- ro = rw.lookupAny(entid, entmode.getObjectType());\r
+ RevObject ro = rw.lookupAny(entid, entmode.getObjectType());\r
rw.parseBody(ro);\r
+ ByteArrayOutputStream os = new ByteArrayOutputStream();\r
+ ObjectLoader ldr = r.open(ro.getId(), Constants.OBJ_BLOB);\r
+ byte[] tmp = new byte[4096];\r
+ InputStream in = ldr.openStream();\r
+ int n;\r
+ while ((n = in.read(tmp)) > 0) {\r
+ os.write(tmp, 0, n);\r
+ }\r
+ in.close();\r
+ content = os.toByteArray();\r
}\r
} catch (Throwable t) {\r
- LOGGER.error("Can't find " + path + " in tree " + tree.name(), t);\r
+ LOGGER.error("Can't find " + path + " in tree " + commit.getTree().name(), t);\r
} finally {\r
- if (rw != null) {\r
- rw.dispose();\r
- }\r
- }\r
- return ro;\r
- }\r
-\r
- public static byte[] getRawContent(Repository r, RevBlob blob) {\r
- ByteArrayOutputStream os = new ByteArrayOutputStream();\r
- try {\r
- ObjectLoader ldr = r.open(blob.getId(), Constants.OBJ_BLOB);\r
- byte[] tmp = new byte[1024];\r
- InputStream in = ldr.openStream();\r
- int n;\r
- while ((n = in.read(tmp)) > 0) {\r
- os.write(tmp, 0, n);\r
- }\r
- in.close();\r
- } catch (Throwable t) {\r
- LOGGER.error("Failed to read raw content", t);\r
+ rw.dispose();\r
+ tw.release();\r
}\r
- return os.toByteArray();\r
- }\r
-\r
- public static String getRawContentAsString(Repository r, RevBlob blob) {\r
- byte[] content = getRawContent(r, blob);\r
- return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));\r
+ return content;\r
}\r
\r
public static String getRawContentAsString(Repository r, RevCommit commit, String blobPath) {\r
- RevObject obj = getRevObject(r, commit.getTree(), blobPath);\r
- byte[] content = getRawContent(r, (RevBlob) obj);\r
+ byte[] content = getRawContent(r, commit, blobPath);\r
+ if (content == null) {\r
+ return null;\r
+ }\r
return new String(content, Charset.forName(Constants.CHARACTER_ENCODING));\r
}\r
\r
- public static List<PathModel> getFilesInPath(Repository r, String basePath, String objectId) {\r
- RevCommit commit = getCommit(r, objectId);\r
- return getFilesInPath(r, basePath, commit);\r
- }\r
-\r
public static List<PathModel> getFilesInPath(Repository r, String basePath, RevCommit commit) {\r
List<PathModel> list = new ArrayList<PathModel>();\r
- if (commit == null) {\r
+ if (!hasCommits(r)) {\r
return list;\r
}\r
- final TreeWalk walk = new TreeWalk(r);\r
+ if (commit == null) {\r
+ commit = getCommit(r, Constants.HEAD);\r
+ }\r
+ final TreeWalk tw = new TreeWalk(r);\r
try {\r
- walk.addTree(commit.getTree());\r
- if (basePath != null && basePath.length() > 0) {\r
+ tw.addTree(commit.getTree());\r
+ if (!StringUtils.isEmpty(basePath)) {\r
PathFilter f = PathFilter.create(basePath);\r
- walk.setFilter(f);\r
- walk.setRecursive(false);\r
+ tw.setFilter(f);\r
+ tw.setRecursive(false);\r
boolean foundFolder = false;\r
- while (walk.next()) {\r
- if (!foundFolder && walk.isSubtree()) {\r
- walk.enterSubtree();\r
+ while (tw.next()) {\r
+ if (!foundFolder && tw.isSubtree()) {\r
+ tw.enterSubtree();\r
}\r
- if (walk.getPathString().equals(basePath)) {\r
+ if (tw.getPathString().equals(basePath)) {\r
foundFolder = true;\r
continue;\r
}\r
if (foundFolder) {\r
- list.add(getPathModel(walk, basePath, commit));\r
+ list.add(getPathModel(tw, basePath, commit));\r
}\r
}\r
} else {\r
- walk.setRecursive(false);\r
- while (walk.next()) {\r
- list.add(getPathModel(walk, null, commit));\r
+ tw.setRecursive(false);\r
+ while (tw.next()) {\r
+ list.add(getPathModel(tw, null, commit));\r
}\r
}\r
} catch (IOException e) {\r
LOGGER.error("Failed to get files for commit " + commit.getName(), e);\r
} finally {\r
- walk.release();\r
+ tw.release();\r
}\r
Collections.sort(list);\r
return list;\r
}\r
\r
- public static List<PathChangeModel> getFilesInCommit(Repository r, String commitId) {\r
- RevCommit commit = getCommit(r, commitId);\r
- return getFilesInCommit(r, commit);\r
- }\r
-\r
public static List<PathChangeModel> getFilesInCommit(Repository r, RevCommit commit) {\r
List<PathChangeModel> list = new ArrayList<PathChangeModel>();\r
- if (commit == null) {\r
- LOGGER.warn("getFilesInCommit for NULL commit");\r
- return list;\r
- }\r
+ RevWalk rw = new RevWalk(r);\r
+ TreeWalk tw = new TreeWalk(r);\r
try {\r
- final RevWalk rw = new RevWalk(r);\r
-\r
+ if (commit == null) {\r
+ ObjectId object = r.resolve(Constants.HEAD);\r
+ commit = rw.parseCommit(object);\r
+ }\r
RevTree commitTree = commit.getTree();\r
\r
- final TreeWalk walk = new TreeWalk(r);\r
- walk.reset();\r
- walk.setRecursive(true);\r
+ tw.reset();\r
+ tw.setRecursive(true);\r
if (commit.getParentCount() == 0) {\r
- walk.addTree(commitTree);\r
- while (walk.next()) {\r
- list.add(new PathChangeModel(walk.getPathString(), walk.getPathString(), 0,\r
- walk.getRawMode(0), commit.getId().getName(), ChangeType.ADD));\r
+ tw.addTree(commitTree);\r
+ while (tw.next()) {\r
+ list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw\r
+ .getRawMode(0), commit.getId().getName(), ChangeType.ADD));\r
}\r
} else {\r
RevCommit parent = rw.parseCommit(commit.getParent(0).getId());\r
RevTree parentTree = parent.getTree();\r
- walk.addTree(parentTree);\r
- walk.addTree(commitTree);\r
- walk.setFilter(TreeFilter.ANY_DIFF);\r
+ tw.addTree(parentTree);\r
+ tw.addTree(commitTree);\r
+ tw.setFilter(TreeFilter.ANY_DIFF);\r
\r
RawTextComparator cmp = RawTextComparator.DEFAULT;\r
DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE);\r
}\r
} catch (Throwable t) {\r
LOGGER.error("failed to determine files in commit!", t);\r
+ } finally {\r
+ rw.dispose();\r
+ tw.release();\r
}\r
return list;\r
}\r
public static List<PathModel> getDocuments(Repository r, List<String> extensions) {\r
List<PathModel> list = new ArrayList<PathModel>();\r
RevCommit commit = getCommit(r, Constants.HEAD);\r
- final TreeWalk walk = new TreeWalk(r);\r
+ final TreeWalk tw = new TreeWalk(r);\r
try {\r
- walk.addTree(commit.getTree());\r
+ tw.addTree(commit.getTree());\r
if (extensions != null && extensions.size() > 0) {\r
Collection<TreeFilter> suffixFilters = new ArrayList<TreeFilter>();\r
for (String extension : extensions) {\r
if (extension.charAt(0) == '.') {\r
- suffixFilters.add(PathSuffixFilter.create(extension));\r
+ suffixFilters.add(PathSuffixFilter.create("\\" + extension));\r
} else {\r
// escape the . since this is a regexp filter\r
suffixFilters.add(PathSuffixFilter.create("\\." + extension));\r
}\r
}\r
TreeFilter filter = OrTreeFilter.create(suffixFilters);\r
- walk.setFilter(filter);\r
- walk.setRecursive(true);\r
- while (walk.next()) {\r
- list.add(getPathModel(walk, null, commit));\r
- }\r
- } else {\r
- while (walk.next()) {\r
- list.add(getPathModel(walk, null, commit));\r
- }\r
+ tw.setFilter(filter);\r
+ tw.setRecursive(true);\r
+ }\r
+ while (tw.next()) {\r
+ list.add(getPathModel(tw, null, commit));\r
}\r
} catch (IOException e) {\r
- LOGGER.error("Failed to get files for commit " + commit.getName(), e);\r
+ LOGGER.error("Failed to get documents for commit " + commit.getName(), e);\r
} finally {\r
- walk.release();\r
+ tw.release();\r
}\r
Collections.sort(list);\r
return list;\r
}\r
\r
- public static Map<ChangeType, AtomicInteger> getChangedPathsStats(List<PathChangeModel> paths) {\r
- Map<ChangeType, AtomicInteger> stats = new HashMap<ChangeType, AtomicInteger>();\r
- for (PathChangeModel path : paths) {\r
- if (!stats.containsKey(path.changeType)) {\r
- stats.put(path.changeType, new AtomicInteger(0));\r
- }\r
- stats.get(path.changeType).incrementAndGet();\r
- }\r
- return stats;\r
- }\r
-\r
- public static enum DiffOutputType {\r
- PLAIN, GITWEB, GITBLIT;\r
-\r
- public static DiffOutputType forName(String name) {\r
- for (DiffOutputType type : values()) {\r
- if (type.name().equalsIgnoreCase(name)) {\r
- return type;\r
- }\r
- }\r
- return null;\r
- }\r
- }\r
-\r
- private static PathModel getPathModel(TreeWalk walk, String basePath, RevCommit commit) {\r
+ private static PathModel getPathModel(TreeWalk tw, String basePath, RevCommit commit) {\r
String name;\r
long size = 0;\r
- if (basePath == null) {\r
- name = walk.getPathString();\r
+ if (StringUtils.isEmpty(basePath)) {\r
+ name = tw.getPathString();\r
} else {\r
- try {\r
- name = walk.getPathString().substring(basePath.length() + 1);\r
- } catch (Throwable t) {\r
- name = walk.getPathString();\r
- }\r
+ name = tw.getPathString().substring(basePath.length() + 1);\r
}\r
try {\r
- if (!walk.isSubtree()) {\r
- size = walk.getObjectReader()\r
- .getObjectSize(walk.getObjectId(0), Constants.OBJ_BLOB);\r
+ if (!tw.isSubtree()) {\r
+ size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB);\r
}\r
} catch (Throwable t) {\r
LOGGER.error("Failed to retrieve blob size", t);\r
}\r
- return new PathModel(name, walk.getPathString(), size, walk.getFileMode(0).getBits(),\r
+ return new PathModel(name, tw.getPathString(), size, tw.getFileMode(0).getBits(),\r
commit.getName());\r
}\r
\r
} else if (FileMode.GITLINK.equals(mode)) {\r
// FIXME gitlink permissions\r
return "gitlink";\r
- } else if (FileMode.MISSING.equals(mode)) {\r
- // FIXME missing permissions\r
- return "missing";\r
}\r
- return "" + mode;\r
+ // FIXME missing permissions\r
+ return "missing";\r
}\r
\r
public static List<RevCommit> getRevLog(Repository r, int maxCount) {\r
return list;\r
}\r
try {\r
- if (objectId == null || objectId.trim().length() == 0) {\r
+ if (StringUtils.isEmpty(objectId)) {\r
objectId = Constants.HEAD;\r
}\r
- RevWalk walk = new RevWalk(r);\r
+ RevWalk rw = new RevWalk(r);\r
ObjectId object = r.resolve(objectId);\r
- walk.markStart(walk.parseCommit(object));\r
+ rw.markStart(rw.parseCommit(object));\r
if (!StringUtils.isEmpty(path)) {\r
TreeFilter filter = AndTreeFilter.create(\r
PathFilterGroup.createFromStrings(Collections.singleton(path)),\r
TreeFilter.ANY_DIFF);\r
- walk.setTreeFilter(filter);\r
+ rw.setTreeFilter(filter);\r
}\r
- Iterable<RevCommit> revlog = walk;\r
+ Iterable<RevCommit> revlog = rw;\r
if (offset > 0) {\r
int count = 0;\r
for (RevCommit rev : revlog) {\r
}\r
}\r
}\r
- walk.dispose();\r
+ rw.dispose();\r
} catch (Throwable t) {\r
- LOGGER.error("Failed to determine last change", t);\r
+ LOGGER.error("Failed to get revlog", t);\r
}\r
return list;\r
}\r
return type;\r
}\r
}\r
- return null;\r
+ return COMMIT;\r
}\r
\r
+ @Override\r
public String toString() {\r
return name().toLowerCase();\r
}\r
return list;\r
}\r
try {\r
- if (objectId == null || objectId.trim().length() == 0) {\r
+ if (StringUtils.isEmpty(objectId)) {\r
objectId = Constants.HEAD;\r
}\r
- RevWalk walk = new RevWalk(r);\r
- walk.setRevFilter(new RevFilter() {\r
+ RevWalk rw = new RevWalk(r);\r
+ rw.setRevFilter(new RevFilter() {\r
\r
@Override\r
public RevFilter clone() {\r
@Override\r
public boolean include(RevWalk walker, RevCommit commit) throws StopWalkException,\r
MissingObjectException, IncorrectObjectTypeException, IOException {\r
+ boolean include = false;\r
switch (type) {\r
case AUTHOR:\r
- return (commit.getAuthorIdent().getName().toLowerCase().indexOf(lcValue) > -1)\r
+ include = (commit.getAuthorIdent().getName().toLowerCase().indexOf(lcValue) > -1)\r
|| (commit.getAuthorIdent().getEmailAddress().toLowerCase()\r
.indexOf(lcValue) > -1);\r
+ break;\r
case COMMITTER:\r
- return (commit.getCommitterIdent().getName().toLowerCase().indexOf(lcValue) > -1)\r
+ include = (commit.getCommitterIdent().getName().toLowerCase()\r
+ .indexOf(lcValue) > -1)\r
|| (commit.getCommitterIdent().getEmailAddress().toLowerCase()\r
.indexOf(lcValue) > -1);\r
+ break;\r
case COMMIT:\r
- return commit.getFullMessage().toLowerCase().indexOf(lcValue) > -1;\r
+ include = commit.getFullMessage().toLowerCase().indexOf(lcValue) > -1;\r
+ break;\r
}\r
- return false;\r
+ return include;\r
}\r
\r
});\r
ObjectId object = r.resolve(objectId);\r
- walk.markStart(walk.parseCommit(object));\r
- Iterable<RevCommit> revlog = walk;\r
+ rw.markStart(rw.parseCommit(object));\r
+ Iterable<RevCommit> revlog = rw;\r
if (offset > 0) {\r
int count = 0;\r
for (RevCommit rev : revlog) {\r
}\r
}\r
}\r
- walk.dispose();\r
+ rw.dispose();\r
} catch (Throwable t) {\r
- LOGGER.error("Failed to determine last change", t);\r
+ LOGGER.error("Failed to search revlogs", t);\r
}\r
return list;\r
}\r
return getRefs(r, Constants.R_REMOTES, maxCount);\r
}\r
\r
- public static List<RefModel> getRefs(Repository r, String refs, int maxCount) {\r
+ public static List<RefModel> getNotes(Repository r, int maxCount) {\r
+ return getRefs(r, Constants.R_NOTES, maxCount);\r
+ }\r
+\r
+ private static List<RefModel> getRefs(Repository r, String refs, int maxCount) {\r
List<RefModel> list = new ArrayList<RefModel>();\r
try {\r
Map<String, Ref> map = r.getRefDatabase().getRefs(refs);\r
return list;\r
}\r
\r
- public static Ref getRef(Repository r, String id) {\r
- // FIXME\r
- try {\r
- Map<String, Ref> map = r.getRefDatabase().getRefs(id);\r
- for (Entry<String, Ref> entry : map.entrySet()) {\r
- return entry.getValue();\r
+ public static List<GitNote> getNotesOnCommit(Repository repository, RevCommit commit) {\r
+ List<GitNote> list = new ArrayList<GitNote>();\r
+ List<RefModel> notesRefs = getNotes(repository, -1);\r
+ for (RefModel notesRef : notesRefs) {\r
+ RevCommit notes = JGitUtils.getCommit(repository, notesRef.getName());\r
+ StringBuilder sb = new StringBuilder(commit.getName());\r
+ sb.insert(2, '/');\r
+ String text = getRawContentAsString(repository, notes, sb.toString());\r
+ if (!StringUtils.isEmpty(text)) {\r
+ GitNote gitNote = new GitNote(notesRef, text);\r
+ list.add(gitNote);\r
}\r
- } catch (IOException e) {\r
- LOGGER.error("Failed to retrieve ref " + id, e);\r
}\r
- return null;\r
- }\r
-\r
- public static Date getCommitDate(RevCommit commit) {\r
- return new Date(commit.getCommitTime() * 1000L);\r
- }\r
-\r
- public static String getDisplayName(PersonIdent person) {\r
- final StringBuilder r = new StringBuilder();\r
- r.append(person.getName());\r
- r.append(" <");\r
- r.append(person.getEmailAddress());\r
- r.append('>');\r
- return r.toString();\r
+ return list;\r
}\r
\r
public static StoredConfig readConfig(Repository r) {\r
StoredConfig c = r.getConfig();\r
- if (c != null) {\r
- try {\r
- c.load();\r
- } catch (ConfigInvalidException cex) {\r
- LOGGER.error("Repository configuration is invalid!", cex);\r
- } catch (IOException cex) {\r
- LOGGER.error("Could not open repository configuration!", cex);\r
- }\r
- return c;\r
+ try {\r
+ c.load();\r
+ } catch (ConfigInvalidException cex) {\r
+ LOGGER.error("Repository configuration is invalid!", cex);\r
+ } catch (IOException cex) {\r
+ LOGGER.error("Could not open repository configuration!", cex);\r
}\r
- return null;\r
+ return c;\r
}\r
\r
public static boolean zip(Repository r, String basePath, String objectId, OutputStream os)\r
if (commit == null) {\r
return false;\r
}\r
- final RevWalk rw = new RevWalk(r);\r
- final TreeWalk walk = new TreeWalk(r);\r
+ boolean success = false;\r
+ RevWalk rw = new RevWalk(r);\r
+ TreeWalk tw = new TreeWalk(r);\r
try {\r
- walk.addTree(commit.getTree());\r
+ tw.addTree(commit.getTree());\r
ZipOutputStream zos = new ZipOutputStream(os);\r
zos.setComment("Generated by Git:Blit");\r
- if (basePath != null && basePath.length() > 0) {\r
+ if (!StringUtils.isEmpty(basePath)) {\r
PathFilter f = PathFilter.create(basePath);\r
- walk.setFilter(f);\r
+ tw.setFilter(f);\r
}\r
- walk.setRecursive(true);\r
- while (walk.next()) {\r
- ZipEntry entry = new ZipEntry(walk.getPathString());\r
- entry.setSize(walk.getObjectReader().getObjectSize(walk.getObjectId(0),\r
+ tw.setRecursive(true);\r
+ while (tw.next()) {\r
+ ZipEntry entry = new ZipEntry(tw.getPathString());\r
+ entry.setSize(tw.getObjectReader().getObjectSize(tw.getObjectId(0),\r
Constants.OBJ_BLOB));\r
entry.setComment(commit.getName());\r
zos.putNextEntry(entry);\r
\r
- ObjectId entid = walk.getObjectId(0);\r
- FileMode entmode = walk.getFileMode(0);\r
+ ObjectId entid = tw.getObjectId(0);\r
+ FileMode entmode = tw.getFileMode(0);\r
RevBlob blob = (RevBlob) rw.lookupAny(entid, entmode.getObjectType());\r
rw.parseBody(blob);\r
\r
in.close();\r
}\r
zos.finish();\r
- return true;\r
+ success = true;\r
} catch (IOException e) {\r
LOGGER.error("Failed to zip files from commit " + commit.getName(), e);\r
} finally {\r
- walk.release();\r
+ tw.release();\r
rw.dispose();\r
}\r
- return false;\r
+ return success;\r
}\r
}\r
public class MarkdownUtils {\r
\r
public static String transformMarkdown(String markdown) throws java.text.ParseException {\r
- // Read raw markdown content and transform it to html\r
- StringReader reader = new StringReader(markdown);\r
- StringWriter writer = new StringWriter();\r
try {\r
- Markdown md = new Markdown();\r
- md.transform(reader, writer);\r
- return writer.toString();\r
- } catch (ParseException p) {\r
- throw new java.text.ParseException(p.getMessage(), 0);\r
- } finally {\r
- reader.close();\r
- try {\r
- writer.close();\r
- } catch (IOException e) {\r
- // IGNORE\r
- }\r
+ return transformMarkdown(new StringReader(markdown));\r
+ } catch (NullPointerException p) {\r
+ throw new java.text.ParseException("Markdown string is null!", 0);\r
}\r
}\r
\r
try {\r
Markdown md = new Markdown();\r
md.transform(markdownReader, writer);\r
- return writer.toString();\r
+ return writer.toString().trim();\r
} catch (ParseException p) {\r
throw new java.text.ParseException(p.getMessage(), 0);\r
} finally {\r
}\r
}\r
}\r
-\r
}\r
public static List<Metric> getDateMetrics(Repository r, boolean includeTotal, String format) {\r
Metric total = new Metric("TOTAL");\r
final Map<String, Metric> metricMap = new HashMap<String, Metric>();\r
- \r
- if (JGitUtils.hasCommits(r)) { \r
- try {\r
- RevWalk walk = new RevWalk(r);\r
- ObjectId object = r.resolve(Constants.HEAD);\r
- RevCommit lastCommit = walk.parseCommit(object);\r
- walk.markStart(lastCommit);\r
- SimpleDateFormat df = new SimpleDateFormat(format);\r
- Iterable<RevCommit> revlog = walk;\r
- for (RevCommit rev : revlog) {\r
- Date d = JGitUtils.getCommitDate(rev);\r
- String p = df.format(d);\r
- if (!metricMap.containsKey(p)) {\r
- metricMap.put(p, new Metric(p));\r
- }\r
- Metric m = metricMap.get(p);\r
- m.count++;\r
- total.count++; \r
- }\r
- } catch (Throwable t) {\r
- JGitUtils.LOGGER.error("Failed to mine log history for metrics", t);\r
- }\r
- }\r
- List<String> keys = new ArrayList<String>(metricMap.keySet());\r
- Collections.sort(keys);\r
- List<Metric> metrics = new ArrayList<Metric>();\r
- for (String key : keys) {\r
- metrics.add(metricMap.get(key));\r
- }\r
- if (includeTotal) {\r
- metrics.add(0, total);\r
- }\r
- return metrics;\r
- }\r
\r
- public static List<Metric> getDateMetrics(Repository r, boolean includeTotal) {\r
- Metric total = new Metric("TOTAL");\r
- final Map<String, Metric> metricMap = new HashMap<String, Metric>();\r
- \r
if (JGitUtils.hasCommits(r)) {\r
final List<RefModel> tags = JGitUtils.getTags(r, -1);\r
final Map<ObjectId, RefModel> tagMap = new HashMap<ObjectId, RefModel>();\r
try {\r
RevWalk walk = new RevWalk(r);\r
ObjectId object = r.resolve(Constants.HEAD);\r
- \r
- RevCommit firstCommit = JGitUtils.getFirstCommit(r, Constants.HEAD);\r
RevCommit lastCommit = walk.parseCommit(object);\r
- int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime())\r
- / (60 * 60 * 24);\r
- total.duration = diffDays;\r
+ walk.markStart(lastCommit);\r
+\r
DateFormat df;\r
- if (diffDays <= 90) {\r
- // Days\r
- df = new SimpleDateFormat("yyyy-MM-dd");\r
- } else if (diffDays > 90 && diffDays < 365) {\r
- // Weeks\r
- df = new SimpleDateFormat("yyyy-MM (w)");\r
+ if (StringUtils.isEmpty(format)) {\r
+ // dynamically determine date format\r
+ RevCommit firstCommit = JGitUtils.getFirstCommit(r, Constants.HEAD);\r
+ int diffDays = (lastCommit.getCommitTime() - firstCommit.getCommitTime())\r
+ / (60 * 60 * 24);\r
+ total.duration = diffDays;\r
+ if (diffDays <= 90) {\r
+ // Days\r
+ df = new SimpleDateFormat("yyyy-MM-dd");\r
+ } else if (diffDays > 90 && diffDays < 365) {\r
+ // Weeks\r
+ df = new SimpleDateFormat("yyyy-MM (w)");\r
+ } else {\r
+ // Months\r
+ df = new SimpleDateFormat("yyyy-MM");\r
+ }\r
} else {\r
- // Months\r
- df = new SimpleDateFormat("yyyy-MM");\r
+ // use specified date format\r
+ df = new SimpleDateFormat(format);\r
}\r
- walk.markStart(lastCommit);\r
- \r
+\r
Iterable<RevCommit> revlog = walk;\r
for (RevCommit rev : revlog) {\r
Date d = JGitUtils.getCommitDate(rev);\r
}\r
}\r
} catch (Throwable t) {\r
- JGitUtils.LOGGER.error("Failed to mine log history for metrics", t);\r
+ LOGGER.error("Failed to mine log history for date metrics", t);\r
}\r
}\r
List<String> keys = new ArrayList<String>(metricMap.keySet());\r
return metrics;\r
}\r
\r
- public static List<Metric> getAuthorMetrics(Repository r) {\r
- Metric total = new Metric("TOTAL");\r
+ public static List<Metric> getAuthorMetrics(Repository r, boolean byEmail) {\r
final Map<String, Metric> metricMap = new HashMap<String, Metric>();\r
- \r
+\r
if (JGitUtils.hasCommits(r)) {\r
try {\r
RevWalk walk = new RevWalk(r);\r
ObjectId object = r.resolve(Constants.HEAD);\r
RevCommit lastCommit = walk.parseCommit(object);\r
walk.markStart(lastCommit);\r
- \r
+\r
Iterable<RevCommit> revlog = walk;\r
for (RevCommit rev : revlog) {\r
- String p = rev.getAuthorIdent().getName();\r
- if (StringUtils.isEmpty(p)) {\r
+ String p;\r
+ if (byEmail) {\r
p = rev.getAuthorIdent().getEmailAddress();\r
+ if (StringUtils.isEmpty(p)) {\r
+ p = rev.getAuthorIdent().getName();\r
+ }\r
+ } else {\r
+ p = rev.getAuthorIdent().getName();\r
+ if (StringUtils.isEmpty(p)) {\r
+ p = rev.getAuthorIdent().getEmailAddress();\r
+ }\r
}\r
if (!metricMap.containsKey(p)) {\r
metricMap.put(p, new Metric(p));\r
}\r
Metric m = metricMap.get(p);\r
m.count++;\r
- total.count++;\r
}\r
} catch (Throwable t) {\r
- JGitUtils.LOGGER.error("Failed to mine log history for metrics", t);\r
+ LOGGER.error("Failed to mine log history for author metrics", t);\r
}\r
}\r
List<String> keys = new ArrayList<String>(metricMap.keySet());\r
}\r
return "";\r
}\r
+ \r
+ public static String getRelativePath(String basePath, String fullPath) { \r
+ String relativePath = fullPath.substring(basePath.length()).replace('\\', '/');\r
+ if (relativePath.charAt(0) == '/') {\r
+ relativePath = relativePath.substring(1);\r
+ }\r
+ return relativePath;\r
+ }\r
}\r
\r
public static List<TicketModel> getTickets(Repository r) {\r
RefModel ticgitBranch = getTicketsBranch(r);\r
+ if (ticgitBranch == null) {\r
+ return null;\r
+ }\r
List<PathModel> paths = JGitUtils.getFilesInPath(r, null, ticgitBranch.commit);\r
List<TicketModel> tickets = new ArrayList<TicketModel>();\r
for (PathModel ticketFolder : paths) {\r
Comment c = new Comment(file.name, content);\r
ticket.comments.add(c);\r
} catch (ParseException e) {\r
- e.printStackTrace();\r
+ LOGGER.error("Failed to parse ticket comment", e);\r
}\r
} else if (chunks[0].equals("TAG")) {\r
if (content.startsWith("TAG_")) {\r
}\r
Collections.sort(ticket.comments);\r
}\r
-\r
- public static String getTicketContent(Repository r, String filePath) {\r
- RefModel ticketsBranch = getTicketsBranch(r);\r
- if (ticketsBranch != null) {\r
- return JGitUtils.getRawContentAsString(r, ticketsBranch.commit, filePath);\r
- }\r
- return "";\r
- }\r
}\r
import com.gitblit.GitBlit;\r
import com.gitblit.Keys;\r
import com.gitblit.utils.DiffUtils;\r
+import com.gitblit.utils.DiffUtils.DiffOutputType;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.JGitUtils.DiffOutputType;\r
import com.gitblit.utils.StringUtils;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.CommitHeaderPanel;\r
import com.gitblit.Keys;\r
import com.gitblit.models.PathModel.PathChangeModel;\r
import com.gitblit.utils.DiffUtils;\r
+import com.gitblit.utils.DiffUtils.DiffOutputType;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.JGitUtils.DiffOutputType;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.CommitHeaderPanel;\r
import com.gitblit.wicket.panels.CommitLegendPanel;\r
<!-- full message -->\r
<div class="commit_message" wicket:id="fullMessage">[commit message]</div>\r
\r
+ <!-- git notes -->\r
+ <table style="padding-bottom:5px;">\r
+ <tr wicket:id="notes">\r
+ <td style="vertical-align:top;"><span class="headRef" wicket:id="refName"></span><br/><span wicket:id="authorName"></span><br/><span wicket:id="authorDate"></span></td>\r
+ <td><span wicket:id="noteContent"></span></td>\r
+ </tr>\r
+ </table>\r
+ \r
<!-- commit legend -->\r
<div style="text-align:right;" wicket:id="commitLegend"></div>\r
\r
import java.util.ArrayList;\r
import java.util.List;\r
\r
+import org.apache.wicket.Component;\r
import org.apache.wicket.PageParameters;\r
import org.apache.wicket.markup.html.basic.Label;\r
import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
import com.gitblit.DownloadZipServlet;\r
import com.gitblit.GitBlit;\r
import com.gitblit.Keys;\r
+import com.gitblit.models.GitNote;\r
import com.gitblit.models.PathModel.PathChangeModel;\r
import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.StringUtils;\r
import com.gitblit.utils.JGitUtils.SearchType;\r
import com.gitblit.wicket.WicketUtils;\r
import com.gitblit.wicket.panels.CommitHeaderPanel;\r
\r
addFullText("fullMessage", c.getFullMessage(), true);\r
\r
+ // git notes\r
+ List<GitNote> notes = JGitUtils.getNotesOnCommit(r, c);\r
+ ListDataProvider<GitNote> notesDp = new ListDataProvider<GitNote>(notes);\r
+ DataView<GitNote> notesView = new DataView<GitNote>("notes", notesDp) {\r
+ private static final long serialVersionUID = 1L;\r
+\r
+ public void populateItem(final Item<GitNote> item) {\r
+ GitNote entry = item.getModelObject();\r
+ Component c = new LinkPanel("refName", null, entry.notesRef.displayName,\r
+ CommitPage.class, newCommitParameter(entry.notesRef.commit.getName()));\r
+ WicketUtils.setCssClass(c, "headRef");\r
+ item.add(c);\r
+ item.add(createPersonPanel("authorName", entry.notesRef.commit.getAuthorIdent(), SearchType.AUTHOR));\r
+ item.add(WicketUtils.createTimestampLabel("authorDate",\r
+ entry.notesRef.commit.getAuthorIdent().getWhen(), getTimeZone()));\r
+ item.add(new Label("noteContent", StringUtils.breakLinesForHtml(entry.content)).setEscapeModelStrings(false));\r
+ }\r
+ };\r
+ add(notesView.setVisible(notes.size() > 0));\r
+ \r
+ \r
// changed paths list\r
List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, c);\r
add(new CommitLegendPanel("commitLegend", paths));\r
import java.util.ArrayList;\r
import java.util.Arrays;\r
import java.util.Collections;\r
-import java.util.Date;\r
import java.util.Iterator;\r
import java.util.List;\r
import java.util.Map;\r
\r
// automatically convert backslashes to forward slashes\r
repositoryModel.name = repositoryModel.name.replace('\\', '/');\r
+ // Automatically replace // with /\r
+ repositoryModel.name = repositoryModel.name.replace("//", "/");\r
+\r
+ // prohibit folder paths\r
+ if (repositoryModel.name.startsWith("/")) { \r
+ error("Leading root folder references (/) are prohibited.");\r
+ return;\r
+ }\r
+ if (repositoryModel.name.startsWith("../")) { \r
+ error("Relative folder references (../) are prohibited.");\r
+ return;\r
+ }\r
+ if (repositoryModel.name.contains("/../")) {\r
+ error("Relative folder references (../) are prohibited.");\r
+ return;\r
+ }\r
\r
// confirm valid characters in repository name\r
char[] validChars = { '/', '.', '_', '-' };\r
}\r
}\r
}\r
-\r
+ \r
// confirm access restriction selection\r
if (repositoryModel.accessRestriction == null) {\r
error("Please select access restriction!");\r
public MetricsPage(PageParameters params) {\r
super(params);\r
Repository r = getRepository();\r
- insertLinePlot("commitsChart", MetricUtils.getDateMetrics(r, false));\r
+ insertLinePlot("commitsChart", MetricUtils.getDateMetrics(r, false, null));\r
insertBarPlot("dayOfWeekChart", getDayOfWeekMetrics(r));\r
insertLinePlot("timeOfDayChart", getTimeOfDayMetrics(r));\r
insertPieChart("authorsChart", getAuthorMetrics(r));\r
if ((metrics != null) && (metrics.size() > 0)) {\r
IChartData data = WicketUtils.getChartData(metrics);\r
\r
- ChartProvider provider = new ChartProvider(new Dimension(400, 100), ChartType.LINE,\r
+ ChartProvider provider = new ChartProvider(new Dimension(500, 100), ChartType.LINE,\r
data);\r
ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM);\r
dateAxis.setLabels(new String[] { metrics.get(0).name,\r
if ((metrics != null) && (metrics.size() > 0)) {\r
IChartData data = WicketUtils.getChartData(metrics);\r
\r
- ChartProvider provider = new ChartProvider(new Dimension(400, 100),\r
+ ChartProvider provider = new ChartProvider(new Dimension(500, 100),\r
ChartType.BAR_VERTICAL_SET, data);\r
ChartAxis dateAxis = new ChartAxis(ChartAxisType.BOTTOM);\r
List<String> labels = new ArrayList<String>();\r
for (Metric metric : metrics) {\r
labels.add(metric.name);\r
}\r
- ChartProvider provider = new ChartProvider(new Dimension(400, 200), ChartType.PIE, data);\r
+ ChartProvider provider = new ChartProvider(new Dimension(500, 200), ChartType.PIE, data);\r
provider.setPieLabels(labels.toArray(new String[labels.size()]));\r
add(new Chart(wicketId, provider));\r
} else {\r
}\r
\r
private List<Metric> getAuthorMetrics(Repository repository) {\r
- List<Metric> authors = MetricUtils.getAuthorMetrics(repository);\r
+ List<Metric> authors = MetricUtils.getAuthorMetrics(repository, true);\r
Collections.sort(authors, new Comparator<Metric>() {\r
@Override\r
public int compare(Metric o1, Metric o2) {\r
List<Metric> metrics = null;\r
Metric metricsTotal = null;\r
if (GitBlit.getBoolean(Keys.web.generateActivityGraph, true)) {\r
- metrics = MetricUtils.getDateMetrics(r, true);\r
+ metrics = MetricUtils.getDateMetrics(r, true, null);\r
metricsTotal = metrics.remove(0);\r
}\r
\r
\r
import java.text.MessageFormat;\r
import java.util.ArrayList;\r
+import java.util.HashMap;\r
import java.util.List;\r
import java.util.Map;\r
import java.util.concurrent.atomic.AtomicInteger;\r
import org.eclipse.jgit.diff.DiffEntry.ChangeType;\r
\r
import com.gitblit.models.PathModel.PathChangeModel;\r
-import com.gitblit.utils.JGitUtils;\r
import com.gitblit.wicket.WicketUtils;\r
\r
public class CommitLegendPanel extends Panel {\r
\r
public CommitLegendPanel(String id, List<PathChangeModel> paths) {\r
super(id);\r
- final Map<ChangeType, AtomicInteger> stats = JGitUtils.getChangedPathsStats(paths);\r
+ final Map<ChangeType, AtomicInteger> stats = getChangedPathsStats(paths);\r
ListDataProvider<ChangeType> legendDp = new ListDataProvider<ChangeType>(\r
new ArrayList<ChangeType>(stats.keySet()));\r
DataView<ChangeType> legendsView = new DataView<ChangeType>("legend", legendDp) {\r
};\r
add(legendsView);\r
}\r
+ \r
+ protected Map<ChangeType, AtomicInteger> getChangedPathsStats(List<PathChangeModel> paths) {\r
+ Map<ChangeType, AtomicInteger> stats = new HashMap<ChangeType, AtomicInteger>();\r
+ for (PathChangeModel path : paths) {\r
+ if (!stats.containsKey(path.changeType)) {\r
+ stats.put(path.changeType, new AtomicInteger(0));\r
+ }\r
+ stats.get(path.changeType).incrementAndGet();\r
+ }\r
+ return stats;\r
+ }\r
}
\ No newline at end of file
import org.eclipse.jgit.revwalk.RevCommit;\r
\r
import com.gitblit.utils.DiffUtils;\r
+import com.gitblit.utils.DiffUtils.DiffOutputType;\r
import com.gitblit.utils.JGitUtils;\r
-import com.gitblit.utils.JGitUtils.DiffOutputType;\r
\r
public class DiffUtilsTest extends TestCase {\r
\r
\r
import com.gitblit.FileSettings;\r
import com.gitblit.GitBlit;\r
+import com.gitblit.GitBlitException;\r
import com.gitblit.JettyLoginService;\r
+import com.gitblit.models.RepositoryModel;\r
\r
public class GitBlitSuite extends TestSetup {\r
public static final File REPOSITORIES = new File("git");\r
suite.addTestSuite(TimeUtilsTest.class);\r
suite.addTestSuite(StringUtilsTest.class);\r
suite.addTestSuite(ByteFormatTest.class);\r
+ suite.addTestSuite(MarkdownUtilsTest.class);\r
suite.addTestSuite(JGitUtilsTest.class);\r
suite.addTestSuite(DiffUtilsTest.class);\r
suite.addTestSuite(MetricUtilsTest.class);\r
\r
@Override\r
protected void setUp() throws Exception {\r
- if (REPOSITORIES.exists() || REPOSITORIES.mkdirs()) {\r
- cloneOrFetch("helloworld.git", "https://github.com/git/hello-world.git", true);\r
- cloneOrFetch("nested/helloworld.git", "https://github.com/git/hello-world.git", true);\r
- cloneOrFetch("ticgit.git", "https://github.com/jeffWelling/ticgit.git", true);\r
- }\r
FileSettings settings = new FileSettings("distrib/gitblit.properties");\r
GitBlit.self().configureContext(settings);\r
JettyLoginService loginService = new JettyLoginService(new File("distrib/users.properties"));\r
loginService.loadUsers();\r
GitBlit.self().setLoginService(loginService);\r
+\r
+ if (REPOSITORIES.exists() || REPOSITORIES.mkdirs()) {\r
+ cloneOrFetch("helloworld.git", "https://github.com/git/hello-world.git", true);\r
+ cloneOrFetch("nested/helloworld.git", "https://github.com/git/hello-world.git", true);\r
+ cloneOrFetch("ticgit.git", "https://github.com/jeffWelling/ticgit.git", true);\r
+\r
+ enableTickets("ticgit.git");\r
+ enableDocs("ticgit.git");\r
+ showRemoteBranches("ticgit.git");\r
+ }\r
}\r
\r
private void cloneOrFetch(String toFolder, String fromUrl, boolean bare) throws Exception {\r
System.out.println("done.");\r
}\r
}\r
+\r
+ private void enableTickets(String repositoryName) {\r
+ try {\r
+ RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);\r
+ model.useTickets = true;\r
+ GitBlit.self().editRepositoryModel(model.name, model, false);\r
+ } catch (GitBlitException g) {\r
+ g.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ private void enableDocs(String repositoryName) {\r
+ try {\r
+ RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);\r
+ model.useDocs = true;\r
+ GitBlit.self().editRepositoryModel(model.name, model, false);\r
+ } catch (GitBlitException g) {\r
+ g.printStackTrace();\r
+ }\r
+ }\r
+ \r
+ private void showRemoteBranches(String repositoryName) {\r
+ try {\r
+ RepositoryModel model = GitBlit.self().getRepositoryModel(repositoryName);\r
+ model.showRemoteBranches = true;\r
+ GitBlit.self().editRepositoryModel(model.name, model, false);\r
+ } catch (GitBlitException g) {\r
+ g.printStackTrace();\r
+ }\r
+ }\r
}\r
\r
import java.io.File;\r
import java.io.FileOutputStream;\r
+import java.util.Arrays;\r
import java.util.Date;\r
import java.util.List;\r
+import java.util.Map;\r
\r
import junit.framework.TestCase;\r
\r
+import org.eclipse.jgit.diff.DiffEntry.ChangeType;\r
import org.eclipse.jgit.lib.Constants;\r
+import org.eclipse.jgit.lib.FileMode;\r
+import org.eclipse.jgit.lib.ObjectId;\r
+import org.eclipse.jgit.lib.PersonIdent;\r
import org.eclipse.jgit.lib.Repository;\r
-import org.eclipse.jgit.revwalk.RevBlob;\r
import org.eclipse.jgit.revwalk.RevCommit;\r
-import org.eclipse.jgit.revwalk.RevObject;\r
-import org.eclipse.jgit.revwalk.RevTree;\r
\r
import com.gitblit.GitBlit;\r
+import com.gitblit.Keys;\r
+import com.gitblit.models.PathModel;\r
import com.gitblit.models.PathModel.PathChangeModel;\r
import com.gitblit.models.RefModel;\r
import com.gitblit.utils.JGitUtils;\r
+import com.gitblit.utils.JGitUtils.SearchType;\r
\r
public class JGitUtilsTest extends TestCase {\r
\r
+ public void testDisplayName() throws Exception {\r
+ assertTrue(JGitUtils.getDisplayName(new PersonIdent("Napoleon Bonaparte", "")).equals(\r
+ "Napoleon Bonaparte"));\r
+ assertTrue(JGitUtils.getDisplayName(new PersonIdent("", "someone@somewhere.com")).equals(\r
+ "<someone@somewhere.com>"));\r
+ assertTrue(JGitUtils.getDisplayName(\r
+ new PersonIdent("Napoleon Bonaparte", "someone@somewhere.com")).equals(\r
+ "Napoleon Bonaparte <someone@somewhere.com>"));\r
+ }\r
+\r
public void testFindRepositories() {\r
List<String> list = JGitUtils.getRepositoryList(null, true, true);\r
assertTrue(list.size() == 0);\r
\r
public void testFirstCommit() throws Exception {\r
assertTrue(JGitUtils.getFirstChange(null, null).equals(new Date(0)));\r
- \r
+\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
RevCommit commit = JGitUtils.getFirstCommit(repository, null);\r
Date firstChange = JGitUtils.getFirstChange(repository, null);\r
commit.getName().equals("f554664a346629dc2b839f7292d06bad2db4aece"));\r
assertTrue(firstChange.equals(new Date(commit.getCommitTime() * 1000L)));\r
}\r
- \r
+\r
public void testLastCommit() throws Exception {\r
assertTrue(JGitUtils.getLastChange(null).equals(new Date(0)));\r
- \r
+\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
assertTrue(JGitUtils.getCommit(repository, null) != null);\r
Date date = JGitUtils.getLastChange(repository);\r
assertTrue("Could not get last repository change date!", date != null);\r
}\r
\r
- \r
-\r
public void testCreateRepository() throws Exception {\r
String[] repositories = { "NewTestRepository.git", "NewTestRepository" };\r
for (String repositoryName : repositories) {\r
repositoryName, isBare);\r
File folder;\r
if (isBare) {\r
- folder = new File(GitBlitSuite.REPOSITORIES, repositoryName); \r
+ folder = new File(GitBlitSuite.REPOSITORIES, repositoryName);\r
} else {\r
folder = new File(GitBlitSuite.REPOSITORIES, repositoryName + "/.git");\r
- } \r
+ }\r
assertTrue(repository != null);\r
assertFalse(JGitUtils.hasCommits(repository));\r
assertTrue(JGitUtils.getFirstCommit(repository, null) == null);\r
assertTrue(JGitUtils.getFirstChange(repository, null).getTime() == folder\r
.lastModified());\r
- assertTrue(JGitUtils.getLastChange(repository).getTime() == folder\r
- .lastModified());\r
+ assertTrue(JGitUtils.getLastChange(repository).getTime() == folder.lastModified());\r
assertTrue(JGitUtils.getCommit(repository, null) == null);\r
repository.close();\r
assertTrue(GitBlit.self().deleteRepository(repositoryName));\r
}\r
\r
public void testRefs() throws Exception {\r
+ Repository repository = GitBlitSuite.getTicgitRepository();\r
+ Map<ObjectId, List<String>> map = JGitUtils.getAllRefs(repository);\r
+ repository.close();\r
+ assertTrue(map.size() > 0);\r
+ }\r
+\r
+ public void testBranches() throws Exception {\r
Repository repository = GitBlitSuite.getTicgitRepository();\r
for (RefModel model : JGitUtils.getLocalBranches(repository, -1)) {\r
assertTrue(model.getName().startsWith(Constants.R_HEADS));\r
+ model.getName().hashCode());\r
assertTrue(model.getShortLog().equals(model.commit.getShortMessage()));\r
}\r
+ assertTrue(JGitUtils.getRemoteBranches(repository, 10).size() == 10);\r
+ repository.close();\r
+ }\r
+\r
+ public void testTags() throws Exception {\r
+ Repository repository = GitBlitSuite.getTicgitRepository();\r
for (RefModel model : JGitUtils.getTags(repository, -1)) {\r
if (model.getObjectId().getName().equals("283035e4848054ff1803cb0e690270787dc92399")) {\r
assertTrue("Not an annotated tag!", model.isAnnotatedTag());\r
repository.close();\r
}\r
\r
- public void testRetrieveRevObject() throws Exception {\r
- Repository repository = GitBlitSuite.getHelloworldRepository();\r
- RevCommit commit = JGitUtils.getCommit(repository, Constants.HEAD);\r
- RevTree tree = commit.getTree();\r
- RevObject object = JGitUtils.getRevObject(repository, tree, "java.java");\r
- repository.close();\r
- assertTrue("Object is null!", object != null);\r
+ public void testCommitNotes() throws Exception {\r
+// Repository repository = new FileRepository(new File("c:/projects/git/jgit.git/.git"));\r
+// RevCommit commit = JGitUtils.getCommit(repository,\r
+// "ada903085d1b4ef8c79e3e2d91f49fee7e188f53");\r
+// List<GitNote> list = JGitUtils.getNotesOnCommit(repository, commit);\r
+// repository.close();\r
+// assertTrue(list.size() > 0);\r
}\r
\r
- public void testRetrieveStringContent() throws Exception {\r
+ public void testStringContent() throws Exception {\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ String contentA = JGitUtils.getRawContentAsString(repository, null, "java.java");\r
RevCommit commit = JGitUtils.getCommit(repository, Constants.HEAD);\r
- RevTree tree = commit.getTree();\r
- RevBlob blob = (RevBlob) JGitUtils.getRevObject(repository, tree, "java.java");\r
- String content = JGitUtils.getRawContentAsString(repository, blob);\r
+ String contentB = JGitUtils.getRawContentAsString(repository, commit, "java.java");\r
+ String contentC = JGitUtils.getRawContentAsString(repository, commit, "missing.txt");\r
repository.close();\r
- assertTrue("Content is null!", content != null && content.length() > 0);\r
+ assertTrue("ContentA is null!", contentA != null && contentA.length() > 0);\r
+ assertTrue("ContentB is null!", contentB != null && contentB.length() > 0);\r
+ assertTrue(contentA.equals(contentB));\r
+ assertTrue(contentC == null);\r
}\r
\r
public void testFilesInCommit() throws Exception {\r
RevCommit commit = JGitUtils.getCommit(repository,\r
"1d0c2933a4ae69c362f76797d42d6bd182d05176");\r
List<PathChangeModel> paths = JGitUtils.getFilesInCommit(repository, commit);\r
+\r
+ commit = JGitUtils.getCommit(repository, "af0e9b2891fda85afc119f04a69acf7348922830");\r
+ List<PathChangeModel> deletions = JGitUtils.getFilesInCommit(repository, commit);\r
+\r
+ commit = JGitUtils.getFirstCommit(repository, null);\r
+ List<PathChangeModel> additions = JGitUtils.getFilesInCommit(repository, commit);\r
+\r
+ List<PathChangeModel> latestChanges = JGitUtils.getFilesInCommit(repository, null);\r
+\r
repository.close();\r
assertTrue("No changed paths found!", paths.size() == 1);\r
for (PathChangeModel path : paths) {\r
assertTrue("PathChangeModel equals itself failed!", path.equals(path));\r
assertFalse("PathChangeModel equals string failed!", path.equals(""));\r
}\r
+ assertTrue(deletions.get(0).changeType.equals(ChangeType.DELETE));\r
+ assertTrue(additions.get(0).changeType.equals(ChangeType.ADD));\r
+ assertTrue(latestChanges.size() > 0);\r
+ }\r
+\r
+ public void testFilesInPath() throws Exception {\r
+ assertTrue(JGitUtils.getFilesInPath(null, null, null).size() == 0);\r
+ Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ List<PathModel> files = JGitUtils.getFilesInPath(repository, null, null);\r
+ repository.close();\r
+ assertTrue(files.size() > 10);\r
+ }\r
+\r
+ public void testDocuments() throws Exception {\r
+ Repository repository = GitBlitSuite.getTicgitRepository();\r
+ List<String> extensions = GitBlit.getStrings(Keys.web.markdownExtensions);\r
+ List<PathModel> markdownDocs = JGitUtils.getDocuments(repository, extensions);\r
+ List<PathModel> markdownDocs2 = JGitUtils.getDocuments(repository,\r
+ Arrays.asList(new String[] { ".mkd", ".md" }));\r
+ List<PathModel> allFiles = JGitUtils.getDocuments(repository, null);\r
+ repository.close();\r
+ assertTrue(markdownDocs.size() > 0);\r
+ assertTrue(markdownDocs2.size() > 0);\r
+ assertTrue(allFiles.size() > markdownDocs.size());\r
+ }\r
+\r
+ public void testFileModes() throws Exception {\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.TREE.getBits()).equals("drwxr-xr-x"));\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.REGULAR_FILE.getBits()).equals(\r
+ "-rw-r--r--"));\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.EXECUTABLE_FILE.getBits()).equals(\r
+ "-rwxr-xr-x"));\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.SYMLINK.getBits()).equals("symlink"));\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.GITLINK.getBits()).equals("gitlink"));\r
+ assertTrue(JGitUtils.getPermissionsFromMode(FileMode.MISSING.getBits()).equals("missing"));\r
+ }\r
+\r
+ public void testRevlog() throws Exception {\r
+ List<RevCommit> commits = JGitUtils.getRevLog(null, 10);\r
+ assertTrue(commits.size() == 0);\r
+\r
+ Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ // get most recent 10 commits\r
+ commits = JGitUtils.getRevLog(repository, 10);\r
+ assertTrue(commits.size() == 10);\r
+\r
+ // test paging and offset by getting the 10th most recent commit\r
+ RevCommit lastCommit = JGitUtils.getRevLog(repository, null, 9, 1).get(0);\r
+ assertTrue(commits.get(9).equals(lastCommit));\r
+\r
+ // grab the two most recent commits to java.java\r
+ commits = JGitUtils.getRevLog(repository, null, "java.java", 0, 2);\r
+ assertTrue(commits.size() == 2);\r
+ repository.close();\r
+ }\r
+\r
+ public void testSearchTypes() throws Exception {\r
+ assertTrue(SearchType.forName("commit").equals(SearchType.COMMIT));\r
+ assertTrue(SearchType.forName("committer").equals(SearchType.COMMITTER));\r
+ assertTrue(SearchType.forName("author").equals(SearchType.AUTHOR));\r
+ assertTrue(SearchType.forName("unknown").equals(SearchType.COMMIT));\r
+\r
+ assertTrue(SearchType.COMMIT.toString().equals("commit"));\r
+ assertTrue(SearchType.COMMITTER.toString().equals("committer"));\r
+ assertTrue(SearchType.AUTHOR.toString().equals("author"));\r
+ }\r
+\r
+ public void testSearchRevlogs() throws Exception {\r
+ List<RevCommit> results = JGitUtils.searchRevlogs(null, null, "java", SearchType.COMMIT, 0,\r
+ 3);\r
+ assertTrue(results.size() == 0);\r
+\r
+ // test commit message search\r
+ Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ results = JGitUtils.searchRevlogs(repository, null, "java", SearchType.COMMIT, 0, 3);\r
+ assertTrue(results.size() == 3);\r
+\r
+ // test author search\r
+ results = JGitUtils.searchRevlogs(repository, null, "timothy", SearchType.AUTHOR, 0, -1);\r
+ assertTrue(results.size() == 1);\r
+\r
+ // test committer search\r
+ results = JGitUtils.searchRevlogs(repository, null, "mike", SearchType.COMMITTER, 0, 10);\r
+ assertTrue(results.size() == 10);\r
+\r
+ // test paging and offset\r
+ RevCommit commit = JGitUtils.searchRevlogs(repository, null, "mike", SearchType.COMMITTER,\r
+ 9, 1).get(0);\r
+ assertTrue(results.get(9).equals(commit));\r
+\r
+ repository.close();\r
}\r
\r
public void testZip() throws Exception {\r
+ assertFalse(JGitUtils.zip(null, null, null, null));\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
- File zipFile = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip");\r
- FileOutputStream fos = new FileOutputStream(zipFile);\r
- boolean success = JGitUtils.zip(repository, null, Constants.HEAD, fos);\r
- assertTrue("Failed to generate zip file!", success);\r
- assertTrue(zipFile.length() > 0);\r
- fos.close();\r
- zipFile.delete();\r
+ File zipFileA = new File(GitBlitSuite.REPOSITORIES, "helloworld.zip");\r
+ FileOutputStream fosA = new FileOutputStream(zipFileA);\r
+ boolean successA = JGitUtils.zip(repository, 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 = JGitUtils.zip(repository, "java.java", Constants.HEAD, fosB);\r
+ fosB.close();\r
+\r
repository.close();\r
+ assertTrue("Failed to generate zip file!", successA);\r
+ assertTrue(zipFileA.length() > 0);\r
+ zipFileA.delete();\r
+\r
+ assertTrue("Failed to generate zip file!", successB);\r
+ assertTrue(zipFileB.length() > 0);\r
+ zipFileB.delete();\r
}\r
}
\ No newline at end of file
--- /dev/null
+/*\r
+ * Copyright 2011 gitblit.com.\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+package com.gitblit.tests;\r
+\r
+import java.text.ParseException;\r
+\r
+import junit.framework.TestCase;\r
+\r
+import com.gitblit.utils.MarkdownUtils;\r
+\r
+public class MarkdownUtilsTest extends TestCase {\r
+\r
+ public void testMarkdown() throws Exception {\r
+ assertTrue(MarkdownUtils.transformMarkdown("# H1").equals("<h1> H1</h1>"));\r
+ assertTrue(MarkdownUtils.transformMarkdown("## H2").equals("<h2> H2</h2>"));\r
+ try {\r
+ MarkdownUtils.transformMarkdown((String) null);\r
+ assertTrue(false);\r
+ } catch (ParseException p) {\r
+ assertTrue(p != null);\r
+ }\r
+ }\r
+}
\ No newline at end of file
\r
public void testMetrics() throws Exception {\r
Repository repository = GitBlitSuite.getHelloworldRepository();\r
- List<Metric> metrics = MetricUtils.getDateMetrics(repository, true);\r
+ List<Metric> metrics = MetricUtils.getDateMetrics(repository, true, null);\r
repository.close();\r
- assertTrue("No metrics found!", metrics.size() > 0);\r
+ assertTrue("No date metrics found!", metrics.size() > 0);\r
+ }\r
+ \r
+ public void testAuthorMetrics() throws Exception {\r
+ Repository repository = GitBlitSuite.getHelloworldRepository();\r
+ List<Metric> byEmail = MetricUtils.getAuthorMetrics(repository, true);\r
+ List<Metric> byName = MetricUtils.getAuthorMetrics(repository, false);\r
+ repository.close();\r
+ assertTrue("No author metrics found!", byEmail.size() == 9);\r
+ assertTrue("No author metrics found!", byName.size() == 8);\r
}\r
}
\ No newline at end of file
\r
public class TicgitUtilsTest extends TestCase {\r
\r
- public void testTicGit() throws Exception {\r
+ public void testTicgitBranch() throws Exception {\r
Repository repository = GitBlitSuite.getTicgitRepository();\r
RefModel branch = TicgitUtils.getTicketsBranch(repository);\r
+ repository.close();\r
assertTrue("Ticgit branch does not exist!", branch != null);\r
+ \r
+ repository = GitBlitSuite.getHelloworldRepository();\r
+ branch = TicgitUtils.getTicketsBranch(repository);\r
+ repository.close();\r
+ assertTrue("Ticgit branch exists!", branch == null);\r
+ }\r
+\r
+ public void testRetrieveTickets() throws Exception {\r
+ Repository repository = GitBlitSuite.getTicgitRepository();\r
List<TicketModel> ticketsA = TicgitUtils.getTickets(repository);\r
List<TicketModel> ticketsB = TicgitUtils.getTickets(repository);\r
repository.close();\r
assertTrue(commentA.hashCode() == commentA.text.hashCode());\r
}\r
}\r
+ \r
+ repository = GitBlitSuite.getHelloworldRepository();\r
+ List<TicketModel> ticketsC = TicgitUtils.getTickets(repository);\r
+ repository.close();\r
+ assertTrue(ticketsC == null);\r
+ }\r
+\r
+ public void testReadTicket() throws Exception {\r
+ Repository repository = GitBlitSuite.getTicgitRepository();\r
+ List<TicketModel> tickets = TicgitUtils.getTickets(repository);\r
+ TicketModel ticket = TicgitUtils\r
+ .getTicket(repository, tickets.get(tickets.size() - 1).name);\r
+ repository.close();\r
+ assertTrue(ticket != null);\r
+ assertTrue(ticket.name\r
+ .equals("1254123752_comments-on-ticgits-longer-than-5-lines-can-t-be-viewed-entirely_266"));\r
}\r
}
\ No newline at end of file