Search in sources :

Example 11 with ObjectId

use of org.eclipse.jgit.lib.ObjectId in project gitblit by gitblit.

the class CommitCache method getCommits.

/**
	 * Get all commits for the specified repository:branch since a specific date.
	 * These commits may be retrieved from the cache if the sinceDate is after
	 * the cacheCutoffDate.
	 *
	 * @param repositoryName
	 * @param repository
	 * @param branch
	 * @param sinceDate
	 * @return a list of commits
	 */
public List<RepositoryCommit> getCommits(String repositoryName, Repository repository, String branch, Date sinceDate) {
    long start = System.nanoTime();
    Date cacheCutoffDate = getCutoffDate();
    List<RepositoryCommit> list;
    if (cacheDays > 0 && (sinceDate.getTime() >= cacheCutoffDate.getTime())) {
        // request fits within the cache window
        String repoKey = repositoryName.toLowerCase();
        String branchKey = branch.toLowerCase();
        RevCommit tip = JGitUtils.getCommit(repository, branch);
        Date tipDate = JGitUtils.getCommitDate(tip);
        ObjectCache<List<RepositoryCommit>> repoCache;
        synchronized (cache) {
            repoCache = cache.get(repoKey);
            if (repoCache == null) {
                repoCache = new ObjectCache<>();
                cache.put(repoKey, repoCache);
            }
        }
        synchronized (repoCache) {
            List<RepositoryCommit> commits;
            if (!repoCache.hasCurrent(branchKey, tipDate)) {
                commits = repoCache.getObject(branchKey);
                if (ArrayUtils.isEmpty(commits)) {
                    // we don't have any cached commits for this branch, reload
                    commits = get(repositoryName, repository, branch, cacheCutoffDate);
                    repoCache.updateObject(branchKey, tipDate, commits);
                    logger.debug(MessageFormat.format("parsed {0} commits from {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", commits.size(), repositoryName, branch, cacheCutoffDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
                } else {
                    // incrementally update cache since the last cached commit
                    ObjectId sinceCommit = commits.get(0).getId();
                    List<RepositoryCommit> incremental = get(repositoryName, repository, branch, sinceCommit);
                    logger.info(MessageFormat.format("incrementally added {0} commits to cache for {1}:{2} in {3} msecs", incremental.size(), repositoryName, branch, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
                    incremental.addAll(commits);
                    repoCache.updateObject(branchKey, tipDate, incremental);
                    commits = incremental;
                }
            } else {
                // cache is current
                commits = repoCache.getObject(branchKey);
                // evict older commits outside the cache window
                commits = reduce(commits, cacheCutoffDate);
                // update cache
                repoCache.updateObject(branchKey, tipDate, commits);
            }
            if (sinceDate.equals(cacheCutoffDate)) {
                // Mustn't hand out the cached list; that's not thread-safe
                list = new ArrayList<>(commits);
            } else {
                // reduce the commits to those since the specified date
                list = reduce(commits, sinceDate);
            }
        }
        logger.debug(MessageFormat.format("retrieved {0} commits from cache of {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", list.size(), repositoryName, branch, sinceDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
    } else {
        // not caching or request outside cache window
        list = get(repositoryName, repository, branch, sinceDate);
        logger.debug(MessageFormat.format("parsed {0} commits from {1}:{2} since {3,date,yyyy-MM-dd} in {4} msecs", list.size(), repositoryName, branch, sinceDate, TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start)));
    }
    return list;
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) List(java.util.List) RepositoryCommit(com.gitblit.models.RepositoryCommit) Date(java.util.Date) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 12 with ObjectId

use of org.eclipse.jgit.lib.ObjectId in project gitblit by gitblit.

the class MetricUtils method getAuthorMetrics.

/**
	 * Returns a list of author metrics for the specified repository.
	 *
	 * @param repository
	 * @param objectId
	 *            if null or empty, HEAD is assumed.
	 * @param byEmailAddress
	 *            group metrics by author email address otherwise by author name
	 * @return list of metrics
	 */
public static List<Metric> getAuthorMetrics(Repository repository, String objectId, boolean byEmailAddress) {
    final Map<String, Metric> metricMap = new HashMap<String, Metric>();
    if (JGitUtils.hasCommits(repository)) {
        try {
            RevWalk walk = new RevWalk(repository);
            // resolve branch
            ObjectId branchObject;
            if (StringUtils.isEmpty(objectId)) {
                branchObject = JGitUtils.getDefaultBranch(repository);
            } else {
                branchObject = repository.resolve(objectId);
            }
            RevCommit lastCommit = walk.parseCommit(branchObject);
            walk.markStart(lastCommit);
            Iterable<RevCommit> revlog = walk;
            for (RevCommit rev : revlog) {
                String p;
                if (byEmailAddress) {
                    p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
                    if (StringUtils.isEmpty(p)) {
                        p = rev.getAuthorIdent().getName().toLowerCase();
                    }
                } else {
                    p = rev.getAuthorIdent().getName().toLowerCase();
                    if (StringUtils.isEmpty(p)) {
                        p = rev.getAuthorIdent().getEmailAddress().toLowerCase();
                    }
                }
                p = p.replace('\n', ' ').replace('\r', ' ').trim();
                if (!metricMap.containsKey(p)) {
                    metricMap.put(p, new Metric(p));
                }
                Metric m = metricMap.get(p);
                m.count++;
            }
        } catch (Throwable t) {
            error(t, repository, "{0} failed to mine log history for author metrics of {1}", objectId);
        }
    }
    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));
    }
    return metrics;
}
Also used : HashMap(java.util.HashMap) ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) Metric(com.gitblit.models.Metric) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 13 with ObjectId

use of org.eclipse.jgit.lib.ObjectId in project gitblit by gitblit.

the class RefLogUtils method updateRefLog.

/**
	 * Updates the reflog with the received commands.
	 *
	 * @param user
	 * @param repository
	 * @param commands
	 * @return true, if the update was successful
	 */
public static boolean updateRefLog(UserModel user, Repository repository, Collection<ReceiveCommand> commands) {
    // only track branches and tags
    List<ReceiveCommand> filteredCommands = new ArrayList<ReceiveCommand>();
    for (ReceiveCommand cmd : commands) {
        if (!cmd.getRefName().startsWith(Constants.R_HEADS) && !cmd.getRefName().startsWith(Constants.R_TAGS)) {
            continue;
        }
        filteredCommands.add(cmd);
    }
    if (filteredCommands.isEmpty()) {
        // nothing to log
        return true;
    }
    RefModel reflogBranch = getRefLogBranch(repository);
    if (reflogBranch == null) {
        JGitUtils.createOrphanBranch(repository, GB_REFLOG, null);
    }
    boolean success = false;
    String message = "push";
    try {
        ObjectId headId = repository.resolve(GB_REFLOG + "^{commit}");
        ObjectInserter odi = repository.newObjectInserter();
        try {
            // Create the in-memory index of the reflog log entry
            DirCache index = createIndex(repository, headId, commands);
            ObjectId indexTreeId = index.writeTree(odi);
            PersonIdent ident;
            if (UserModel.ANONYMOUS.equals(user)) {
                // anonymous push
                ident = new PersonIdent(user.username + "/" + user.username, user.username);
            } else {
                // construct real pushing account
                ident = new PersonIdent(MessageFormat.format("{0}/{1}", user.getDisplayName(), user.username), user.emailAddress == null ? user.username : user.emailAddress);
            }
            // Create a commit object
            CommitBuilder commit = new CommitBuilder();
            commit.setAuthor(ident);
            commit.setCommitter(ident);
            commit.setEncoding(Constants.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_REFLOG);
                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_REFLOG, commitId.toString(), rc));
                }
            } finally {
                revWalk.close();
            }
        } finally {
            odi.close();
        }
    } catch (Throwable t) {
        error(t, repository, "Failed to commit reflog entry to {0}");
    }
    return success;
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) RefModel(com.gitblit.models.RefModel) ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Result(org.eclipse.jgit.lib.RefUpdate.Result) DirCache(org.eclipse.jgit.dircache.DirCache) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 14 with ObjectId

