private static final Logger LOG = Loggers.get(GitBlameCommand.class);
private static final Pattern EMAIL_PATTERN = Pattern.compile("<(.*?)>");
private static final String COMMITTER_TIME = "committer-time ";
- private static final String COMMITTER_MAIL = "committer-mail ";
+ private static final String AUTHOR_MAIL = "author-mail ";
private static final String MINIMUM_REQUIRED_GIT_VERSION = "2.24.0";
private static final String DEFAULT_GIT_COMMAND = "git";
private final List<BlameLine> blameLines = new LinkedList<>();
private String sha1 = null;
private String committerTime = null;
- private String committerMail = null;
+ private String authorMail = null;
public List<BlameLine> getBlameLines() {
return blameLines;
saveEntry();
} else if (line.startsWith(COMMITTER_TIME)) {
committerTime = line.substring(COMMITTER_TIME.length());
- } else if (line.startsWith(COMMITTER_MAIL)) {
+ } else if (line.startsWith(AUTHOR_MAIL)) {
Matcher matcher = EMAIL_PATTERN.matcher(line);
- if (!matcher.find(COMMITTER_MAIL.length()) || matcher.groupCount() != 1) {
- throw new IllegalStateException("Couldn't parse committer email from: " + line);
+ if (matcher.find(AUTHOR_MAIL.length())) {
+ authorMail = matcher.group(1);
}
- committerMail = matcher.group(1);
- if (committerMail.equals("not.committed.yet")) {
+ if (authorMail.equals("not.committed.yet")) {
throw new UncommittedLineException();
}
}
}
private void saveEntry() {
- checkState(committerMail != null, "Did not find a committer email for an entry");
+ checkState(authorMail != null, "Did not find an author email for an entry");
checkState(committerTime != null, "Did not find a committer time for an entry");
checkState(sha1 != null, "Did not find a commit sha1 for an entry");
try {
blameLines.add(new BlameLine()
.revision(sha1)
- .author(committerMail)
+ .author(authorMail)
.date(Date.from(Instant.ofEpochSecond(Long.parseLong(committerTime)))));
} catch (NumberFormatException e) {
throw new IllegalStateException("Invalid committer time found: " + committerTime);
}
- committerMail = null;
+ authorMail = null;
sha1 = null;
committerTime = null;
}
assertThat(blame).isEqualTo(expectedBlame);
}
+ @Test
+ public void blame_different_author_and_committer() throws Exception {
+ File projectDir = createNewTempFolder();
+ javaUnzip("dummy-git-different-committer.zip", projectDir);
+ File baseDir = new File(projectDir, "dummy-git");
+
+ List<BlameLine> blame = blameCommand.blame(baseDir.toPath(), DUMMY_JAVA);
+
+ Date revisionDate1 = DateUtils.parseDateTime("2012-07-17T16:12:48+0200");
+ String revision1 = "6b3aab35a3ea32c1636fee56f996e677653c48ea";
+ String author1 = "david@gageot.net";
+
+ // second commit, which has a commit date different than the author date
+ Date revisionDate2 = DateUtils.parseDateTime("2022-10-11T14:14:26+0200");
+ String revision2 = "7609f824d5ff7018bebf107cdbe4edcc901b574f";
+ String author2 = "duarte.meneses@sonarsource.com";
+
+ List<BlameLine> expectedBlame = new LinkedList<>();
+ for (int i = 0; i < 25; i++) {
+ expectedBlame.add(new BlameLine().revision(revision1).date(revisionDate1).author(author1));
+ }
+ for (int i = 0; i < 3; i++) {
+ expectedBlame.add(new BlameLine().revision(revision2).date(revisionDate2).author(author2));
+ }
+ for (int i = 0; i < 1; i++) {
+ expectedBlame.add(new BlameLine().revision(revision1).date(revisionDate1).author(author1));
+ }
+
+ assertThat(blame).isEqualTo(expectedBlame);
+ }
+
@Test
public void git_blame_uses_safe_local_repository() throws Exception {
File projectDir = createNewTempFolder();