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