use of org.eclipse.jgit.lib.ObjectId in project gitblit by gitblit.

the class JGitUtils method createOrphanBranch.

/**
	 * Create an orphaned branch in a repository.
	 *
	 * @param repository
	 * @param branchName
	 * @param author
	 *            if unspecified, Gitblit will be the author of this new branch
	 * @return true if successful
	 */
public static boolean createOrphanBranch(Repository repository, String branchName, PersonIdent author) {
    boolean success = false;
    String message = "Created branch " + branchName;
    if (author == null) {
        author = new PersonIdent("Gitblit", "gitblit@localhost");
    }
    try {
        ObjectInserter odi = repository.newObjectInserter();
        try {
            // Create a blob object to insert into a tree
            ObjectId blobId = odi.insert(Constants.OBJ_BLOB, message.getBytes(Constants.CHARACTER_ENCODING));
            // Create a tree object to reference from a commit
            TreeFormatter tree = new TreeFormatter();
            tree.append(".branch", FileMode.REGULAR_FILE, blobId);
            ObjectId treeId = odi.insert(tree);
            // Create a commit object
            CommitBuilder commit = new CommitBuilder();
            commit.setAuthor(author);
            commit.setCommitter(author);
            commit.setEncoding(Constants.CHARACTER_ENCODING);
            commit.setMessage(message);
            commit.setTreeId(treeId);
            // Insert the commit into the repository
            ObjectId commitId = odi.insert(commit);
            odi.flush();
            RevWalk revWalk = new RevWalk(repository);
            try {
                RevCommit revCommit = revWalk.parseCommit(commitId);
                if (!branchName.startsWith("refs/")) {
                    branchName = "refs/heads/" + branchName;
                }
                RefUpdate ru = repository.updateRef(branchName);
                ru.setNewObjectId(commitId);
                ru.setRefLogMessage("commit: " + revCommit.getShortMessage(), false);
                Result rc = ru.forceUpdate();
                switch(rc) {
                    case NEW:
                    case FORCED:
                    case FAST_FORWARD:
                        success = true;
                        break;
                    default:
                        success = false;
                }
            } finally {
                revWalk.close();
            }
        } finally {
            odi.close();
        }
    } catch (Throwable t) {
        error(t, repository, "Failed to create orphan branch {1} in repository {0}", branchName);
    }
    return success;
}
Also used : ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) TreeFormatter(org.eclipse.jgit.lib.TreeFormatter) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate) FetchResult(org.eclipse.jgit.transport.FetchResult) Result(org.eclipse.jgit.lib.RefUpdate.Result)

