Search in sources :

Example 1 with BlameResult

use of org.eclipse.jgit.blame.BlameResult in project maven-scm by apache.

the class JGitBlameCommand method executeBlameCommand.

@Override
public BlameScmResult executeBlameCommand(ScmProviderRepository repo, ScmFileSet workingDirectory, String filename) throws ScmException {
    Git git = null;
    File basedir = workingDirectory.getBasedir();
    try {
        git = JGitUtils.openRepo(basedir);
        BlameResult blameResult = git.blame().setFilePath(filename).call();
        List<BlameLine> lines = new ArrayList<BlameLine>();
        int i = 0;
        while ((i = blameResult.computeNext()) != -1) {
            lines.add(new BlameLine(blameResult.getSourceAuthor(i).getWhen(), blameResult.getSourceCommit(i).getName(), blameResult.getSourceAuthor(i).getName(), blameResult.getSourceCommitter(i).getName()));
        }
        return new BlameScmResult("JGit blame", lines);
    } catch (Exception e) {
        throw new ScmException("JGit blame failure!", e);
    } finally {
        JGitUtils.closeRepo(git);
    }
}
Also used : BlameLine(org.apache.maven.scm.command.blame.BlameLine) ScmException(org.apache.maven.scm.ScmException) Git(org.eclipse.jgit.api.Git) BlameResult(org.eclipse.jgit.blame.BlameResult) BlameScmResult(org.apache.maven.scm.command.blame.BlameScmResult) ArrayList(java.util.ArrayList) File(java.io.File) ScmException(org.apache.maven.scm.ScmException)

Example 2 with BlameResult

use of org.eclipse.jgit.blame.BlameResult in project egit by eclipse.

the class BlameOperation method execute.

@Override
public void execute(IProgressMonitor monitor) throws CoreException {
    SubMonitor progress = SubMonitor.convert(monitor, 3);
    final RevisionInformation info = new RevisionInformation();
    final BlameCommand command = new BlameCommand(repository).setFollowFileRenames(true).setFilePath(path);
    if (startCommit != null)
        command.setStartCommit(startCommit);
    else {
        try {
            command.setStartCommit(repository.resolve(Constants.HEAD));
        } catch (IOException e) {
            Activator.error("Error resolving HEAD for showing annotations in repository: " + repository, // $NON-NLS-1$
            e);
            return;
        }
    }
    if (Activator.getDefault().getPreferenceStore().getBoolean(UIPreferences.BLAME_IGNORE_WHITESPACE))
        command.setTextComparator(RawTextComparator.WS_IGNORE_ALL);
    BlameResult result;
    try {
        result = command.call();
    } catch (Exception e1) {
        Activator.error(e1.getMessage(), e1);
        return;
    }
    progress.worked(1);
    if (result == null)
        return;
    Map<RevCommit, BlameRevision> revisions = new HashMap<>();
    int lineCount = result.getResultContents().size();
    BlameRevision previous = null;
    for (int i = 0; i < lineCount; i++) {
        RevCommit commit = result.getSourceCommit(i);
        String sourcePath = result.getSourcePath(i);
        if (commit == null) {
            // Unregister the current revision
            if (previous != null) {
                previous.register();
                previous = null;
            }
            continue;
        }
        BlameRevision revision = revisions.get(commit);
        if (revision == null) {
            revision = new BlameRevision();
            revision.setRepository(repository);
            revision.setCommit(commit);
            revision.setSourcePath(sourcePath);
            revisions.put(commit, revision);
            info.addRevision(revision);
        }
        revision.addSourceLine(i, result.getSourceLine(i));
        if (previous != null)
            if (previous == revision)
                previous.addLine();
            else {
                previous.register();
                previous = revision.reset(i);
            }
        else
            previous = revision.reset(i);
    }
    if (previous != null)
        previous.register();
    progress.worked(1);
    if (shell.isDisposed()) {
        return;
    }
    if (fileRevision != null) {
        storage = fileRevision.getStorage(progress.newChild(1));
    } else {
        progress.worked(1);
    }
    shell.getDisplay().asyncExec(new Runnable() {

        @Override
        public void run() {
            openEditor(info);
        }
    });
}
Also used : BlameResult(org.eclipse.jgit.blame.BlameResult) HashMap(java.util.HashMap) SubMonitor(org.eclipse.core.runtime.SubMonitor) BlameCommand(org.eclipse.jgit.api.BlameCommand) IOException(java.io.IOException) CoreException(org.eclipse.core.runtime.CoreException) BadLocationException(org.eclipse.jface.text.BadLocationException) IOException(java.io.IOException) RevisionInformation(org.eclipse.jface.text.revisions.RevisionInformation) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 3 with BlameResult

