src/com/gitblit/Constants.java
@@ -88,6 +88,8 @@ public static final String ISO8601 = "yyyy-MM-dd'T'HH:mm:ssZ"; public static final String R_GITBLIT = "refs/gitblit/"; public static String getGitBlitVersion() { return NAME + " v" + VERSION; } src/com/gitblit/GitServlet.java
@@ -29,6 +29,7 @@ import java.util.Enumeration; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import javax.servlet.ServletConfig; @@ -37,7 +38,9 @@ import javax.servlet.http.HttpServletRequest; import org.eclipse.jgit.http.server.resolver.DefaultReceivePackFactory; import org.eclipse.jgit.http.server.resolver.DefaultUploadPackFactory; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.Ref; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.PostReceiveHook; @@ -45,6 +48,8 @@ import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceiveCommand.Result; import org.eclipse.jgit.transport.ReceivePack; import org.eclipse.jgit.transport.RefFilter; import org.eclipse.jgit.transport.UploadPack; import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException; import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException; import org.slf4j.Logger; @@ -55,7 +60,9 @@ import com.gitblit.models.UserModel; import com.gitblit.utils.ClientLogger; import com.gitblit.utils.HttpUtils; import com.gitblit.utils.IssueUtils; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.PushLogUtils; import com.gitblit.utils.StringUtils; /** @@ -129,6 +136,35 @@ } return rp; } }); // override the default upload pack to exclude gitblit refs setUploadPackFactory(new DefaultUploadPackFactory() { @Override public UploadPack create(final HttpServletRequest req, final Repository db) throws ServiceNotEnabledException, ServiceNotAuthorizedException { UploadPack up = super.create(req, db); RefFilter refFilter = new RefFilter() { @Override public Map<String, Ref> filter(Map<String, Ref> refs) { // admin accounts can access all refs UserModel user = GitBlit.self().authenticate(req); if (user == null) { user = UserModel.ANONYMOUS; } if (user.canAdmin()) { return refs; } // normal users can not clone gitblit refs refs.remove(IssueUtils.GB_ISSUES); refs.remove(PushLogUtils.GB_PUSHES); return refs; } }; up.setRefFilter(refFilter); return up; } }); super.init(new GitblitServletConfig(config)); @@ -264,12 +300,11 @@ logger.info("skipping post-receive hooks, no refs created, updated, or removed"); return; } RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName); Set<String> scripts = new LinkedHashSet<String>(); scripts.addAll(GitBlit.self().getPostReceiveScriptsInherited(repository)); scripts.addAll(repository.postReceiveScripts); UserModel user = getUserModel(rp); runGroovy(repository, user, commands, rp, scripts); RepositoryModel repository = GitBlit.self().getRepositoryModel(repositoryName); // log ref changes for (ReceiveCommand cmd : commands) { if (Result.OK.equals(cmd.getResult())) { // add some logging for important ref changes @@ -289,6 +324,16 @@ } } // update push log PushLogUtils.updatePushLog(user, rp.getRepository(), commands); logger.info(MessageFormat.format("{0} push log updated", repository.name)); // run Groovy hook scripts Set<String> scripts = new LinkedHashSet<String>(); scripts.addAll(GitBlit.self().getPostReceiveScriptsInherited(repository)); scripts.addAll(repository.postReceiveScripts); runGroovy(repository, user, commands, rp, scripts); // Experimental // runNativeScript(rp, "hooks/post-receive", commands); } src/com/gitblit/models/Activity.java
@@ -25,7 +25,6 @@ import java.util.Map; import java.util.Set; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.revwalk.RevCommit; import com.gitblit.utils.StringUtils; @@ -126,87 +125,5 @@ public int compareTo(Activity o) { // reverse chronological order return o.startDate.compareTo(startDate); } /** * Model class to represent a RevCommit, it's source repository, and the * branch. This class is used by the activity page. * * @author James Moger */ public static class RepositoryCommit implements Serializable, Comparable<RepositoryCommit> { private static final long serialVersionUID = 1L; public final String repository; public final String branch; private final RevCommit commit; private List<RefModel> refs; public RepositoryCommit(String repository, String branch, RevCommit commit) { this.repository = repository; this.branch = branch; this.commit = commit; } public void setRefs(List<RefModel> refs) { this.refs = refs; } public List<RefModel> getRefs() { return refs; } public String getName() { return commit.getName(); } public String getShortName() { return commit.getName().substring(0, 8); } public String getShortMessage() { return commit.getShortMessage(); } public int getParentCount() { return commit.getParentCount(); } public PersonIdent getAuthorIdent() { return commit.getAuthorIdent(); } public PersonIdent getCommitterIdent() { return commit.getCommitterIdent(); } @Override public boolean equals(Object o) { if (o instanceof RepositoryCommit) { RepositoryCommit commit = (RepositoryCommit) o; return repository.equals(commit.repository) && getName().equals(commit.getName()); } return false; } @Override public int hashCode() { return (repository + commit).hashCode(); } @Override public int compareTo(RepositoryCommit o) { // reverse-chronological order if (commit.getCommitTime() > o.commit.getCommitTime()) { return -1; } else if (commit.getCommitTime() < o.commit.getCommitTime()) { return 1; } return 0; } } } src/com/gitblit/models/PushLogEntry.java
New file @@ -0,0 +1,166 @@ /* * Copyright 2013 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; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.revwalk.RevCommit; /** * Model class to represent a push into a repository. * * @author James Moger */ public class PushLogEntry implements Serializable, Comparable<PushLogEntry> { private static final long serialVersionUID = 1L; public final String repository; public final Date date; public final UserModel user; private final Set<RepositoryCommit> commits; /** * Constructor for specified duration of push from start date. * * @param repository * the repository that received the push * @param date * the date of the push * @param user * the user who pushed */ public PushLogEntry(String repository, Date date, UserModel user) { this.repository = repository; this.date = date; this.user = user; this.commits = new LinkedHashSet<RepositoryCommit>(); } /** * Adds a commit to the push entry object as long as the commit is not a * duplicate. * * @param branch * @param commit * @return a RepositoryCommit, if one was added. Null if this is duplicate * commit */ public RepositoryCommit addCommit(String branch, RevCommit commit) { RepositoryCommit commitModel = new RepositoryCommit(repository, branch, commit); if (commits.add(commitModel)) { return commitModel; } return null; } /** * Returns the list of branches changed by the push. * * @return a list of branches */ public List<String> getChangedBranches() { return getChangedRefs(Constants.R_HEADS); } /** * Returns the list of tags changed by the push. * * @return a list of tags */ public List<String> getChangedTags() { return getChangedRefs(Constants.R_TAGS); } /** * Gets the changed refs in the push. * * @param baseRef * @return the changed refs */ protected List<String> getChangedRefs(String baseRef) { Set<String> refs = new HashSet<String>(); for (RepositoryCommit commit : commits) { if (baseRef == null || commit.branch.startsWith(baseRef)) { refs.add(commit.branch); } } List<String> list = new ArrayList<String>(refs); Collections.sort(list); return list; } /** * The total number of commits in the push. * * @return the number of commits in the push */ public int getCommitCount() { return commits.size(); } /** * Returns all commits in the push. * * @return a list of commits */ public List<RepositoryCommit> getCommits() { List<RepositoryCommit> list = new ArrayList<RepositoryCommit>(commits); Collections.sort(list); return list; } /** * Returns all commits that belong to a particular ref * * @param ref * @return a list of commits */ public List<RepositoryCommit> getCommits(String ref) { List<RepositoryCommit> list = new ArrayList<RepositoryCommit>(); for (RepositoryCommit commit : commits) { if (commit.branch.equals(ref)) { list.add(commit); } } Collections.sort(list); return list; } @Override public int compareTo(PushLogEntry o) { // reverse chronological order return o.date.compareTo(date); } @Override public String toString() { return MessageFormat.format("{0,date,yyyy-MM-dd HH:mm}: {1} pushed {2,number,0} commit{3} to {4} ", date, user.getDisplayName(), commits.size(), commits.size() == 1 ? "":"s", repository); } } src/com/gitblit/models/RepositoryCommit.java
New file @@ -0,0 +1,104 @@ /* * 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; import java.util.List; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.revwalk.RevCommit; /** * Model class to represent a RevCommit, it's source repository, and the branch. * This class is used by the activity page. * * @author James Moger */ public class RepositoryCommit implements Serializable, Comparable<RepositoryCommit> { private static final long serialVersionUID = 1L; public final String repository; public final String branch; private final RevCommit commit; private List<RefModel> refs; public RepositoryCommit(String repository, String branch, RevCommit commit) { this.repository = repository; this.branch = branch; this.commit = commit; } public void setRefs(List<RefModel> refs) { this.refs = refs; } public List<RefModel> getRefs() { return refs; } public String getName() { return commit.getName(); } public String getShortName() { return commit.getName().substring(0, 8); } public String getShortMessage() { return commit.getShortMessage(); } public int getParentCount() { return commit.getParentCount(); } public PersonIdent getAuthorIdent() { return commit.getAuthorIdent(); } public PersonIdent getCommitterIdent() { return commit.getCommitterIdent(); } @Override public boolean equals(Object o) { if (o instanceof RepositoryCommit) { RepositoryCommit commit = (RepositoryCommit) o; return repository.equals(commit.repository) && getName().equals(commit.getName()); } return false; } @Override public int hashCode() { return (repository + commit).hashCode(); } @Override public int compareTo(RepositoryCommit o) { // reverse-chronological order if (commit.getCommitTime() > o.commit.getCommitTime()) { return -1; } else if (commit.getCommitTime() < o.commit.getCommitTime()) { return 1; } return 0; } } src/com/gitblit/utils/ActivityUtils.java
@@ -36,9 +36,9 @@ import com.gitblit.GitBlit; import com.gitblit.models.Activity; import com.gitblit.models.Activity.RepositoryCommit; import com.gitblit.models.GravatarProfile; import com.gitblit.models.RefModel; import com.gitblit.models.RepositoryCommit; import com.gitblit.models.RepositoryModel; import com.google.gson.reflect.TypeToken; src/com/gitblit/utils/IssueUtils.java
@@ -76,9 +76,9 @@ public abstract boolean accept(IssueModel issue); } public static final String GB_ISSUES = "refs/heads/gb-issues"; public static final String GB_ISSUES = "refs/gitblit/issues"; static final Logger LOGGER = LoggerFactory.getLogger(JGitUtils.class); static final Logger LOGGER = LoggerFactory.getLogger(IssueUtils.class); /** * Log an error message and exception. @@ -111,7 +111,13 @@ * @return a refmodel for the gb-issues branch or null */ public static RefModel getIssuesBranch(Repository repository) { return JGitUtils.getBranch(repository, "gb-issues"); List<RefModel> refs = JGitUtils.getRefs(repository, com.gitblit.Constants.R_GITBLIT); for (RefModel ref : refs) { if (ref.reference.getName().equals(GB_ISSUES)) { return ref; } } return null; } /** @@ -394,7 +400,7 @@ public static IssueModel createIssue(Repository repository, Change change) { RefModel issuesBranch = getIssuesBranch(repository); if (issuesBranch == null) { JGitUtils.createOrphanBranch(repository, "gb-issues", null); JGitUtils.createOrphanBranch(repository, GB_ISSUES, null); } if (StringUtils.isEmpty(change.author)) { @@ -471,7 +477,7 @@ RefModel issuesBranch = getIssuesBranch(repository); if (issuesBranch == null) { throw new RuntimeException("gb-issues branch does not exist!"); throw new RuntimeException(GB_ISSUES + " does not exist!"); } if (StringUtils.isEmpty(issueId)) { src/com/gitblit/utils/JGitUtils.java
@@ -1457,6 +1457,20 @@ int maxCount) { return getRefs(repository, Constants.R_NOTES, fullName, maxCount); } /** * Returns the list of refs in the specified base ref. If repository does * not exist or is empty, an empty list is returned. * * @param repository * @param fullName * if true, /refs/yadayadayada is returned. If false, * yadayadayada is returned. * @return list of refs */ public static List<RefModel> getRefs(Repository repository, String baseRef) { return getRefs(repository, baseRef, true, -1); } /** * Returns a list of references in the repository matching "refs". If the src/com/gitblit/utils/PushLogUtils.java
New file @@ -0,0 +1,344 @@ /* * Copyright 2013 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.utils; import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.Date; import java.util.List; import java.util.Set; import java.util.TreeSet; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; import org.eclipse.jgit.api.errors.JGitInternalException; import org.eclipse.jgit.dircache.DirCache; import org.eclipse.jgit.dircache.DirCacheBuilder; import org.eclipse.jgit.dircache.DirCacheEntry; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.CommitBuilder; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.ObjectInserter; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.lib.RefUpdate; import org.eclipse.jgit.lib.RefUpdate.Result; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.treewalk.CanonicalTreeParser; import org.eclipse.jgit.treewalk.TreeWalk; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.PushLogEntry; import com.gitblit.models.RefModel; import com.gitblit.models.UserModel; /** * Utility class for maintaining a pushlog within a git repository on an * orphan branch. * * @author James Moger * */ public class PushLogUtils { public static final String GB_PUSHES = "refs/gitblit/pushes"; static final Logger LOGGER = LoggerFactory.getLogger(PushLogUtils.class); /** * Log an error message and exception. * * @param t * @param repository * if repository is not null it MUST be the {0} parameter in the * pattern. * @param pattern * @param objects */ private static void error(Throwable t, Repository repository, String pattern, Object... objects) { List<Object> parameters = new ArrayList<Object>(); if (objects != null && objects.length > 0) { for (Object o : objects) { parameters.add(o); } } if (repository != null) { parameters.add(0, repository.getDirectory().getAbsolutePath()); } LOGGER.error(MessageFormat.format(pattern, parameters.toArray()), t); } /** * Returns a RefModel for the gb-pushes branch in the repository. If the * branch can not be found, null is returned. * * @param repository * @return a refmodel for the gb-pushes branch or null */ public static RefModel getPushLogBranch(Repository repository) { List<RefModel> refs = JGitUtils.getRefs(repository, com.gitblit.Constants.R_GITBLIT); for (RefModel ref : refs) { if (ref.reference.getName().equals(GB_PUSHES)) { return ref; } } return null; } /** * Updates a push log. * * @param user * @param repository * @param commands * @return true, if the update was successful */ public static boolean updatePushLog(UserModel user, Repository repository, Collection<ReceiveCommand> commands) { RefModel pushlogBranch = getPushLogBranch(repository); if (pushlogBranch == null) { JGitUtils.createOrphanBranch(repository, GB_PUSHES, null); } boolean success = false; String message = "push"; try { ObjectId headId = repository.resolve(GB_PUSHES + "^{commit}"); ObjectInserter odi = repository.newObjectInserter(); try { // Create the in-memory index of the push log entry DirCache index = createIndex(repository, headId, commands); ObjectId indexTreeId = index.writeTree(odi); PersonIdent ident = new PersonIdent(user.getDisplayName(), user.emailAddress == null ? user.username:user.emailAddress); // Create a commit object CommitBuilder commit = new CommitBuilder(); commit.setAuthor(ident); commit.setCommitter(ident); commit.setEncoding(Constants.CHARACTER_ENCODING); commit.setMessage(message); commit.setParentId(headId); commit.setTreeId(indexTreeId); // Insert the commit into the repository ObjectId commitId = odi.insert(commit); odi.flush(); RevWalk revWalk = new RevWalk(repository); try { RevCommit revCommit = revWalk.parseCommit(commitId); RefUpdate ru = repository.updateRef(GB_PUSHES); ru.setNewObjectId(commitId); ru.setExpectedOldObjectId(headId); ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false); Result rc = ru.forceUpdate(); switch (rc) { case NEW: case FORCED: case FAST_FORWARD: success = true; break; case REJECTED: case LOCK_FAILURE: throw new ConcurrentRefUpdateException(JGitText.get().couldNotLockHEAD, ru.getRef(), rc); default: throw new JGitInternalException(MessageFormat.format( JGitText.get().updatingRefFailed, GB_PUSHES, commitId.toString(), rc)); } } finally { revWalk.release(); } } finally { odi.release(); } } catch (Throwable t) { error(t, repository, "Failed to commit pushlog entry to {0}"); } return success; } /** * Creates an in-memory index of the push log entry. * * @param repo * @param headId * @param commands * @return an in-memory index * @throws IOException */ private static DirCache createIndex(Repository repo, ObjectId headId, Collection<ReceiveCommand> commands) throws IOException { DirCache inCoreIndex = DirCache.newInCore(); DirCacheBuilder dcBuilder = inCoreIndex.builder(); ObjectInserter inserter = repo.newObjectInserter(); long now = System.currentTimeMillis(); Set<String> ignorePaths = new TreeSet<String>(); try { // add receive commands to the temporary index for (ReceiveCommand command : commands) { // use the ref names as the path names String path = command.getRefName(); ignorePaths.add(path); StringBuilder change = new StringBuilder(); change.append(command.getType().name()).append(' '); switch (command.getType()) { case CREATE: change.append(ObjectId.zeroId().getName()); change.append(' '); change.append(command.getNewId().getName()); break; case UPDATE: case UPDATE_NONFASTFORWARD: change.append(command.getOldId().getName()); change.append(' '); change.append(command.getNewId().getName()); break; case DELETE: change = null; break; } if (change == null) { // ref deleted continue; } String content = change.toString(); // create an index entry for this attachment final DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.setLength(content.length()); dcEntry.setLastModified(now); dcEntry.setFileMode(FileMode.REGULAR_FILE); // insert object dcEntry.setObjectId(inserter.insert(Constants.OBJ_BLOB, content.getBytes("UTF-8"))); // add to temporary in-core index dcBuilder.add(dcEntry); } // Traverse HEAD to add all other paths TreeWalk treeWalk = new TreeWalk(repo); int hIdx = -1; if (headId != null) hIdx = treeWalk.addTree(new RevWalk(repo).parseTree(headId)); treeWalk.setRecursive(true); while (treeWalk.next()) { String path = treeWalk.getPathString(); CanonicalTreeParser hTree = null; if (hIdx != -1) hTree = treeWalk.getTree(hIdx, CanonicalTreeParser.class); if (!ignorePaths.contains(path)) { // add entries from HEAD for all other paths if (hTree != null) { // create a new DirCacheEntry with data retrieved from // HEAD final DirCacheEntry dcEntry = new DirCacheEntry(path); dcEntry.setObjectId(hTree.getEntryObjectId()); dcEntry.setFileMode(hTree.getEntryFileMode()); // add to temporary in-core index dcBuilder.add(dcEntry); } } } // release the treewalk treeWalk.release(); // finish temporary in-core index used for this commit dcBuilder.finish(); } finally { inserter.release(); } return inCoreIndex; } public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository) { return getPushLog(repositoryName, repository, null, -1); } public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, int maxCount) { return getPushLog(repositoryName, repository, null, maxCount); } public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, Date minimumDate) { return getPushLog(repositoryName, repository, minimumDate, -1); } public static List<PushLogEntry> getPushLog(String repositoryName, Repository repository, Date minimumDate, int maxCount) { List<PushLogEntry> list = new ArrayList<PushLogEntry>(); RefModel ref = getPushLogBranch(repository); if (ref == null) { return list; } List<RevCommit> pushes; if (minimumDate == null) { pushes = JGitUtils.getRevLog(repository, GB_PUSHES, 0, maxCount); } else { pushes = JGitUtils.getRevLog(repository, GB_PUSHES, minimumDate); } for (RevCommit push : pushes) { if (push.getAuthorIdent().getName().equalsIgnoreCase("gitblit")) { // skip gitblit/internal commits continue; } Date date = push.getAuthorIdent().getWhen(); UserModel user = new UserModel(push.getAuthorIdent().getEmailAddress()); user.displayName = push.getAuthorIdent().getName(); PushLogEntry log = new PushLogEntry(repositoryName, date, user); list.add(log); List<PathChangeModel> changedRefs = JGitUtils.getFilesInCommit(repository, push); for (PathChangeModel change : changedRefs) { switch (change.changeType) { case DELETE: break; case ADD: case MODIFY: String content = JGitUtils.getStringContent(repository, push.getTree(), change.path); String [] fields = content.split(" "); String oldId = fields[1]; String newId = fields[2]; List<RevCommit> pushedCommits = JGitUtils.getRevLog(repository, oldId, newId); for (RevCommit pushedCommit : pushedCommits) { log.addCommit(change.path, pushedCommit); } break; default: break; } } } Collections.sort(list); return list; } } src/com/gitblit/wicket/panels/ActivityPanel.java
@@ -27,7 +27,7 @@ import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.Activity; import com.gitblit.models.Activity.RepositoryCommit; import com.gitblit.models.RepositoryCommit; import com.gitblit.utils.StringUtils; import com.gitblit.wicket.WicketUtils; import com.gitblit.wicket.pages.CommitDiffPage; src/com/gitblit/wicket/panels/RefsPanel.java
@@ -129,8 +129,14 @@ name = name.substring(Constants.R_TAGS.length()); cssClass = "tagRef"; } else if (name.startsWith(Constants.R_NOTES)) { // codereview refs linkClass = CommitPage.class; cssClass = "otherRef"; } else if (name.startsWith(com.gitblit.Constants.R_GITBLIT)) { // gitblit refs linkClass = LogPage.class; cssClass = "otherRef"; name = name.substring(com.gitblit.Constants.R_GITBLIT.length()); } Component c = new LinkPanel("refName", null, name, linkClass, tests/com/gitblit/tests/GitServletTest.java
@@ -7,9 +7,11 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.text.MessageFormat; import java.util.Date; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; import org.eclipse.jgit.api.CloneCommand; @@ -18,6 +20,7 @@ import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileRepository; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.RefSpec; @@ -34,9 +37,11 @@ import com.gitblit.Constants.AuthorizationControl; import com.gitblit.GitBlit; import com.gitblit.Keys; import com.gitblit.models.PushLogEntry; import com.gitblit.models.RepositoryModel; import com.gitblit.models.UserModel; import com.gitblit.utils.JGitUtils; import com.gitblit.utils.PushLogUtils; public class GitServletTest { @@ -756,4 +761,14 @@ GitBlitSuite.close(git); GitBlit.self().deleteUser(user.username); } @Test public void testPushLog() throws IOException { String name = "refchecks/ticgit.git"; File refChecks = new File(GitBlitSuite.REPOSITORIES, name); FileRepository repository = new FileRepository(refChecks); List<PushLogEntry> pushes = PushLogUtils.getPushLog(name, repository); GitBlitSuite.close(repository); assertTrue("Repository has an empty push log!", pushes.size() > 0); } } tests/com/gitblit/tests/PushLogTest.java
New file @@ -0,0 +1,37 @@ /* * Copyright 2013 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.io.File; import java.io.IOException; import java.util.List; import org.eclipse.jgit.storage.file.FileRepository; import org.junit.Test; import com.gitblit.models.PushLogEntry; import com.gitblit.utils.PushLogUtils; public class PushLogTest { @Test public void testPushLog() throws IOException { String name = "~james/helloworld.git"; FileRepository repository = new FileRepository(new File(GitBlitSuite.REPOSITORIES, name)); List<PushLogEntry> pushes = PushLogUtils.getPushLog(name, repository); GitBlitSuite.close(repository); } }