public static void main(String[] args) throws IOException, GitAPIException { // prepare a new test-repository try (Repository repository = CookbookHelper.openJGitCookbookRepository()) { BlameCommand blamer = new BlameCommand(repository); ObjectId commitID = repository.resolve("HEAD~~"); blamer.setStartCommit(commitID); blamer.setFilePath("README.md"); BlameResult blame = blamer.call(); // read the number of lines from the given revision, this excludes changes from the last two commits due to the "~~" above int lines = countLinesOfFileInCommit(repository, commitID, "README.md"); for (int i = 0; i < lines; i++) { RevCommit commit = blame.getSourceCommit(i); System.out.println("Line: " + i + ": " + commit); } final int currentLines; try (final FileInputStream input = new FileInputStream("README.md")) { currentLines = IOUtils.readLines(input, "UTF-8").size(); } System.out.println("Displayed commits responsible for " + lines + " lines of README.md, current version has " + currentLines + " lines"); } }
/** * Compute the blame data for the parent, we are not interested in the * specific commit but the parent, since we only want to know the last person * that edited this specific part of the code. * * @param entry {@link PatchListEntry} * @param commit Parent {@link RevCommit} * @return Result of blame computation, null if the computation fails */ private BlameResult computeBlame(final PatchListEntry entry, final RevCommit parent) { BlameCommand blameCommand = new BlameCommand(repo); blameCommand.setStartCommit(parent); blameCommand.setFilePath(entry.getNewName()); try { BlameResult blameResult = blameCommand.call(); blameResult.computeAll(); return blameResult; } catch (GitAPIException ex) { log.error("Couldn't execute blame for commit {}", parent.getName(), ex); } catch (IOException err) { log.error("Error while computing blame for commit {}", parent.getName(), err); } return null; }
/** * 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; }
/** * 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; }