use of org.eclipse.jgit.blame.BlameResult in project gitblit by gitblit.

the class DiffUtils method blame.

/**
 * Returns the list of lines in the specified source file annotated with the
 * source commit metadata.
 *
 * @param repository
 * @param blobPath
 * @param objectId
 * @return list of annotated lines
 */
public static List<AnnotatedLine> blame(Repository repository, String blobPath, String objectId) {
    List<AnnotatedLine> lines = new ArrayList<AnnotatedLine>();
    try {
        ObjectId object;
        if (StringUtils.isEmpty(objectId)) {
            object = JGitUtils.getDefaultBranch(repository);
        } else {
            object = repository.resolve(objectId);
        }
        BlameCommand blameCommand = new BlameCommand(repository);
        blameCommand.setFilePath(blobPath);
        blameCommand.setStartCommit(object);
        BlameResult blameResult = blameCommand.call();
        RawText rawText = blameResult.getResultContents();
        int length = rawText.size();
        for (int i = 0; i < length; i++) {
            RevCommit commit = blameResult.getSourceCommit(i);
            AnnotatedLine line = new AnnotatedLine(commit, i + 1, rawText.getString(i));
            lines.add(line);
        }
    } catch (Throwable t) {
        LOGGER.error(MessageFormat.format("failed to generate blame for {0} {1}!", blobPath, objectId), t);
    }
    return lines;
}
Also used : AnnotatedLine(com.gitblit.models.AnnotatedLine) BlameResult(org.eclipse.jgit.blame.BlameResult) ObjectId(org.eclipse.jgit.lib.ObjectId) ArrayList(java.util.ArrayList) BlameCommand(org.eclipse.jgit.api.BlameCommand) RawText(org.eclipse.jgit.diff.RawText) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 4 with BlameResult

use of org.eclipse.jgit.blame.BlameResult in project searchcode-server by boyter.

the class IndexGitRepoJob method getBlameInfo.

/**
 * Uses the inbuilt git
 * TODO lots of hairy bits in here need tests to capture issues
 */
public List<CodeOwner> getBlameInfo(int codeLinesSize, String repoName, String repoLocations, String fileName) {
    List<CodeOwner> codeOwners = new ArrayList<>(codeLinesSize);
    try {
        // The / part is required due to centos bug for version 1.1.1
        // This appears to be correct
        String repoLoc = repoLocations + "/" + repoName + "/.git";
        Repository localRepository = new FileRepository(new File(repoLoc));
        BlameCommand blamer = new BlameCommand(localRepository);
        ObjectId commitID = localRepository.resolve("HEAD");
        if (commitID == null) {
            this.logger.severe(String.format("caca9ca8::getblameinfo commitId is null for repository %s filename %s", repoLoc, fileName));
            return codeOwners;
        }
        BlameResult blame;
        // Somewhere in here appears to be wrong...
        blamer.setStartCommit(commitID);
        blamer.setFilePath(fileName);
        blame = blamer.call();
        // Hail mary attempt to solve issue on CentOS Attempt to set at all costs
        if (blame == null) {
            // This one appears to solve the issue so don't remove it
            String[] split = fileName.split("/");
            blamer.setStartCommit(commitID);
            if (split.length != 1) {
                blamer.setFilePath(String.join("/", Arrays.asList(split).subList(1, split.length)));
            }
            blame = blamer.call();
        }
        if (blame == null) {
            String[] split = fileName.split("/");
            blamer.setStartCommit(commitID);
            if (split.length != 1) {
                blamer.setFilePath("/" + String.join("/", Arrays.asList(split).subList(1, split.length)));
            }
            blame = blamer.call();
        }
        if (blame == null) {
            this.logger.info(String.format("273e0a9e::getblameinfo is null for repository %s filename %s", repoLoc, fileName));
        }
        if (blame != null) {
            // Get all the owners their number of commits and most recent commit
            HashMap<String, CodeOwner> owners = new HashMap<>();
            RevCommit commit;
            PersonIdent authorIdent;
            try {
                for (int i = 0; i < codeLinesSize; i++) {
                    commit = blame.getSourceCommit(i);
                    authorIdent = commit.getAuthorIdent();
                    if (owners.containsKey(authorIdent.getName())) {
                        CodeOwner codeOwner = owners.get(authorIdent.getName());
                        codeOwner.incrementLines();
                        int timestamp = codeOwner.getMostRecentUnixCommitTimestamp();
                        if (commit.getCommitTime() > timestamp) {
                            codeOwner.setMostRecentUnixCommitTimestamp(commit.getCommitTime());
                        }
                        owners.put(authorIdent.getName(), codeOwner);
                    } else {
                        owners.put(authorIdent.getName(), new CodeOwner(authorIdent.getName(), 1, commit.getCommitTime()));
                    }
                }
            } catch (IndexOutOfBoundsException ex) {
                // blame.getSourceCommit(i) will throw this exception and there is no way I can see to correctly
                // identify when it will occur. Its not something that is severe so we log it under info
                this.logger.info(String.format("4cf371a5::error in class %s exception %s for repository %s index out of bounds, this can safely be ignored but is something to fix in the future", ex.getClass(), ex.getMessage(), repoName));
            }
            codeOwners = new ArrayList<>(owners.values());
        }
    } catch (IOException ex) {
        this.logger.severe(String.format("85cd8d0c::error in class %s exception %s for repository %s", ex.getClass(), ex.getMessage(), repoName));
    } catch (GitAPIException ex) {
        this.logger.severe(String.format("91029067::error in class %s exception %s for repository %s", ex.getClass(), ex.getMessage(), repoName));
    } catch (IllegalArgumentException ex) {
        this.logger.severe(String.format("8b6da512::error in class %s exception %s for repository %s", ex.getClass(), ex.getMessage(), repoName));
    }
    return codeOwners;
}
Also used : FileRepository(org.eclipse.jgit.internal.storage.file.FileRepository) CodeOwner(com.searchcode.app.dto.CodeOwner) BlameResult(org.eclipse.jgit.blame.BlameResult) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) BlameCommand(org.eclipse.jgit.api.BlameCommand) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) FileRepository(org.eclipse.jgit.internal.storage.file.FileRepository) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 5 with BlameResult

