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