Procházet zdrojové kódy

Draft mechanism to record a push log as a hidden orphan branch

tags/v1.2.1
James Moger před 11 roky
rodič
revize
f8bb95d50a

+ 2
- 0
src/com/gitblit/Constants.java Zobrazit soubor

@@ -88,6 +88,8 @@ public class Constants {
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;
}

+ 50
- 5
src/com/gitblit/GitServlet.java Zobrazit soubor

@@ -29,6 +29,7 @@ import java.util.Collection;
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.ServletException;
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.PreReceiveHook;
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.RepositoryModel;
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;
/**
@@ -131,6 +138,35 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet {
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 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet {
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
@@ -288,6 +323,16 @@ public class GitServlet extends org.eclipse.jgit.http.server.GitServlet {
}
}
}
// 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);

+ 0
- 83
src/com/gitblit/models/Activity.java Zobrazit soubor

@@ -25,7 +25,6 @@ import java.util.List;
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;
@@ -127,86 +126,4 @@ public class Activity implements Serializable, Comparable<Activity> {
// 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;
}
}
}

+ 166
- 0
src/com/gitblit/models/PushLogEntry.java Zobrazit soubor

@@ -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);
}
}

+ 104
- 0
src/com/gitblit/models/RepositoryCommit.java Zobrazit soubor

@@ -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;
}
}

+ 1
- 1
src/com/gitblit/utils/ActivityUtils.java Zobrazit soubor

@@ -36,9 +36,9 @@ import org.eclipse.jgit.revwalk.RevCommit;
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;

+ 11
- 5
src/com/gitblit/utils/IssueUtils.java Zobrazit soubor

@@ -76,9 +76,9 @@ public class IssueUtils {
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 @@ public class IssueUtils {
* @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 class IssueUtils {
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 @@ public class IssueUtils {
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)) {

+ 14
- 0
src/com/gitblit/utils/JGitUtils.java Zobrazit soubor

@@ -1457,6 +1457,20 @@ public class JGitUtils {
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

+ 344
- 0
src/com/gitblit/utils/PushLogUtils.java Zobrazit soubor

@@ -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;
}
}

+ 1
- 1
src/com/gitblit/wicket/panels/ActivityPanel.java Zobrazit soubor

@@ -27,7 +27,7 @@ import com.gitblit.Constants;
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;

+ 6
- 0
src/com/gitblit/wicket/panels/RefsPanel.java Zobrazit soubor

@@ -129,8 +129,14 @@ public class RefsPanel extends Panel {
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,

+ 15
- 0
tests/com/gitblit/tests/GitServletTest.java Zobrazit soubor

@@ -7,9 +7,11 @@ import static org.junit.Assert.assertTrue;
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.ResetCommand.ResetType;
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.AccessRestrictionType;
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 @@ public class GitServletTest {
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);
}
}

+ 37
- 0
tests/com/gitblit/tests/PushLogTest.java Zobrazit soubor

@@ -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);
}
}

Načítá se…
Zrušit
Uložit