Example 15 with ObjectId

use of org.eclipse.jgit.lib.ObjectId in project gitblit by gitblit.

the class JGitUtils method getCommit.

/**
	 * Returns the specified commit from the repository. If the repository does
	 * not exist or is empty, null is returned.
	 *
	 * @param repository
	 * @param objectId
	 *            if unspecified, HEAD is assumed.
	 * @return RevCommit
	 */
public static RevCommit getCommit(Repository repository, String objectId) {
    if (!hasCommits(repository)) {
        return null;
    }
    RevCommit commit = null;
    RevWalk walk = null;
    try {
        // resolve object id
        ObjectId branchObject;
        if (StringUtils.isEmpty(objectId) || "HEAD".equalsIgnoreCase(objectId)) {
            branchObject = getDefaultBranch(repository);
        } else {
            branchObject = repository.resolve(objectId);
        }
        if (branchObject == null) {
            return null;
        }
        walk = new RevWalk(repository);
        RevCommit rev = walk.parseCommit(branchObject);
        commit = rev;
    } catch (Throwable t) {
        error(t, repository, "{0} failed to get commit {1}", objectId);
    } finally {
        if (walk != null) {
            walk.dispose();
        }
    }
    return commit;
}
Also used : AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Aggregations

ObjectId (org.eclipse.jgit.lib.ObjectId)357 Test (org.junit.Test)128 RevCommit (org.eclipse.jgit.revwalk.RevCommit)125 RevWalk (org.eclipse.jgit.revwalk.RevWalk)86 IOException (java.io.IOException)63 Repository (org.eclipse.jgit.lib.Repository)63 Change (com.google.gerrit.reviewdb.client.Change)41 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)40 ArrayList (java.util.ArrayList)36 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)34 PatchSet (com.google.gerrit.reviewdb.client.PatchSet)34 Ref (org.eclipse.jgit.lib.Ref)34 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)33 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)26 AnyObjectId (org.eclipse.jgit.lib.AnyObjectId)24 RefUpdate (org.eclipse.jgit.lib.RefUpdate)23 NoteMap (org.eclipse.jgit.notes.NoteMap)22 Map (java.util.Map)21 OrmException (com.google.gwtorm.server.OrmException)20 ObjectReader (org.eclipse.jgit.lib.ObjectReader)20