Search in sources :

Example 6 with PathChangeModel

use of com.gitblit.models.PathModel.PathChangeModel in project gitblit by gitblit.

the class JGitUtils method getFilesInRange.

/**
	 * Returns the list of files changed in a specified commit. If the
	 * repository does not exist or is empty, an empty list is returned.
	 *
	 * @param repository
	 * @param startCommit
	 *            earliest commit
	 * @param endCommit
	 *            most recent commit. if null, HEAD is assumed.
	 * @return list of files changed in a commit range
	 */
public static List<PathChangeModel> getFilesInRange(Repository repository, RevCommit startCommit, RevCommit endCommit) {
    List<PathChangeModel> list = new ArrayList<PathChangeModel>();
    if (!hasCommits(repository)) {
        return list;
    }
    try {
        DiffFormatter df = new DiffFormatter(null);
        df.setRepository(repository);
        df.setDiffComparator(RawTextComparator.DEFAULT);
        df.setDetectRenames(true);
        List<DiffEntry> diffEntries = df.scan(startCommit.getTree(), endCommit.getTree());
        for (DiffEntry diff : diffEntries) {
            PathChangeModel pcm = PathChangeModel.from(diff, endCommit.getName(), repository);
            list.add(pcm);
        }
        Collections.sort(list);
    } catch (Throwable t) {
        error(t, repository, "{0} failed to determine files in range {1}..{2}!", startCommit, endCommit);
    }
    return list;
}
Also used : PathChangeModel(com.gitblit.models.PathModel.PathChangeModel) ArrayList(java.util.ArrayList) DiffFormatter(org.eclipse.jgit.diff.DiffFormatter) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 7 with PathChangeModel

use of com.gitblit.models.PathModel.PathChangeModel in project gitblit by gitblit.

the class JGitUtils method getFilesInCommit.

/**
	 * Returns the list of files changed in a specified commit. If the
	 * repository does not exist or is empty, an empty list is returned.
	 *
	 * @param repository
	 * @param commit
	 *            if null, HEAD is assumed.
	 * @param calculateDiffStat
	 *            if true, each PathChangeModel will have insertions/deletions
	 * @return list of files changed in a commit
	 */
public static List<PathChangeModel> getFilesInCommit(Repository repository, RevCommit commit, boolean calculateDiffStat) {
    List<PathChangeModel> list = new ArrayList<PathChangeModel>();
    if (!hasCommits(repository)) {
        return list;
    }
    RevWalk rw = new RevWalk(repository);
    try {
        if (commit == null) {
            ObjectId object = getDefaultBranch(repository);
            commit = rw.parseCommit(object);
        }
        if (commit.getParentCount() == 0) {
            TreeWalk tw = new TreeWalk(repository);
            tw.reset();
            tw.setRecursive(true);
            tw.addTree(commit.getTree());
            while (tw.next()) {
                long size = 0;
                FilestoreModel filestoreItem = null;
                ObjectId objectId = tw.getObjectId(0);
                try {
                    if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) {
                        size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB);
                        if (isPossibleFilestoreItem(size)) {
                            filestoreItem = getFilestoreItem(tw.getObjectReader().open(objectId));
                        }
                    }
                } catch (Throwable t) {
                    error(t, null, "failed to retrieve blob size for " + tw.getPathString());
                }
                list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), filestoreItem, size, tw.getRawMode(0), objectId.getName(), commit.getId().getName(), ChangeType.ADD));
            }
            tw.close();
        } else {
            RevCommit parent = rw.parseCommit(commit.getParent(0).getId());
            DiffStatFormatter df = new DiffStatFormatter(commit.getName(), repository);
            df.setRepository(repository);
            df.setDiffComparator(RawTextComparator.DEFAULT);
            df.setDetectRenames(true);
            List<DiffEntry> diffs = df.scan(parent.getTree(), commit.getTree());
            for (DiffEntry diff : diffs) {
                // create the path change model
                PathChangeModel pcm = PathChangeModel.from(diff, commit.getName(), repository);
                if (calculateDiffStat) {
                    // update file diffstats
                    df.format(diff);
                    PathChangeModel pathStat = df.getDiffStat().getPath(pcm.path);
                    if (pathStat != null) {
                        pcm.insertions = pathStat.insertions;
                        pcm.deletions = pathStat.deletions;
                    }
                }
                list.add(pcm);
            }
        }
    } catch (Throwable t) {
        error(t, repository, "{0} failed to determine files in commit!");
    } finally {
        rw.dispose();
    }
    return list;
}
Also used : PathChangeModel(com.gitblit.models.PathModel.PathChangeModel) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) FilestoreModel(com.gitblit.models.FilestoreModel) ArrayList(java.util.ArrayList) RevWalk(org.eclipse.jgit.revwalk.RevWalk) TreeWalk(org.eclipse.jgit.treewalk.TreeWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit) DiffEntry(org.eclipse.jgit.diff.DiffEntry)