use of org.eclipse.jgit.blame.BlameResult in project sonarqube by SonarSource.

the class JGitBlameCommand method blame.

private void blame(BlameOutput output, Git git, File gitBaseDir, InputFile inputFile) {
    String filename = pathResolver.relativePath(gitBaseDir, inputFile.file());
    LOG.debug("Blame file {}", filename);
    BlameResult blameResult;
    try {
        blameResult = git.blame().setTextComparator(RawTextComparator.WS_IGNORE_ALL).setFilePath(filename).call();
    } catch (Exception e) {
        throw new IllegalStateException("Unable to blame file " + inputFile.relativePath(), e);
    }
    List<BlameLine> lines = new ArrayList<>();
    if (blameResult == null) {
        LOG.debug("Unable to blame file {}. It is probably a symlink.", inputFile.relativePath());
        return;
    }
    for (int i = 0; i < blameResult.getResultContents().size(); i++) {
        if (blameResult.getSourceAuthor(i) == null || blameResult.getSourceCommit(i) == null) {
            LOG.debug("Unable to blame file {}. No blame info at line {}. Is file committed? [Author: {} Source commit: {}]", inputFile.relativePath(), i + 1, blameResult.getSourceAuthor(i), blameResult.getSourceCommit(i));
            return;
        }
        lines.add(new BlameLine().date(blameResult.getSourceCommitter(i).getWhen()).revision(blameResult.getSourceCommit(i).getName()).author(blameResult.getSourceAuthor(i).getEmailAddress()));
    }
    if (lines.size() == inputFile.lines() - 1) {
        // SONARPLUGINS-3097 Git do not report blame on last empty line
        lines.add(lines.get(lines.size() - 1));
    }
    output.blameResult(inputFile, lines);
}
Also used : BlameLine(org.sonar.api.batch.scm.BlameLine) BlameResult(org.eclipse.jgit.blame.BlameResult) ArrayList(java.util.ArrayList)

Aggregations

BlameResult (org.eclipse.jgit.blame.BlameResult)5 ArrayList (java.util.ArrayList)4 BlameCommand (org.eclipse.jgit.api.BlameCommand)3 RevCommit (org.eclipse.jgit.revwalk.RevCommit)3 HashMap (java.util.HashMap)2 AnnotatedLine (com.gitblit.models.AnnotatedLine)1 CodeOwner (com.searchcode.app.dto.CodeOwner)1 File (java.io.File)1 IOException (java.io.IOException)1 ScmException (org.apache.maven.scm.ScmException)1 BlameLine (org.apache.maven.scm.command.blame.BlameLine)1 BlameScmResult (org.apache.maven.scm.command.blame.BlameScmResult)1 CoreException (org.eclipse.core.runtime.CoreException)1 SubMonitor (org.eclipse.core.runtime.SubMonitor)1 BadLocationException (org.eclipse.jface.text.BadLocationException)1 RevisionInformation (org.eclipse.jface.text.revisions.RevisionInformation)1 Git (org.eclipse.jgit.api.Git)1 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)1 RawText (org.eclipse.jgit.diff.RawText)1 FileRepository (org.eclipse.jgit.internal.storage.file.FileRepository)1