]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-17353 native git blame reads author instead of committer
authorSteve Marion <steve.marion@sonarsource.com>
Tue, 11 Oct 2022 12:22:10 +0000 (14:22 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 12 Oct 2022 20:03:43 +0000 (20:03 +0000)
sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitBlameCommand.java
sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitBlameCommandTest.java
sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-different-committer.zip [new file with mode: 0644]

index 777dd28c0f53a01031d08992fb728700b21573c4..89e67f26b18663349713001493c98eb9dd31d53f 100644 (file)
@@ -48,7 +48,7 @@ public class GitBlameCommand {
   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";
@@ -141,7 +141,7 @@ public class GitBlameCommand {
     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;
@@ -154,31 +154,30 @@ public class GitBlameCommand {
         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;
     }
index 56402740d9cb09b052b2572e29cab9fcabf0a7c8..734edac0262b6354bae057081747b8da75b0fe9a 100644 (file)
@@ -118,6 +118,37 @@ public class GitBlameCommandTest {
     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();
diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-different-committer.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-different-committer.zip
new file mode 100644 (file)
index 0000000..a3cd5a9
Binary files /dev/null and b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-different-committer.zip differ