Example 8 with PathChangeModel

use of com.gitblit.models.PathModel.PathChangeModel in project gitblit by gitblit.

the class RefLogUtils method getRefLog.

/**
	 * Returns the list of reflog entries as they were recorded by Gitblit.
	 * Each RefLogEntry may represent multiple ref updates.
	 *
	 * @param repositoryName
	 * @param repository
	 * @param minimumDate
	 * @param offset
	 * @param maxCount
	 * 			if < 0, all entries are returned.
	 * @return a list of reflog entries
	 */
public static List<RefLogEntry> getRefLog(String repositoryName, Repository repository, Date minimumDate, int offset, int maxCount) {
    List<RefLogEntry> list = new ArrayList<RefLogEntry>();
    RefModel ref = getRefLogBranch(repository);
    if (ref == null) {
        return list;
    }
    if (maxCount == 0) {
        return list;
    }
    Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(repository);
    List<RevCommit> pushes;
    if (minimumDate == null) {
        pushes = JGitUtils.getRevLog(repository, GB_REFLOG, offset, maxCount);
    } else {
        pushes = JGitUtils.getRevLog(repository, GB_REFLOG, minimumDate);
    }
    for (RevCommit push : pushes) {
        if (push.getAuthorIdent().getName().equalsIgnoreCase("gitblit")) {
            // skip gitblit/internal commits
            continue;
        }
        UserModel user = newUserModelFrom(push.getAuthorIdent());
        Date date = push.getAuthorIdent().getWhen();
        RefLogEntry log = new RefLogEntry(repositoryName, date, user);
        // only report HEADS and TAGS for now
        List<PathChangeModel> changedRefs = new ArrayList<PathChangeModel>();
        for (PathChangeModel refChange : JGitUtils.getFilesInCommit(repository, push)) {
            if (refChange.path.startsWith(Constants.R_HEADS) || refChange.path.startsWith(Constants.R_TAGS)) {
                changedRefs.add(refChange);
            }
        }
        if (changedRefs.isEmpty()) {
            // skip empty commits
            continue;
        }
        list.add(log);
        for (PathChangeModel change : changedRefs) {
            switch(change.changeType) {
                case DELETE:
                    log.updateRef(change.path, ReceiveCommand.Type.DELETE);
                    break;
                default:
                    String content = JGitUtils.getStringContent(repository, push.getTree(), change.path);
                    String[] fields = content.split(" ");
                    String oldId = fields[1];
                    String newId = fields[2];
                    log.updateRef(change.path, ReceiveCommand.Type.valueOf(fields[0]), oldId, newId);
                    if (ObjectId.zeroId().getName().equals(newId)) {
                        // ref deletion
                        continue;
                    }
                    try {
                        List<RevCommit> pushedCommits = JGitUtils.getRevLog(repository, oldId, newId);
                        for (RevCommit pushedCommit : pushedCommits) {
                            RepositoryCommit repoCommit = log.addCommit(change.path, pushedCommit);
                            if (repoCommit != null) {
                                repoCommit.setRefs(allRefs.get(pushedCommit.getId()));
                            }
                        }
                    } catch (Exception e) {
                    }
            }
        }
    }
    Collections.sort(list);
    return list;
}
Also used : RefModel(com.gitblit.models.RefModel) ObjectId(org.eclipse.jgit.lib.ObjectId) PathChangeModel(com.gitblit.models.PathModel.PathChangeModel) ArrayList(java.util.ArrayList) RepositoryCommit(com.gitblit.models.RepositoryCommit) RefLogEntry(com.gitblit.models.RefLogEntry) Date(java.util.Date) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) IOException(java.io.IOException) JGitInternalException(org.eclipse.jgit.api.errors.JGitInternalException) UserModel(com.gitblit.models.UserModel) ArrayList(java.util.ArrayList) List(java.util.List) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 9 with PathChangeModel

use of com.gitblit.models.PathModel.PathChangeModel in project gitblit by gitblit.

the class BranchTicketService method onRefsChanged.

/**
	 * Listen for tickets branch changes and (re)index tickets, as appropriate
	 */
@Override
public synchronized void onRefsChanged(RefsChangedEvent event) {
    if (!(event instanceof ReceiveCommandEvent)) {
        return;
    }
    ReceiveCommandEvent branchUpdate = (ReceiveCommandEvent) event;
    RepositoryModel repository = branchUpdate.model;
    ReceiveCommand cmd = branchUpdate.cmd;
    try {
        switch(cmd.getType()) {
            case CREATE:
            case UPDATE_NONFASTFORWARD:
                // reindex everything
                reindex(repository);
                break;
            case UPDATE:
                // incrementally index ticket updates
                resetCaches(repository);
                long start = System.nanoTime();
                log.info("incrementally indexing {} ticket branch due to received ref update", repository.name);
                Repository db = repositoryManager.getRepository(repository.name);
                try {
                    Set<Long> ids = new HashSet<Long>();
                    List<PathChangeModel> paths = JGitUtils.getFilesInRange(db, cmd.getOldId().getName(), cmd.getNewId().getName());
                    for (PathChangeModel path : paths) {
                        String name = path.name.substring(path.name.lastIndexOf('/') + 1);
                        if (!JOURNAL.equals(name)) {
                            continue;
                        }
                        String tid = path.path.split("/")[2];
                        long ticketId = Long.parseLong(tid);
                        if (!ids.contains(ticketId)) {
                            ids.add(ticketId);
                            TicketModel ticket = getTicket(repository, ticketId);
                            log.info(MessageFormat.format("indexing ticket #{0,number,0}: {1}", ticketId, ticket.title));
                            indexer.index(ticket);
                        }
                    }
                    long end = System.nanoTime();
                    log.info("incremental indexing of {0} ticket(s) completed in {1} msecs", ids.size(), TimeUnit.NANOSECONDS.toMillis(end - start));
                } finally {
                    db.close();
                }
                break;
            default:
                log.warn("Unexpected receive type {} in BranchTicketService.onRefsChanged" + cmd.getType());
                break;
        }
    } catch (Exception e) {
        log.error("failed to reindex " + repository.name, e);
    }
}
Also used : ReceiveCommand(org.eclipse.jgit.transport.ReceiveCommand) PathChangeModel(com.gitblit.models.PathModel.PathChangeModel) TicketModel(com.gitblit.models.TicketModel) RepositoryModel(com.gitblit.models.RepositoryModel) ConcurrentRefUpdateException(org.eclipse.jgit.api.errors.ConcurrentRefUpdateException) IOException(java.io.IOException) Repository(org.eclipse.jgit.lib.Repository) ReceiveCommandEvent(com.gitblit.git.ReceiveCommandEvent) AtomicLong(java.util.concurrent.atomic.AtomicLong) HashSet(java.util.HashSet)

Aggregations

PathChangeModel (com.gitblit.models.PathModel.PathChangeModel)9 ArrayList (java.util.ArrayList)7 RevCommit (org.eclipse.jgit.revwalk.RevCommit)6 IOException (java.io.IOException)4 UserModel (com.gitblit.models.UserModel)3 ObjectId (org.eclipse.jgit.lib.ObjectId)3 Repository (org.eclipse.jgit.lib.Repository)3 RefModel (com.gitblit.models.RefModel)2 TicketModel (com.gitblit.models.TicketModel)2 Change (com.gitblit.models.TicketModel.Change)2 Patchset (com.gitblit.models.TicketModel.Patchset)2 Review (com.gitblit.models.TicketModel.Review)2 HashSet (java.util.HashSet)2 ConcurrentRefUpdateException (org.eclipse.jgit.api.errors.ConcurrentRefUpdateException)2 DiffEntry (org.eclipse.jgit.diff.DiffEntry)2 AnyObjectId (org.eclipse.jgit.lib.AnyObjectId)2 RevWalk (org.eclipse.jgit.revwalk.RevWalk)2 ReceiveCommandEvent (com.gitblit.git.ReceiveCommandEvent)1 FilestoreModel (com.gitblit.models.FilestoreModel)1 RefLogEntry (com.gitblit.models.RefLogEntry)1