From d8a3797bd65b1b04f4ccfa9b7a0fc1c59dd0d6eb Mon Sep 17 00:00:00 2001 From: =?utf8?q?L=C3=A9o=20Geoffroy?= <99647462+leo-geoffroy-sonarsource@users.noreply.github.com> Date: Tue, 14 Mar 2023 16:22:08 +0100 Subject: [PATCH] SONAR-18408 Integrate git-files-blame algorithm to scanner-engine Co-authored-by: lukasz-jarocki-sonarsource Co-authored-by: leo-geoffroy-sonarsource Co-authored-by: benjamin-campomenosi-sonarsource Co-authored-by: Duarte Meneses --- build.gradle | 1 + sonar-scanner-engine/build.gradle | 3 +- .../sonar/scm/git/CompositeBlameCommand.java | 103 +++++++++- .../java/org/sonar/scm/git/GitScmSupport.java | 4 +- ...ommand.java => NativeGitBlameCommand.java} | 8 +- .../sonar/scm/git/strategy/BlameStrategy.java | 25 +++ .../git/strategy/DefaultBlameStrategy.java | 80 ++++++++ .../scm/git/CompositeBlameCommandIT.java | 184 ++++++++++++++++++ .../scm/git/CompositeBlameCommandTest.java | 150 +++++++------- .../org/sonar/scm/git/GitScmProviderTest.java | 6 +- .../test/java/org/sonar/scm/git/GitUtils.java | 24 +++ .../sonar/scm/git/JGitBlameCommandTest.java | 30 ++- ...st.java => NativeGitBlameCommandTest.java} | 41 ++-- .../strategy/DefaultBlameStrategyTest.java | 82 ++++++++ .../5files-5commits/fifth-file.js | 1 + .../5files-5commits/first-file.js | 1 + .../5files-5commits/fourth-file.js | 1 + .../5files-5commits/second-file.js | 1 + .../5files-5commits/third-file.js | 1 + .../expected-blame/5lines-5commits/5lines.js | 5 + .../sonar/scm/git/expected-blame/ReadMe.txt | 6 + .../dummy-git-few-comitters/pom.xml | 52 +++++ .../src/main/java/org/dummy/AnotherDummy.java | 29 +++ .../src/main/java/org/dummy/Dummy.java | 29 +++ .../test/java/org/dummy/AnotherDummyTest.java | 31 +++ .../scm/git/expected-blame/dummy-git/pom.xml | 52 +++++ .../src/main/java/org/dummy/AnotherDummy.java | 29 +++ .../src/main/java/org/dummy/Dummy.java | 29 +++ .../test/java/org/dummy/AnotherDummyTest.java | 31 +++ .../merge-commits/merge-commit.js | 3 + .../one-file-many-merges-and-renames/file1.js | 10 + .../one-file-one-commit/one-commit.js | 1 + .../renamed-many-times.js | 5 + .../one-file-two-commits/two-commits.js | 2 + .../firstcopy.js | 1 + .../secondcopy.js | 1 + .../two-files-one-commit/firstfile.js | 1 + .../two-files-one-commit/secondfile.js | 1 + .../two-merge-commits/two-merge-commits.js | 4 + .../scm/git/test-repos/5files-5commits.zip | Bin 0 -> 27239 bytes .../scm/git/test-repos/5lines-5commits.zip | Bin 0 -> 28514 bytes .../test-repos/dummy-git-few-comitters.zip | Bin 0 -> 64004 bytes .../scm/git/test-repos/merge-commits.zip | Bin 0 -> 21206 bytes .../one-file-many-merges-and-renames.zip | Bin 0 -> 40675 bytes .../git/test-repos/one-file-one-commit.zip | Bin 0 -> 17336 bytes .../one-file-renamed-many-times.zip | Bin 0 -> 23835 bytes .../git/test-repos/one-file-two-commits.zip | Bin 0 -> 18942 bytes .../two-files-moved-around-with-conflicts.zip | Bin 0 -> 25956 bytes .../git/test-repos/two-files-one-commit.zip | Bin 0 -> 18077 bytes .../scm/git/test-repos/two-merge-commits.zip | Bin 0 -> 26802 bytes 50 files changed, 945 insertions(+), 123 deletions(-) rename sonar-scanner-engine/src/main/java/org/sonar/scm/git/{GitBlameCommand.java => NativeGitBlameCommand.java} (96%) create mode 100644 sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/BlameStrategy.java create mode 100644 sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/DefaultBlameStrategy.java create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java rename sonar-scanner-engine/src/test/java/org/sonar/scm/git/{GitBlameCommandTest.java => NativeGitBlameCommandTest.java} (87%) create mode 100644 sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fifth-file.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/first-file.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fourth-file.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/second-file.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/third-file.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5lines-5commits/5lines.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/ReadMe.txt create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/pom.xml create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/AnotherDummy.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/Dummy.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/test/java/org/dummy/AnotherDummyTest.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/pom.xml create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/AnotherDummy.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/Dummy.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/test/java/org/dummy/AnotherDummyTest.java create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/merge-commits/merge-commit.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-many-merges-and-renames/file1.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-one-commit/one-commit.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-renamed-many-times/renamed-many-times.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-two-commits/two-commits.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/firstcopy.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/secondcopy.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/firstfile.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/secondfile.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-merge-commits/two-merge-commits.js create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/5files-5commits.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/5lines-5commits.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-few-comitters.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/merge-commits.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-many-merges-and-renames.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-one-commit.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-renamed-many-times.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-two-commits.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-files-moved-around-with-conflicts.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-files-one-commit.zip create mode 100644 sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-merge-commits.zip diff --git a/build.gradle b/build.gradle index ef662359dc0..6e3f4a527e9 100644 --- a/build.gradle +++ b/build.gradle @@ -352,6 +352,7 @@ subprojects { dependency 'org.postgresql:postgresql:42.5.1' dependency 'org.reflections:reflections:0.10.2' dependency 'org.simpleframework:simple:5.1.6' + dependency 'org.sonarsource.git.blame:git-files-blame:1.0.0.157' dependency 'org.sonarsource.orchestrator:sonar-orchestrator:3.40.0.183' dependency 'org.sonarsource.update-center:sonar-update-center-common:1.29.0.1000' dependency("org.springframework:spring-context:${springVersion}") { diff --git a/sonar-scanner-engine/build.gradle b/sonar-scanner-engine/build.gradle index 851230ea84f..269ec1996e5 100644 --- a/sonar-scanner-engine/build.gradle +++ b/sonar-scanner-engine/build.gradle @@ -34,6 +34,7 @@ dependencies { api 'org.slf4j:log4j-over-slf4j' api 'org.slf4j:slf4j-api' api 'org.sonarsource.api.plugin:sonar-plugin-api' + api 'org.sonarsource.git.blame:git-files-blame' api 'org.sonarsource.update-center:sonar-update-center-common' api 'org.springframework:spring-context' @@ -60,7 +61,7 @@ dependencies { } license { - excludes(["**/Fake.java", "**/Fake.groovy", "org/sonar/scanner/cpd/ManyStatements.java"]) + excludes(["**/Fake.java", "**/Fake.groovy", "org/sonar/scanner/cpd/ManyStatements.java", "org/sonar/scm/git/expected-blame/**/*"]) } artifactoryPublish.skip = false diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/CompositeBlameCommand.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/CompositeBlameCommand.java index 1ea3b4a4f39..69c02674fd3 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/CompositeBlameCommand.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/CompositeBlameCommand.java @@ -22,14 +22,19 @@ package org.sonar.scm.git; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.util.ArrayList; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.diff.RawTextComparator; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; @@ -44,8 +49,13 @@ import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.log.Logger; import org.sonar.api.utils.log.Loggers; import org.sonar.api.utils.log.Profiler; +import org.sonar.scm.git.blame.BlameResult; +import org.sonar.scm.git.blame.RepositoryBlameCommand; +import org.sonar.scm.git.strategy.BlameStrategy; +import org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum; import static java.util.Optional.ofNullable; +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.GIT_FILES_BLAME; public class CompositeBlameCommand extends BlameCommand { private static final Logger LOG = Loggers.get(CompositeBlameCommand.class); @@ -53,12 +63,16 @@ public class CompositeBlameCommand extends BlameCommand { private final AnalysisWarnings analysisWarnings; private final PathResolver pathResolver; private final JGitBlameCommand jgitCmd; - private final GitBlameCommand nativeCmd; + private final NativeGitBlameCommand nativeCmd; private boolean nativeGitEnabled = false; - public CompositeBlameCommand(AnalysisWarnings analysisWarnings, PathResolver pathResolver, JGitBlameCommand jgitCmd, GitBlameCommand nativeCmd) { + private final BlameStrategy blameStrategy; + + public CompositeBlameCommand(AnalysisWarnings analysisWarnings, PathResolver pathResolver, JGitBlameCommand jgitCmd, + NativeGitBlameCommand nativeCmd, BlameStrategy blameStrategy) { this.analysisWarnings = analysisWarnings; this.pathResolver = pathResolver; + this.blameStrategy = blameStrategy; this.jgitCmd = jgitCmd; this.nativeCmd = nativeCmd; } @@ -66,23 +80,48 @@ public class CompositeBlameCommand extends BlameCommand { @Override public void blame(BlameInput input, BlameOutput output) { File basedir = input.fileSystem().baseDir(); - try (Repository repo = JGitUtils.buildRepository(basedir.toPath()); Git git = Git.wrap(repo)) { + try (Repository repo = JGitUtils.buildRepository(basedir.toPath())) { + File gitBaseDir = repo.getWorkTree(); if (cloneIsInvalid(gitBaseDir)) { return; } Profiler profiler = Profiler.create(LOG); profiler.startDebug("Collecting committed files"); - Set committedFiles = collectAllCommittedFiles(repo); + Map inputFileByGitRelativePath = getCommittedFilesToBlame(repo, gitBaseDir, input); profiler.stopDebug(); + + BlameAlgorithmEnum blameAlgorithmEnum = this.blameStrategy.getBlameAlgorithm(Runtime.getRuntime().availableProcessors(), inputFileByGitRelativePath.size()); + LOG.debug("Using {} strategy to blame files", blameAlgorithmEnum); + if (blameAlgorithmEnum == GIT_FILES_BLAME) { + blameWithFilesGitCommand(output, repo, inputFileByGitRelativePath); + } else { + blameWithNativeGitCommand(output, repo, inputFileByGitRelativePath, gitBaseDir); + } + } + } + + private Map getCommittedFilesToBlame(Repository repo, File gitBaseDir, BlameInput input) { + Set committedFiles = collectAllCommittedFiles(repo); + Map inputFileByGitRelativePath = new HashMap<>(); + for (InputFile inputFile : input.filesToBlame()) { + String relative = pathResolver.relativePath(gitBaseDir, inputFile.file()); + if (relative == null || !committedFiles.contains(relative)) { + continue; + } + inputFileByGitRelativePath.put(relative, inputFile); + } + return inputFileByGitRelativePath; + } + + private void blameWithNativeGitCommand(BlameOutput output, Repository repo, Map inputFileByGitRelativePath, File gitBaseDir) { + try (Git git = Git.wrap(repo)) { nativeGitEnabled = nativeCmd.checkIfEnabled(); ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors(), new GitThreadFactory()); - for (InputFile inputFile : input.filesToBlame()) { - String filename = pathResolver.relativePath(gitBaseDir, inputFile.file()); - if (filename == null || !committedFiles.contains(filename)) { - continue; - } + for (Map.Entry e : inputFileByGitRelativePath.entrySet()) { + InputFile inputFile = e.getValue(); + String filename = e.getKey(); // exceptions thrown by the blame method will be ignored executorService.submit(() -> blame(output, git, gitBaseDir, inputFile, filename)); } @@ -151,6 +190,29 @@ public class CompositeBlameCommand extends BlameCommand { } } + private static void blameWithFilesGitCommand(BlameOutput output, Repository repo, Map inputFileByGitRelativePath) { + RepositoryBlameCommand blameCommand = new RepositoryBlameCommand(repo) + .setTextComparator(RawTextComparator.WS_IGNORE_ALL) + .setMultithreading(true) + .setFilePaths(inputFileByGitRelativePath.keySet()); + try { + BlameResult blameResult = blameCommand.call(); + + for (Map.Entry e : inputFileByGitRelativePath.entrySet()) { + BlameResult.FileBlame fileBlameResult = blameResult.getFileBlameByPath().get(e.getKey()); + + if (fileBlameResult == null) { + LOG.debug("Unable to blame file {}.", e.getValue().filename()); + continue; + } + + saveBlameInformationForFileInTheOutput(fileBlameResult, e.getValue(), output); + } + } catch (GitAPIException e) { + LOG.warn("There was an issue when interacting with git repository: " + e.getMessage(), e); + } + } + private boolean cloneIsInvalid(File gitBaseDir) { if (Files.isRegularFile(gitBaseDir.toPath().resolve(".git/objects/info/alternates"))) { LOG.info("This git repository references another local repository which is not well supported. SCM information might be missing for some files. " @@ -166,4 +228,27 @@ public class CompositeBlameCommand extends BlameCommand { return false; } + + private static void saveBlameInformationForFileInTheOutput(BlameResult.FileBlame fileBlame, InputFile file, BlameOutput output) { + List linesList = new ArrayList<>(); + for (int i = 0; i < fileBlame.lines(); i++) { + if (fileBlame.getAuthorEmails()[i] == null || fileBlame.getCommitHashes()[i] == null || fileBlame.getCommitDates()[i] == null) { + LOG.debug("Unable to blame file {}. No blame info at line {}. Is file committed? [Author: {} Source commit: {}]", file.filename()); + linesList.clear(); + break; + } + linesList.add(new BlameLine() + .date(fileBlame.getCommitDates()[i]) + .revision(fileBlame.getCommitHashes()[i]) + .author(fileBlame.getAuthorEmails()[i])); + } + if (!linesList.isEmpty()) { + if (linesList.size() == file.lines() - 1) { + // SONARPLUGINS-3097 Git does not report blame on last empty line + linesList.add(linesList.get(linesList.size() - 1)); + } + output.blameResult(file, linesList); + } + } + } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmSupport.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmSupport.java index 70f7e2918d0..e06c95c7c48 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmSupport.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitScmSupport.java @@ -22,6 +22,7 @@ package org.sonar.scm.git; import java.util.Arrays; import java.util.List; import org.eclipse.jgit.util.FS; +import org.sonar.scm.git.strategy.DefaultBlameStrategy; public final class GitScmSupport { private GitScmSupport() { @@ -33,8 +34,9 @@ public final class GitScmSupport { return Arrays.asList( JGitBlameCommand.class, CompositeBlameCommand.class, + NativeGitBlameCommand.class, + DefaultBlameStrategy.class, ProcessWrapperFactory.class, - GitBlameCommand.class, GitScmProvider.class, GitIgnoreCommand.class); } diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitBlameCommand.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/NativeGitBlameCommand.java similarity index 96% rename from sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitBlameCommand.java rename to sonar-scanner-engine/src/main/java/org/sonar/scm/git/NativeGitBlameCommand.java index 9469ec15c38..0dd2e1620ef 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/GitBlameCommand.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/NativeGitBlameCommand.java @@ -39,13 +39,13 @@ import org.springframework.beans.factory.annotation.Autowired; import static java.util.Collections.emptyList; import static org.sonar.api.utils.Preconditions.checkState; -public class GitBlameCommand { +public class NativeGitBlameCommand { protected static final String BLAME_COMMAND = "blame"; protected static final String GIT_DIR_FLAG = "--git-dir"; protected static final String GIT_DIR_ARGUMENT = "%s/.git"; protected static final String GIT_DIR_FORCE_FLAG = "-C"; - private static final Logger LOG = Loggers.get(GitBlameCommand.class); + private static final Logger LOG = Loggers.get(NativeGitBlameCommand.class); private static final Pattern EMAIL_PATTERN = Pattern.compile("<(.*?)>"); private static final String COMMITTER_TIME = "committer-time "; private static final String AUTHOR_MAIL = "author-mail "; @@ -64,12 +64,12 @@ public class GitBlameCommand { private String gitCommand; @Autowired - public GitBlameCommand(System2 system, ProcessWrapperFactory processWrapperFactory) { + public NativeGitBlameCommand(System2 system, ProcessWrapperFactory processWrapperFactory) { this.system = system; this.processWrapperFactory = processWrapperFactory; } - GitBlameCommand(String gitCommand, System2 system, ProcessWrapperFactory processWrapperFactory) { + NativeGitBlameCommand(String gitCommand, System2 system, ProcessWrapperFactory processWrapperFactory) { this.gitCommand = gitCommand; this.system = system; this.processWrapperFactory = processWrapperFactory; diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/BlameStrategy.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/BlameStrategy.java new file mode 100644 index 00000000000..7092d5e5e05 --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/BlameStrategy.java @@ -0,0 +1,25 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scm.git.strategy; + +public interface BlameStrategy { + + DefaultBlameStrategy.BlameAlgorithmEnum getBlameAlgorithm(int availableProcessors, int numberOfFiles); +} diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/DefaultBlameStrategy.java b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/DefaultBlameStrategy.java new file mode 100644 index 00000000000..d52aed22d0d --- /dev/null +++ b/sonar-scanner-engine/src/main/java/org/sonar/scm/git/strategy/DefaultBlameStrategy.java @@ -0,0 +1,80 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scm.git.strategy; + +import org.sonar.api.config.Configuration; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; + +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.*; + +/** + * The blame strategy defines when the files-blame algorithm is used over jgit or native git algorithm. + * It has been found that the JGit/Git native algorithm performs better in certain circumstances, such as: + * - When we have many cores available for multi-threading + * - The number of files to be blame by the algorithm + * This two metrics are correlated: + * - The more threads available, the more it is favorable to use the JGit/Git native algorithm + * - The more files available, the more it is favorable to use the git-files-blame algorithm + */ +public class DefaultBlameStrategy implements BlameStrategy { + + private static final Logger LOG = Loggers.get(DefaultBlameStrategy.class); + private static final int FILES_GIT_BLAME_TRIGGER = 10; + public static final String PROP_SONAR_SCM_USE_BLAME_ALGORITHM = "sonar.scm.use.blame.algorithm"; + private final Configuration configuration; + + public DefaultBlameStrategy(Configuration configuration) { + this.configuration = configuration; + } + + @Override + public BlameAlgorithmEnum getBlameAlgorithm(int availableProcessors, int numberOfFiles) { + BlameAlgorithmEnum forcedStrategy = configuration.get(PROP_SONAR_SCM_USE_BLAME_ALGORITHM) + .map(BlameAlgorithmEnum::valueOf) + .orElse(null); + + if (forcedStrategy != null) { + return forcedStrategy; + } + + if (availableProcessors == 0) { + LOG.warn("Available processors are 0. Falling back to native git blame"); + return GIT_NATIVE_BLAME; + } + if (numberOfFiles / availableProcessors > FILES_GIT_BLAME_TRIGGER) { + return GIT_FILES_BLAME; + } + + return GIT_NATIVE_BLAME; + } + + public enum BlameAlgorithmEnum { + /** + * Strategy using native git for the blame, or JGit on single file as a fallback + */ + GIT_NATIVE_BLAME, + /** + * Strategy using git-files-blame algorithm + */ + GIT_FILES_BLAME; + } + +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java new file mode 100644 index 00000000000..3178cf68327 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandIT.java @@ -0,0 +1,184 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scm.git; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.LinkOption; +import java.nio.file.Path; +import java.time.OffsetDateTime; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; +import org.sonar.api.batch.fs.InputFile; +import org.sonar.api.batch.fs.internal.DefaultFileSystem; +import org.sonar.api.batch.fs.internal.TestInputFileBuilder; +import org.sonar.api.batch.scm.BlameCommand; +import org.sonar.api.batch.scm.BlameLine; +import org.sonar.api.notifications.AnalysisWarnings; +import org.sonar.api.scan.filesystem.PathResolver; +import org.sonar.api.utils.System2; +import org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@RunWith(DataProviderRunner.class) +public class CompositeBlameCommandIT { + + private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class); + + private final BlameCommand.BlameInput input = mock(BlameCommand.BlameInput.class); + private final JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(); + + private final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory(); + private final NativeGitBlameCommand nativeGitBlameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); + + @Test + @UseDataProvider("namesOfTheTestRepositoriesWithBlameAlgorithm") + public void testThatBlameAlgorithmOutputsTheSameDataAsGitNativeBlame(String folder, BlameAlgorithmEnum blameAlgorithm) throws Exception { + CompositeBlameCommand underTest = new CompositeBlameCommand(analysisWarnings, new PathResolver(), jGitBlameCommand, nativeGitBlameCommand, (p, f) -> blameAlgorithm); + + TestBlameOutput output = new TestBlameOutput(); + File gitFolder = unzipGitRepository(folder); + + setUpBlameInputWithFile(gitFolder.toPath()); + + underTest.blame(input, output); + + assertBlameMatchesExpectedBlame(output.blame, gitFolder); + } + + @DataProvider + public static Object[][] namesOfTheTestRepositoriesWithBlameAlgorithm() { + List testCases = List.of("one-file-one-commit", + "one-file-two-commits", + "two-files-one-commit", + "merge-commits", + "5lines-5commits", + "5files-5commits", + "two-files-moved-around-with-conflicts", + "one-file-renamed-many-times", + "one-file-many-merges-and-renames", + "two-merge-commits", + "dummy-git", + "dummy-git-few-comitters" + ); + + List blameStrategies = Arrays.stream(BlameAlgorithmEnum.values()).collect(Collectors.toList()); + return testCases.stream() + .flatMap(t -> blameStrategies.stream().map(b -> new Object[]{t, b})) + .toArray(Object[][]::new); + } + + + private void assertBlameMatchesExpectedBlame(Map> blame, File gitFolder) throws Exception { + Map> expectedBlame = readExpectedBlame(gitFolder.getName()); + + assertThat(blame.entrySet()) + .as("Blamed files: " + blame.keySet() + ". Expected blamed files " + expectedBlame.keySet()) + .hasSize(expectedBlame.size()); + + for (Map.Entry> actualBlame : blame.entrySet()) { + Path relativeFilePath = gitFolder.toPath().relativize(actualBlame.getKey().path()); + assertThat(actualBlame.getValue()) + .as("A difference is found in file " + relativeFilePath) + .isEqualTo(expectedBlame.get(relativeFilePath)); + } + } + + // --- helper methods --- // + + private Map> readExpectedBlame(String expectedBlameFolder) throws Exception { + Path expectedBlameFiles = new File(Utils.class.getResource("expected-blame/" + expectedBlameFolder).toURI()).toPath(); + Map> expectedBlame = new HashMap<>(); + + List filesInExpectedBlameFolder = Files.walk(expectedBlameFiles).filter(Files::isRegularFile).collect(Collectors.toList()); + for (Path expectedFileBlamePath : filesInExpectedBlameFolder) { + List blameLines = new ArrayList<>(); + List expectedBlameStrings = Files.readAllLines(expectedFileBlamePath); + for (String line : expectedBlameStrings) { + String revision = line.substring(0, 40); + + int beginningEmail = line.indexOf("<") + 1, endEmail = line.indexOf(">"); + String email = line.substring(beginningEmail, endEmail); + + int beginningDate = line.indexOf("2", endEmail), dateLength = 25; + String sDate = line.substring(beginningDate, beginningDate + dateLength); + Date parsedDate = new Date(OffsetDateTime.parse(sDate).toInstant().toEpochMilli()); + + BlameLine blameLine = new BlameLine() + .revision(revision) + .author(email) + .date(parsedDate); + + blameLines.add(blameLine); + } + expectedBlame.put(expectedBlameFiles.relativize(expectedFileBlamePath), blameLines); + } + return expectedBlame; + } + + private File unzipGitRepository(String repositoryName) throws IOException { + File gitFolderForEachTest = temp.newFolder().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toFile(); + Utils.javaUnzip(repositoryName + ".zip", gitFolderForEachTest); + return gitFolderForEachTest.toPath().resolve(repositoryName).toFile(); + } + + private static class TestBlameOutput implements BlameCommand.BlameOutput { + private final Map> blame = new ConcurrentHashMap<>(); + + @Override + public void blameResult(InputFile inputFile, List list) { + blame.put(inputFile, list); + } + } + + private void setUpBlameInputWithFile(Path baseDir) throws IOException { + DefaultFileSystem fs = new DefaultFileSystem(baseDir); + when(input.fileSystem()).thenReturn(fs); + + try (Stream stream = Files.walk(baseDir)) { + List inputFiles = stream.filter(Files::isRegularFile) + .map(f -> new TestInputFileBuilder("foo", baseDir.toFile(), f.toFile()).build()) + .filter(f -> !f.toString().startsWith(".git") && !f.toString().endsWith(".class")) + .collect(Collectors.toList()); + when(input.filesToBlame()).thenReturn(inputFiles); + } + } +} diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java index 622196549bd..088ee40d541 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/CompositeBlameCommandTest.java @@ -19,6 +19,9 @@ */ package org.sonar.scm.git; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -30,10 +33,14 @@ import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.IntStream; import org.apache.commons.io.FileUtils; +import org.assertj.core.api.Condition; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; import org.sonar.api.batch.fs.InputFile; import org.sonar.api.batch.fs.internal.DefaultFileSystem; import org.sonar.api.batch.fs.internal.DefaultInputFile; @@ -46,26 +53,33 @@ import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.MessageException; import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; +import org.sonar.scm.git.strategy.BlameStrategy; +import org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.Assume.assumeTrue; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.intThat; import static org.mockito.ArgumentMatchers.startsWith; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; import static org.mockito.Mockito.when; import static org.sonar.scm.git.Utils.javaUnzip; +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.GIT_FILES_BLAME; +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.GIT_NATIVE_BLAME; +@RunWith(DataProviderRunner.class) public class CompositeBlameCommandTest { private static final String DUMMY_JAVA = "src/main/java/org/dummy/Dummy.java"; - private final PathResolver pathResolver = new PathResolver(); private final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory(); private final JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(); - private final GitBlameCommand gitBlameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + private final NativeGitBlameCommand nativeGitBlameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); private final AnalysisWarnings analysisWarnings = mock(AnalysisWarnings.class); - private final CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, gitBlameCommand); + + private final PathResolver pathResolver = new PathResolver(); @Rule public TemporaryFolder temp = new TemporaryFolder(); @@ -74,10 +88,15 @@ public class CompositeBlameCommandTest { public LogTester logTester = new LogTester(); private final BlameCommand.BlameInput input = mock(BlameCommand.BlameInput.class); + @DataProvider + public static List blameAlgorithms() { + return Arrays.stream(BlameAlgorithmEnum.values()).collect(Collectors.toList()); + } + @Test public void use_jgit_if_native_git_disabled() throws IOException { - GitBlameCommand gitCmd = new GitBlameCommand("invalidcommandnotfound", System2.INSTANCE, processWrapperFactory); - BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, gitCmd); + NativeGitBlameCommand gitCmd = new NativeGitBlameCommand("invalidcommandnotfound", System2.INSTANCE, processWrapperFactory); + BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, gitCmd, (p, f) -> GIT_NATIVE_BLAME); File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); @@ -85,14 +104,33 @@ public class CompositeBlameCommandTest { setUpBlameInputWithFile(baseDir.toPath()); TestBlameOutput output = new TestBlameOutput(); blameCmd.blame(input, output); + + assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Using GIT_NATIVE_BLAME strategy to blame files"); assertThat(output.blame).hasSize(1); assertThat(output.blame.get(input.filesToBlame().iterator().next())).hasSize(29); } + @Test + public void blame_shouldCallStrategyWithCorrectSpecifications() throws IOException { + + BlameStrategy strategyMock = mock(BlameStrategy.class); + BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, strategyMock); + + File projectDir = createNewTempFolder(); + javaUnzip("dummy-git.zip", projectDir); + + File baseDir = new File(projectDir, "dummy-git"); + setUpBlameInputWithFile(baseDir.toPath()); + TestBlameOutput output = new TestBlameOutput(); + blameCmd.blame(input, output); + + verify(strategyMock).getBlameAlgorithm(intThat((i) -> i > 0), intThat(i -> i == 1)); + } + @Test public void fallback_to_jgit_if_native_git_fails() throws Exception { - GitBlameCommand gitCmd = mock(GitBlameCommand.class); - BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, gitCmd); + NativeGitBlameCommand gitCmd = mock(NativeGitBlameCommand.class); + BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, gitCmd, (p, f) -> GIT_NATIVE_BLAME); File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); @@ -102,6 +140,8 @@ public class CompositeBlameCommandTest { setUpBlameInputWithFile(baseDir.toPath()); TestBlameOutput output = new TestBlameOutput(); blameCmd.blame(input, output); + + assertThat(logTester.logs(LoggerLevel.DEBUG)).contains("Using GIT_NATIVE_BLAME strategy to blame files"); assertThat(output.blame).hasSize(1); assertThat(output.blame.get(input.filesToBlame().iterator().next())).hasSize(29); @@ -111,12 +151,15 @@ public class CompositeBlameCommandTest { } @Test - public void skip_files_not_committed() throws Exception { + @UseDataProvider("blameAlgorithms") + public void skip_files_not_committed(BlameAlgorithmEnum strategy) throws Exception { // skip if git not installed - assumeTrue(gitBlameCommand.checkIfEnabled()); + if (strategy == GIT_NATIVE_BLAME) { + assumeTrue(nativeGitBlameCommand.checkIfEnabled()); + } JGitBlameCommand jgit = mock(JGitBlameCommand.class); - BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jgit, gitBlameCommand); + BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jgit, nativeGitBlameCommand, (p, f) -> strategy); File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); @@ -126,18 +169,16 @@ public class CompositeBlameCommandTest { blameCmd.blame(input, output); assertThat(output.blame).hasSize(1); assertThat(output.blame.get(input.filesToBlame().iterator().next())).hasSize(29); - - // never had to fall back to jgit - verifyNoInteractions(jgit); } @Test - public void skip_files_when_head_commit_is_missing() throws IOException { + @UseDataProvider("blameAlgorithms") + public void skip_files_when_head_commit_is_missing(BlameAlgorithmEnum strategy) throws IOException { // skip if git not installed - assumeTrue(gitBlameCommand.checkIfEnabled()); + assumeTrue(nativeGitBlameCommand.checkIfEnabled()); JGitBlameCommand jgit = mock(JGitBlameCommand.class); - BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jgit, gitBlameCommand); + BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jgit, nativeGitBlameCommand, (p, f) -> strategy); File projectDir = createNewTempFolder(); javaUnzip("no-head-git.zip", projectDir); @@ -149,31 +190,15 @@ public class CompositeBlameCommandTest { assertThat(output.blame).isEmpty(); verifyNoInteractions(jgit); - assertThat(logTester.logs()) + assertThat(logTester.logs(LoggerLevel.WARN)) .contains("Could not find HEAD commit"); } @Test - public void use_native_git_by_default() throws IOException { - // skip test if git is not installed - assumeTrue(gitBlameCommand.checkIfEnabled()); - File projectDir = createNewTempFolder(); - javaUnzip("dummy-git.zip", projectDir); - File baseDir = new File(projectDir, "dummy-git"); + @UseDataProvider("blameAlgorithms") + public void return_early_when_shallow_clone_detected(BlameAlgorithmEnum strategy) throws IOException { + CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, (p, f) -> strategy); - JGitBlameCommand jgit = mock(JGitBlameCommand.class); - BlameCommand blameCmd = new CompositeBlameCommand(analysisWarnings, pathResolver, jgit, gitBlameCommand); - - setUpBlameInputWithFile(baseDir.toPath()); - TestBlameOutput output = new TestBlameOutput(); - blameCmd.blame(input, output); - assertThat(output.blame).hasSize(1); - assertThat(output.blame.get(input.filesToBlame().iterator().next())).hasSize(29); - verifyNoInteractions(jgit); - } - - @Test - public void return_early_when_shallow_clone_detected() throws IOException { File projectDir = createNewTempFolder(); javaUnzip("shallow-git.zip", projectDir); @@ -189,6 +214,8 @@ public class CompositeBlameCommandTest { @Test public void fail_if_not_git_project() throws IOException { + CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, (p, f) -> GIT_FILES_BLAME); + File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); @@ -207,7 +234,10 @@ public class CompositeBlameCommandTest { } @Test - public void dont_fail_with_symlink() throws IOException { + @UseDataProvider("blameAlgorithms") + public void dont_fail_with_symlink(BlameAlgorithmEnum strategy) throws IOException { + CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, (p, f) -> strategy); + assumeTrue(!System2.INSTANCE.isOsWindows()); File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); @@ -229,10 +259,13 @@ public class CompositeBlameCommandTest { when(input.filesToBlame()).thenReturn(Arrays.asList(inputFile, inputFile2)); TestBlameOutput output = new TestBlameOutput(); blameCommand.blame(input, output); + assertThat(output.blame).isNotEmpty(); } @Test public void return_early_when_clone_with_reference_detected() throws IOException { + CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, (p, f) -> GIT_FILES_BLAME); + File projectDir = createNewTempFolder(); javaUnzip("dummy-git-reference-clone.zip", projectDir); @@ -248,8 +281,9 @@ public class CompositeBlameCommandTest { TestBlameOutput output = new TestBlameOutput(); blameCommand.blame(input, output); - assertThat(logTester.logs()).first() - .matches(s -> s.contains("This git repository references another local repository which is not well supported")); + assertThat(logTester.logs()) + .haveAtLeastOne(new Condition<>(s-> s.startsWith("This git repository references another local repository which is not well supported"), + "log for reference detected")); // contains commits referenced from the old clone and commits in the new clone assertThat(output.blame).containsKey(inputFile); @@ -259,7 +293,9 @@ public class CompositeBlameCommandTest { } @Test - public void blame_on_nested_module() throws IOException { + @UseDataProvider("blameAlgorithms") + public void blame_on_nested_module(BlameAlgorithmEnum strategy) throws IOException { + CompositeBlameCommand blameCommand = new CompositeBlameCommand(analysisWarnings, pathResolver, jGitBlameCommand, nativeGitBlameCommand, (p, f) -> strategy); File projectDir = createNewTempFolder(); javaUnzip("dummy-git-nested.zip", projectDir); File baseDir = new File(projectDir, "dummy-git-nested/dummy-project"); @@ -271,40 +307,16 @@ public class CompositeBlameCommandTest { fs.add(inputFile); BlameCommand.BlameOutput blameResult = mock(BlameCommand.BlameOutput.class); - when(input.filesToBlame()).thenReturn(Arrays.asList(inputFile)); + when(input.filesToBlame()).thenReturn(List.of(inputFile)); blameCommand.blame(input, blameResult); Date revisionDate = DateUtils.parseDateTime("2012-07-17T16:12:48+0200"); String revision = "6b3aab35a3ea32c1636fee56f996e677653c48ea"; String author = "david@gageot.net"; verify(blameResult).blameResult(inputFile, - Arrays.asList( - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author), - new BlameLine().revision(revision).date(revisionDate).author(author))); + IntStream.range(0, 26) + .mapToObj(i -> new BlameLine().revision(revision).date(revisionDate).author(author)) + .collect(Collectors.toList())); } private BlameCommand.BlameInput setUpBlameInputWithFile(Path baseDir) { @@ -317,7 +329,7 @@ public class CompositeBlameCommandTest { } private File createNewTempFolder() throws IOException { - // This is needed for Windows, otherwise the created File point to invalid (shortened by Windows) temp folder path + // This is needed for Windows, otherwise the created File points to invalid (shortened by Windows) temp folder path return temp.newFolder().toPath().toRealPath(LinkOption.NOFOLLOW_LINKS).toFile(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java index 242b31fe372..cb7d1f68aec 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitScmProviderTest.java @@ -54,6 +54,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.sonar.api.config.Configuration; import org.sonar.api.notifications.AnalysisWarnings; import org.sonar.api.scan.filesystem.PathResolver; import org.sonar.api.utils.MessageException; @@ -61,6 +62,7 @@ import org.sonar.api.utils.System2; import org.sonar.api.utils.log.LogAndArguments; import org.sonar.api.utils.log.LogTester; import org.sonar.core.documentation.DocumentationLinkGenerator; +import org.sonar.scm.git.strategy.DefaultBlameStrategy; import static java.lang.String.format; import static java.util.Collections.emptySet; @@ -145,8 +147,8 @@ public class GitScmProviderTest { @Test public void returnImplem() { JGitBlameCommand jblameCommand = new JGitBlameCommand(); - GitBlameCommand nativeBlameCommand = new GitBlameCommand(System2.INSTANCE, new ProcessWrapperFactory()); - CompositeBlameCommand compositeBlameCommand = new CompositeBlameCommand(analysisWarnings, new PathResolver(), jblameCommand, nativeBlameCommand); + NativeGitBlameCommand nativeBlameCommand = new NativeGitBlameCommand(System2.INSTANCE, new ProcessWrapperFactory()); + CompositeBlameCommand compositeBlameCommand = new CompositeBlameCommand(analysisWarnings, new PathResolver(), jblameCommand, nativeBlameCommand, new DefaultBlameStrategy(mock(Configuration.class))); GitScmProvider gitScmProvider = new GitScmProvider(compositeBlameCommand, analysisWarnings, gitIgnoreCommand, system2, documentationLinkGenerator); assertThat(gitScmProvider.blameCommand()).isEqualTo(compositeBlameCommand); diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java index 6257b1bb512..13b152994fb 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitUtils.java @@ -40,5 +40,29 @@ public class GitUtils { Files.write(newFile, content.getBytes(), StandardOpenOption.CREATE); } + public static void createFile(Path worktree, String relativePath, String... lines) throws IOException { + Path newFile = worktree.resolve(relativePath); + Files.createDirectories(newFile.getParent()); + String content = String.join(System.lineSeparator(), lines) + System.lineSeparator(); + Files.write(newFile, content.getBytes(), StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING); + } + + public static void deleteFile(Path worktree, String relativePath) throws IOException { + Path fileToDelete = worktree.resolve(relativePath); + Files.delete(fileToDelete); + } + + public static void copyFile(Path worktree, String origin, String dest) throws IOException { + Path originPath = worktree.resolve(origin); + Path destPath = worktree.resolve(dest); + Files.copy(originPath, destPath); + } + + public static void moveFile(Path worktree, String origin, String dest) throws IOException { + Path originPath = worktree.resolve(origin); + Path destPath = worktree.resolve(dest); + Files.move(originPath, destPath); + } + } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java index 2100475da9d..af8a102f367 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/JGitBlameCommandTest.java @@ -30,6 +30,7 @@ import java.util.List; import org.apache.commons.io.FileUtils; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.lib.Repository; +import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; @@ -53,15 +54,20 @@ public class JGitBlameCommandTest { public LogTester logTester = new LogTester(); private final JGitBlameCommand jGitBlameCommand = new JGitBlameCommand(); + private Path baseDir; - @Test - public void blame_returns_all_lines() throws IOException { + @Before + public void before() throws IOException { File projectDir = createNewTempFolder(); javaUnzip("dummy-git.zip", projectDir); + baseDir = projectDir.toPath().resolve("dummy-git"); + } + + @Test + public void blame_returns_all_lines() { - File baseDir = new File(projectDir, "dummy-git"); - try (Git git = loadRepository(baseDir.toPath())) { + try (Git git = loadRepository(baseDir)) { List blameLines = jGitBlameCommand.blame(git, DUMMY_JAVA); Date revisionDate1 = DateUtils.parseDateTime("2012-07-17T16:12:48+0200"); @@ -90,10 +96,6 @@ public class JGitBlameCommandTest { @Test public void modified_file_returns_no_blame() throws IOException { - File projectDir = createNewTempFolder(); - javaUnzip("dummy-git.zip", projectDir); - - Path baseDir = projectDir.toPath().resolve("dummy-git"); // Emulate a modification Files.write(baseDir.resolve(DUMMY_JAVA), "modification and \n some new line".getBytes()); @@ -105,16 +107,12 @@ public class JGitBlameCommandTest { @Test public void new_file_returns_no_blame() throws IOException { - File projectDir = createNewTempFolder(); - javaUnzip("dummy-git.zip", projectDir); - - File baseDir = new File(projectDir, "dummy-git"); String relativePath2 = "src/main/java/org/dummy/Dummy2.java"; // Emulate a new file - FileUtils.copyFile(new File(baseDir, DUMMY_JAVA), new File(baseDir, relativePath2)); + FileUtils.copyFile(new File(baseDir.toFile(), DUMMY_JAVA), new File(baseDir.toFile(), relativePath2)); - try (Git git = loadRepository(baseDir.toPath())) { + try (Git git = loadRepository(baseDir)) { assertThat(jGitBlameCommand.blame(git, DUMMY_JAVA)).hasSize(29); assertThat(jGitBlameCommand.blame(git, relativePath2)).isEmpty(); } @@ -123,10 +121,6 @@ public class JGitBlameCommandTest { @Test public void symlink_doesnt_fail() throws IOException { assumeTrue(!System2.INSTANCE.isOsWindows()); - File projectDir = temp.newFolder(); - javaUnzip("dummy-git.zip", projectDir); - - Path baseDir = projectDir.toPath().resolve("dummy-git"); String relativePath2 = "src/main/java/org/dummy/Dummy2.java"; // Create symlink diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitBlameCommandTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java similarity index 87% rename from sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitBlameCommandTest.java rename to sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java index 834f02bd837..8bebca19a87 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/GitBlameCommandTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/NativeGitBlameCommandTest.java @@ -19,6 +19,7 @@ */ package org.sonar.scm.git; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; import java.io.File; import java.io.IOException; import java.nio.file.Files; @@ -35,6 +36,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; +import org.junit.runner.RunWith; import org.sonar.api.batch.scm.BlameLine; import org.sonar.api.utils.DateUtils; import org.sonar.api.utils.System2; @@ -51,15 +53,16 @@ import static org.mockito.ArgumentMatchers.isNull; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import static org.sonar.scm.git.GitBlameCommand.BLAME_COMMAND; -import static org.sonar.scm.git.GitBlameCommand.GIT_DIR_ARGUMENT; -import static org.sonar.scm.git.GitBlameCommand.GIT_DIR_FLAG; -import static org.sonar.scm.git.GitBlameCommand.GIT_DIR_FORCE_FLAG; +import static org.sonar.scm.git.NativeGitBlameCommand.BLAME_COMMAND; +import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_ARGUMENT; +import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_FLAG; +import static org.sonar.scm.git.NativeGitBlameCommand.GIT_DIR_FORCE_FLAG; import static org.sonar.scm.git.GitUtils.createFile; import static org.sonar.scm.git.GitUtils.createRepository; import static org.sonar.scm.git.Utils.javaUnzip; -public class GitBlameCommandTest { +@RunWith(DataProviderRunner.class) +public class NativeGitBlameCommandTest { private static final String DUMMY_JAVA = "src/main/java/org/dummy/Dummy.java"; @Rule @@ -67,7 +70,7 @@ public class GitBlameCommandTest { @Rule public LogTester logTester = new LogTester(); private final ProcessWrapperFactory processWrapperFactory = new ProcessWrapperFactory(); - private final GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + private final NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); @Before public void skipTestsIfNoGitFound() { @@ -161,7 +164,7 @@ public class GitBlameCommandTest { anyString(), anyString(), anyString(), anyString(), anyString(), anyString())) .then(invocation -> mockProcess); - GitBlameCommand blameCommand = new GitBlameCommand(gitCommand, System2.INSTANCE, mockFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(gitCommand, System2.INSTANCE, mockFactory); blameCommand.blame(baseDir.toPath(), DUMMY_JAVA); verify(mockFactory).create(any(), any(), eq(gitCommand), @@ -204,27 +207,27 @@ public class GitBlameCommandTest { @Test public void git_should_be_detected() { - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); assertThat(blameCommand.checkIfEnabled()).isTrue(); } @Test public void git_should_not_be_detected() { - GitBlameCommand blameCommand = new GitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory); assertThat(blameCommand.checkIfEnabled()).isFalse(); } @Test public void git_should_not_be_enabled_if_version_command_is_not_found() { ProcessWrapperFactory mockedCmd = mockGitVersionCommand("error: unknown option `version'"); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, mockedCmd); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd); assertThat(blameCommand.checkIfEnabled()).isFalse(); } @Test public void git_should_not_be_enabled_if_version_command_does_not_return_string_output() { ProcessWrapperFactory mockedCmd = mockGitVersionCommand(null); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, mockedCmd); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd); assertThat(blameCommand.checkIfEnabled()).isFalse(); } @@ -244,7 +247,7 @@ public class GitBlameCommandTest { return mock(ProcessWrapper.class); }); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, mockedCmd); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockedCmd); assertThat(blameCommand.checkIfEnabled()).isTrue(); }); } @@ -252,14 +255,14 @@ public class GitBlameCommandTest { @Test public void git_should_not_be_enabled_if_version_is_less_than_required_minimum() { ProcessWrapperFactory mockFactory = mockGitVersionCommand("git version 1.9.0"); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, mockFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, mockFactory); assertThat(blameCommand.checkIfEnabled()).isFalse(); } @Test public void throw_exception_if_command_fails() throws Exception { Path baseDir = temp.newFolder().toPath(); - GitBlameCommand blameCommand = new GitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand("randomcmdthatwillneverbefound", System2.INSTANCE, processWrapperFactory); assertThatThrownBy(() -> blameCommand.blame(baseDir, "file")).isInstanceOf(IOException.class); } @@ -271,7 +274,7 @@ public class GitBlameCommandTest { createFile(filePath, "line", baseDir); commitWithNoEmail(git, filePath); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); assertThat(blameCommand.checkIfEnabled()).isTrue(); List blame = blameCommand.blame(baseDir, filePath); assertThat(blame).hasSize(1); @@ -289,7 +292,7 @@ public class GitBlameCommandTest { createFile(filePath, "line", baseDir); commit(git, filePath, "my DOT name AT server DOT com"); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); assertThat(blameCommand.checkIfEnabled()).isTrue(); List blame = blameCommand.blame(baseDir, filePath); assertThat(blame).hasSize(1); @@ -304,7 +307,7 @@ public class GitBlameCommandTest { createFile(filePath, "line", baseDir); commitWithNoEmail(git, filePath); - GitBlameCommand blameCommand = new GitBlameCommand(System2.INSTANCE, processWrapperFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(System2.INSTANCE, processWrapperFactory); assertThat(blameCommand.checkIfEnabled()).isTrue(); List blame = blameCommand.blame(baseDir, filePath); assertThat(blame).hasSize(1); @@ -329,7 +332,7 @@ public class GitBlameCommandTest { return mockProcess; }); - GitBlameCommand blameCommand = new GitBlameCommand(system2, mockFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(system2, mockFactory); assertThat(blameCommand.checkIfEnabled()).isTrue(); assertThat(logTester.logs()).contains("Found git.exe at C:\\mockGit.exe"); } @@ -343,7 +346,7 @@ public class GitBlameCommandTest { ProcessWrapperFactory mockFactory = mock(ProcessWrapperFactory.class); mockGitWhereOnWindows(mockFactory); - GitBlameCommand blameCommand = new GitBlameCommand(system2, mockFactory); + NativeGitBlameCommand blameCommand = new NativeGitBlameCommand(system2, mockFactory); assertThat(blameCommand.checkIfEnabled()).isFalse(); } diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java new file mode 100644 index 00000000000..2cf351e5e33 --- /dev/null +++ b/sonar-scanner-engine/src/test/java/org/sonar/scm/git/strategy/DefaultBlameStrategyTest.java @@ -0,0 +1,82 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.scm.git.strategy; + +import java.util.Optional; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.config.Configuration; +import org.sonar.api.utils.log.LogTester; +import org.sonar.api.utils.log.LoggerLevel; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.GIT_FILES_BLAME; +import static org.sonar.scm.git.strategy.DefaultBlameStrategy.BlameAlgorithmEnum.GIT_NATIVE_BLAME; + +public class DefaultBlameStrategyTest { + + private final Configuration configuration = mock(Configuration.class); + private final BlameStrategy underTest = new DefaultBlameStrategy(configuration); + + @Rule + public LogTester logTester = new LogTester(); + + @Test + public void useRepositoryBlame_whenFileBlamePropsEnabled_shouldDisableRepoBlame() { + when(configuration.get(DefaultBlameStrategy.PROP_SONAR_SCM_USE_BLAME_ALGORITHM)).thenReturn(Optional.of(GIT_FILES_BLAME.name())); + + assertThat(underTest.getBlameAlgorithm(1, 1)).isEqualTo(GIT_FILES_BLAME); + + } + + @Test + public void useRepositoryBlame_whenFileBlamePropsDisableOrUnspecified_shouldEnableRepoBlame() { + when(configuration.get(DefaultBlameStrategy.PROP_SONAR_SCM_USE_BLAME_ALGORITHM)).thenReturn(Optional.of(GIT_NATIVE_BLAME.name())); + + assertThat(underTest.getBlameAlgorithm(1, 10000)).isEqualTo(GIT_NATIVE_BLAME); + + } + + @Test + public void useRepositoryBlame_whenFileBlamePropsInvalid_shouldThrowException() { + when(configuration.get(DefaultBlameStrategy.PROP_SONAR_SCM_USE_BLAME_ALGORITHM)).thenReturn(Optional.of("unknown")); + + assertThatThrownBy(() -> underTest.getBlameAlgorithm(1, 1)).isInstanceOf(IllegalArgumentException.class); + + } + + @Test + public void useRepositoryBlame_whenProcessorsCountAndFileSizeSpecified_shouldEnableRepoBlame() { + when(configuration.getBoolean(DefaultBlameStrategy.PROP_SONAR_SCM_USE_BLAME_ALGORITHM)).thenReturn(Optional.empty()); + + assertThat(underTest.getBlameAlgorithm(1, 10000)).isEqualTo(GIT_FILES_BLAME); + assertThat(underTest.getBlameAlgorithm(8, 10)).isEqualTo(GIT_NATIVE_BLAME); + + assertThat(underTest.getBlameAlgorithm(1, 10)).isEqualTo(GIT_NATIVE_BLAME); + assertThat(underTest.getBlameAlgorithm(1, 11)).isEqualTo(GIT_FILES_BLAME); + + + assertThat(underTest.getBlameAlgorithm(0, 10)).isEqualTo(GIT_NATIVE_BLAME); + assertThat(logTester.logs(LoggerLevel.WARN)).contains("Available processors are 0. Falling back to native git blame"); + } +} diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fifth-file.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fifth-file.js new file mode 100644 index 00000000000..f87f63f495e --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fifth-file.js @@ -0,0 +1 @@ +37463a67cb907766a8fb2178fd4fc9a1b6f4f14f ( 2023-02-24T09:51:22+01:00 1) fifth-file - changed diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/first-file.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/first-file.js new file mode 100644 index 00000000000..b2ad74c5667 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/first-file.js @@ -0,0 +1 @@ +5c2578e72d07e95781682a3ce1be61a954e39df8 ( 2023-02-24T09:49:41+01:00 1) first-file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fourth-file.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fourth-file.js new file mode 100644 index 00000000000..cdb59898f57 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/fourth-file.js @@ -0,0 +1 @@ +a7015bf40760ca91ae7d73d9102958fc870b30b9 ( 2023-02-24T09:51:08+01:00 1) fourth-file - changed diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/second-file.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/second-file.js new file mode 100644 index 00000000000..1cf8ae4a139 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/second-file.js @@ -0,0 +1 @@ +8bda33b1296875441f08c157140eb8504e13ebb2 ( 2023-02-24T09:49:59+01:00 1) second-file - changed diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/third-file.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/third-file.js new file mode 100644 index 00000000000..9e9bcd22016 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5files-5commits/third-file.js @@ -0,0 +1 @@ +442ca0c2c76fe6eee3246cae40fe36c077f4d4a0 ( 2023-02-24T09:50:13+01:00 1) third-file - changed diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5lines-5commits/5lines.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5lines-5commits/5lines.js new file mode 100644 index 00000000000..eaa6ca66feb --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/5lines-5commits/5lines.js @@ -0,0 +1,5 @@ +d0da62499e8476f7d7599b37d2f2201770cf6790 ( 2023-03-01T10:31:46+01:00 1) first line +bed9b1f0ae87ecda5ef1c805e303e2295676317b ( 2023-03-01T10:32:16+01:00 2) second line +939282feaabde0d049e739fd3e30937836c6fc13 ( 2023-03-01T10:32:33+01:00 3) third line +f4cfbd0b9fe74daea9dd588ec41e8da71505e959 ( 2023-03-01T10:32:46+01:00 4) fourth line +5fa3e610adad109fdc89cdfa68592ddd7a0ba3c6 ( 2023-03-01T10:33:03+01:00 5) fifth line diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/ReadMe.txt b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/ReadMe.txt new file mode 100644 index 00000000000..9949224313b --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/ReadMe.txt @@ -0,0 +1,6 @@ +This folder contains expected blame data for corresponding repositories (stored in test-repos folder). The data in expected-blame folder is +produced by blaming each file with +git blame {file_name_from_the_repository} --date=iso-strict --show-email -l --root > expected-blame/repository-name/{file_name_from_the_repository} + +The expected blame data is then used in the corresponding unit and integration tests to assert correctness of the new git blame algorithm +implemented in the scanner engine. \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/pom.xml b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/pom.xml new file mode 100644 index 00000000000..2424e4faa60 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/pom.xml @@ -0,0 +1,52 @@ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 1) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 2) 4.0.0 +783905e3d8b3e6f89a63c573d5fcf60af7845ebe ( 2012-07-20T18:52:36+02:00 3) dummy-git +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 4) dummy +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 5) 1.0 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 6) jar +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 7) Dummy +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 8) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 9) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 10) UTF-8 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 11) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 12) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 13) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 14) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 15) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 16) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 17) maven-clean-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 18) 2.4.1 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 19) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 20) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 21) maven-compiler-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 22) 2.3.2 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 23) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 24) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 25) maven-resources-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 26) 2.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 27) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 28) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 29) maven-source-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 30) 2.1.2 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 31) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 32) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 33) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 34) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 35) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 36) maven-compiler-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 37) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 38) 1.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 39) 1.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 40) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 41) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 42) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 43) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 44) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 45) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 46) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 47) junit +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 48) junit +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 49) 4.10 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 50) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 51) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 52) diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/AnotherDummy.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/AnotherDummy.java new file mode 100644 index 00000000000..ffec5c679d1 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/AnotherDummy.java @@ -0,0 +1,29 @@ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 1) /* +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 2) * Sonar, open source software quality management tool. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 3) * Copyright (C) 2008-2012 SonarSource +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 4) * mailto:contact AT sonarsource DOT com +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 5) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 6) * Sonar is free software; you can redistribute it and/or +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 7) * modify it under the terms of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 8) * License as published by the Free Software Foundation; either +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 9) * version 3 of the License, or (at your option) any later version. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 10) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 11) * Sonar is distributed in the hope that it will be useful, +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 14) * Lesser General Public License for more details. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 15) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 16) * You should have received a copy of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 17) * License along with Sonar; if not, write to the Free Software +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 19) */ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 20) package org.dummy; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 21) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 22) public class AnotherDummy { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 23) public String say(boolean hello) { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 24) if (hello) { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 25) return "Hello"; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 26) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 27) return new String("GoodBye"); +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 28) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 29) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/Dummy.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/Dummy.java new file mode 100644 index 00000000000..d54958921de --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/main/java/org/dummy/Dummy.java @@ -0,0 +1,29 @@ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 1) /* +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 2) * Sonar, open source software quality management tool. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 3) * Copyright (C) 2008-2012 SonarSource +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 4) * mailto:contact AT sonarsource DOT com +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 5) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 6) * Sonar is free software; you can redistribute it and/or +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 7) * modify it under the terms of the GNU Lesser General Public +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 8) * License as published by the Free Software Foundation; either +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 9) * version 3 of the License, or (at your option) any later version. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 10) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 11) * Sonar is distributed in the hope that it will be useful, +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 14) * Lesser General Public License for more details. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 15) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 16) * You should have received a copy of the GNU Lesser General Public +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 17) * License along with Sonar; if not, write to the Free Software +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 19) */ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 20) package org.dummy; +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 21) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 22) public class Dummy { +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 23) public String sayHello() { +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 24) return "Hello"; +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 25) } +7609f824d5ff7018bebf107cdbe4edcc901b574f ( 2022-10-11T14:14:26+02:00 26) public String sayBye() { +7609f824d5ff7018bebf107cdbe4edcc901b574f ( 2022-10-11T14:14:26+02:00 27) return "Bye"; +7609f824d5ff7018bebf107cdbe4edcc901b574f ( 2022-10-11T14:14:26+02:00 28) } +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 29) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/test/java/org/dummy/AnotherDummyTest.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/test/java/org/dummy/AnotherDummyTest.java new file mode 100644 index 00000000000..92c55be754a --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git-few-comitters/src/test/java/org/dummy/AnotherDummyTest.java @@ -0,0 +1,31 @@ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 1) /* +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 2) * Sonar, open source software quality management tool. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 3) * Copyright (C) 2008-2012 SonarSource +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 4) * mailto:contact AT sonarsource DOT com +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 5) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 6) * Sonar is free software; you can redistribute it and/or +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 7) * modify it under the terms of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 8) * License as published by the Free Software Foundation; either +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 9) * version 3 of the License, or (at your option) any later version. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 10) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 11) * Sonar is distributed in the hope that it will be useful, +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 14) * Lesser General Public License for more details. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 15) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 16) * You should have received a copy of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 17) * License along with Sonar; if not, write to the Free Software +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 19) */ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 20) package org.dummy; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 21) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 22) import org.junit.Test; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 23) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 24) import static org.junit.Assert.assertEquals; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 25) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 26) public class AnotherDummyTest { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 27) @Test +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 28) public void should_say_hello() { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 29) assertEquals("Hello", new AnotherDummy().say(true)); +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 30) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 31) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/pom.xml b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/pom.xml new file mode 100644 index 00000000000..d770317afb6 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/pom.xml @@ -0,0 +1,52 @@ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 1) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 2) 4.0.0 +783905e3d8b3e6f89a63c573d5fcf60af7845ebe ( 2012-07-20T18:52:36+02:00 3) dummy-git +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 4) dummy +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 5) 1.0 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 6) jar +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 7) Dummy +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 8) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 9) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 10) UTF-8 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 11) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 12) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 13) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 14) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 15) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 16) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 17) maven-clean-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 18) 2.4.1 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 19) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 20) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 21) maven-compiler-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 22) 2.3.2 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 23) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 24) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 25) maven-resources-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 26) 2.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 27) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 28) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 29) maven-source-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 30) 2.1.2 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 31) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 32) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 33) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 34) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 35) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 36) maven-compiler-plugin +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 37) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 38) 1.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 39) 1.5 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 40) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 41) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 42) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 43) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 44) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 45) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 46) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 47) junit +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 48) junit +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 49) 4.10 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 50) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 51) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 52) diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/AnotherDummy.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/AnotherDummy.java new file mode 100644 index 00000000000..bf0da1e1e2d --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/AnotherDummy.java @@ -0,0 +1,29 @@ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 1) /* +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 2) * Sonar, open source software quality management tool. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 3) * Copyright (C) 2008-2012 SonarSource +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 4) * mailto:contact AT sonarsource DOT com +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 5) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 6) * Sonar is free software; you can redistribute it and/or +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 7) * modify it under the terms of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 8) * License as published by the Free Software Foundation; either +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 9) * version 3 of the License, or (at your option) any later version. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 10) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 11) * Sonar is distributed in the hope that it will be useful, +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 14) * Lesser General Public License for more details. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 15) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 16) * You should have received a copy of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 17) * License along with Sonar; if not, write to the Free Software +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 19) */ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 20) package org.dummy; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 21) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 22) public class AnotherDummy { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 23) public String say(boolean hello) { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 24) if (hello) { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 25) return "Hello"; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 26) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 27) return new String("GoodBye"); +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 28) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 29) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/Dummy.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/Dummy.java new file mode 100644 index 00000000000..8245e31e6cc --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/main/java/org/dummy/Dummy.java @@ -0,0 +1,29 @@ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 1) /* +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 2) * Sonar, open source software quality management tool. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 3) * Copyright (C) 2008-2012 SonarSource +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 4) * mailto:contact AT sonarsource DOT com +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 5) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 6) * Sonar is free software; you can redistribute it and/or +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 7) * modify it under the terms of the GNU Lesser General Public +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 8) * License as published by the Free Software Foundation; either +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 9) * version 3 of the License, or (at your option) any later version. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 10) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 11) * Sonar is distributed in the hope that it will be useful, +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 14) * Lesser General Public License for more details. +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 15) * +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 16) * You should have received a copy of the GNU Lesser General Public +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 17) * License along with Sonar; if not, write to the Free Software +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 19) */ +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 20) package org.dummy; +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 21) +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 22) public class Dummy { +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 23) public String sayHello() { +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 24) return "Hello"; +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 25) } +0d269c1acfb8e6d4d33f3c43041eb87e0df0f5e7 ( 2015-05-19T13:31:09+02:00 26) public String sayBye() { +0d269c1acfb8e6d4d33f3c43041eb87e0df0f5e7 ( 2015-05-19T13:31:09+02:00 27) return "Bye"; +0d269c1acfb8e6d4d33f3c43041eb87e0df0f5e7 ( 2015-05-19T13:31:09+02:00 28) } +6b3aab35a3ea32c1636fee56f996e677653c48ea ( 2012-07-17T16:12:48+02:00 29) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/test/java/org/dummy/AnotherDummyTest.java b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/test/java/org/dummy/AnotherDummyTest.java new file mode 100644 index 00000000000..c7df309c4a2 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/dummy-git/src/test/java/org/dummy/AnotherDummyTest.java @@ -0,0 +1,31 @@ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 1) /* +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 2) * Sonar, open source software quality management tool. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 3) * Copyright (C) 2008-2012 SonarSource +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 4) * mailto:contact AT sonarsource DOT com +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 5) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 6) * Sonar is free software; you can redistribute it and/or +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 7) * modify it under the terms of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 8) * License as published by the Free Software Foundation; either +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 9) * version 3 of the License, or (at your option) any later version. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 10) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 11) * Sonar is distributed in the hope that it will be useful, +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 12) * but WITHOUT ANY WARRANTY; without even the implied warranty of +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 13) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 14) * Lesser General Public License for more details. +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 15) * +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 16) * You should have received a copy of the GNU Lesser General Public +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 17) * License along with Sonar; if not, write to the Free Software +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 18) * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 19) */ +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 20) package org.dummy; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 21) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 22) import org.junit.Test; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 23) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 24) import static org.junit.Assert.assertEquals; +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 25) +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 26) public class AnotherDummyTest { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 27) @Test +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 28) public void should_say_hello() { +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 29) assertEquals("Hello", new AnotherDummy().say(true)); +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 30) } +ffb55a516440d069145dd9199e4ac67976b2338b ( 2012-07-20T15:26:23+02:00 31) } diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/merge-commits/merge-commit.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/merge-commits/merge-commit.js new file mode 100644 index 00000000000..3fca0bd063a --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/merge-commits/merge-commit.js @@ -0,0 +1,3 @@ +2b6ccf6d99dea2840613563aa54fdc5c8efc05cb ( 2023-03-01T14:43:49+01:00 1) first commit +5a729e03b90e11d3d4f582a63cd2df93a7db41e0 ( 2023-03-01T14:44:47+01:00 2) second commit on master +e62f234121479b8aa3bf60481324784c6ed6ba40 ( 2023-03-01T14:45:59+01:00 3) commit on branch \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-many-merges-and-renames/file1.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-many-merges-and-renames/file1.js new file mode 100644 index 00000000000..1a868d1d919 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-many-merges-and-renames/file1.js @@ -0,0 +1,10 @@ +691242bf1b8319a7398be257c206203f7d6b8743 file1.js ( 2023-02-24T10:28:35+01:00 1) 111 - changed +cb5f118c653af2e6d4d30f798714f45f5338c11c file.js ( 2023-02-24T10:29:03+01:00 2) 222 - changed +84dd29d9b45487fecae9d952f1e71c5dea4cd356 file.js ( 2023-02-24T10:26:31+01:00 3) 333 +ea53e21a12061a733434454cf6cb8c6c29094fd0 file1.js ( 2023-02-24T10:33:06+01:00 4) 444 - changed in master +84dd29d9b45487fecae9d952f1e71c5dea4cd356 file.js ( 2023-02-24T10:26:31+01:00 5) 555 +223e2f4e80d72199dae13b94690099dccc20eeea file1.js ( 2023-03-01T10:52:44+01:00 6) 666 - changed on branch1 +84dd29d9b45487fecae9d952f1e71c5dea4cd356 file.js ( 2023-02-24T10:26:31+01:00 7) 777 +84dd29d9b45487fecae9d952f1e71c5dea4cd356 file.js ( 2023-02-24T10:26:31+01:00 8) 888 +84dd29d9b45487fecae9d952f1e71c5dea4cd356 file.js ( 2023-02-24T10:26:31+01:00 9) 999 +c700a4b511aeecb225b4bd86dbe964f29730cffd file.js ( 2023-02-24T10:27:59+01:00 10) 100 - changed diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-one-commit/one-commit.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-one-commit/one-commit.js new file mode 100644 index 00000000000..348567b955e --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-one-commit/one-commit.js @@ -0,0 +1 @@ +23628a3b878ae8dd5e51042c7a39057a3e4ce45c ( 2023-02-23T14:29:45+01:00 1) hello world diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-renamed-many-times/renamed-many-times.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-renamed-many-times/renamed-many-times.js new file mode 100644 index 00000000000..d9ca90d398a --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-renamed-many-times/renamed-many-times.js @@ -0,0 +1,5 @@ +13bc62d2a546d41696e25e26ae44b3671f5ddf89 c.js ( 2023-02-24T10:16:08+01:00 1) initial-change +13bc62d2a546d41696e25e26ae44b3671f5ddf89 c.js ( 2023-02-24T10:16:08+01:00 2) second-change +13bc62d2a546d41696e25e26ae44b3671f5ddf89 c.js ( 2023-02-24T10:16:08+01:00 3) third-change +3561639d487376f1d8c0297838fd2a94c5563d61 d.js ( 2023-02-24T10:16:39+01:00 4) fourth-change +5123767d66854a431e9f6a05a88cf7db6e73aabc e.js ( 2023-02-24T10:17:15+01:00 5) fifth-change \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-two-commits/two-commits.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-two-commits/two-commits.js new file mode 100644 index 00000000000..4d40b8eadd9 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/one-file-two-commits/two-commits.js @@ -0,0 +1,2 @@ +51c8ead53b248e93e66e5038c826524c0730f271 ( 2023-02-23T14:39:44+01:00 1) first line first commit +b497efbe6a7ff547dee5dcc368b8920dba0fd908 ( 2023-02-23T14:40:18+01:00 2) second line second commit diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/firstcopy.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/firstcopy.js new file mode 100644 index 00000000000..167d039fec9 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/firstcopy.js @@ -0,0 +1 @@ +5ee03833d69a38d440a8685eb33dd96b0bea24e6 first.js ( 2023-03-02T11:47:42+01:00 1) commit on master, file: first.js \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/secondcopy.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/secondcopy.js new file mode 100644 index 00000000000..89de99f0a0a --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-moved-around-with-conflicts/secondcopy.js @@ -0,0 +1 @@ +dab8b2a7c229b1111fbfe7c7dda7f9913ebb71f9 ( 2023-03-02T11:46:47+01:00 1) second commit, file: second.js \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/firstfile.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/firstfile.js new file mode 100644 index 00000000000..5ce08eaf95c --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/firstfile.js @@ -0,0 +1 @@ +a66e868e71a5e871ca9d9d74035adc0a743ac537 ( 2023-02-23T16:45:23+01:00 1) first file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/secondfile.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/secondfile.js new file mode 100644 index 00000000000..927595f0883 --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-files-one-commit/secondfile.js @@ -0,0 +1 @@ +a66e868e71a5e871ca9d9d74035adc0a743ac537 ( 2023-02-23T16:45:23+01:00 1) second file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-merge-commits/two-merge-commits.js b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-merge-commits/two-merge-commits.js new file mode 100644 index 00000000000..06935cc60fb --- /dev/null +++ b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/expected-blame/two-merge-commits/two-merge-commits.js @@ -0,0 +1,4 @@ +48559ab7c378fb7181dc515967bd0dcfc71a8a57 ( 2023-03-01T14:54:30+01:00 1) first commit +b5767c89ce517009ede7a6c7e69f46f4d2270fb5 ( 2023-03-01T14:56:53+01:00 2) fifth commit on master +69cf0175d31c5a2c1517ac2d3515864324c436e9 ( 2023-03-01T14:55:02+01:00 3) second commit on branch +c65549591670241841ae5882453ea05e51e3df20 ( 2023-03-01T14:56:33+01:00 4) fourth commit on branch \ No newline at end of file diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/5files-5commits.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/5files-5commits.zip new file mode 100644 index 0000000000000000000000000000000000000000..2e5068acc6f6f0e6022270b088fabf7d4596a76b GIT binary patch literal 27239 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 P2mX)%TVXu|!r%T6^v4wV literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-few-comitters.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/dummy-git-few-comitters.zip new file mode 100644 index 0000000000000000000000000000000000000000..fcef9cdf47ca33baf2eb9e67bc842f593f63fb20 GIT binary patch literal 64004 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 literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/merge-commits.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/merge-commits.zip new file mode 100644 index 0000000000000000000000000000000000000000..60e9d2a150255a347d27b695c64e5dd5477bb26c GIT binary patch literal 21206 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 literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-many-merges-and-renames.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-many-merges-and-renames.zip new file mode 100644 index 0000000000000000000000000000000000000000..ce7e7b993ca0456f4aaedc9a1517d92c6c1e1e5c GIT binary patch literal 40675 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 bq0T!~nBN?d`3++}{C5V@2M@zPHjMuQwg36a literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-one-commit.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/one-file-one-commit.zip new file mode 100644 index 0000000000000000000000000000000000000000..becfbf720e441d4e1fdd71ab1b1ecaee9393898f GIT binary patch literal 17336 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

;(I<197*jpYsI}V00ZOK>}|20B>RQ64S>L^*BY1 zk1yrU%`SITSo6MlxMr+qb~V%hi>^496?#?=9G(8r?ut6kGXkk(^Jxmf(2HbVOd$~A zzzSVX{*_@Iofd8Bkv+{Se34#V@Xe^iy_b~nuWq03bv-W-yJ^D<1POcLcz*Vmb=c4D z&|OfDbBOtTf@)`t5*jYTmCHP>7j5SN<394F|MH>@kY2RRVNr;pX!hku?R{-2Ux@;r zw!U6zB^LF?dGxoVs~e~vx8GlC-1=xU(qP|S%hiTv%QQEqNrA&Kd&W)&dRDF>$zoAe z1cNu2U~Fdo@oRsc3=$c$=XbU+ZnoHQ7?s_rn!(6diu0t73?5oBbJng5N?@8YAIuiU zBT`3e5HC~BrrEf9&4OVXg}|P6 zXY^B@wy&&OVLgKLlQ&um(xSeUzsjAv{V!O z%}~t(g^Rg&!L?w_Wt`!CMy>~nUMS9oZ)O&DyM^+%hOOGp{N1k3(U@}FMfl8cgp+eB zzZt3Q@4oX7MO$luZHI-353CMCo}XtXG=48H30FpW(^`OX1v>|IE14ThUtI6;MU9K> zVmu)STa~FMuBdy;BoVGFl^(99wihfHE)?=~gaGwLKa!2O5Na+RJb+MG#j&})w=d}T z*?OsB!ZiPKW&Kc4bAI?;`dfH70q2N-m6_Mm`G)jW8wHO93x_19!42+ml3D4_%|eBx zFAd{-)#J_NpZbJ}k{~@z55)Z(AKYFII_FujO}_{-JtJzRSL*Ug^5P658|oH5F`DGIea9Rh&hoS<g{rrh*V9Ub-PbD5f+~I61v(`-eObZz2p@=9lEY#ucL9GDkOw+Y3CVL&bjCb z;u*|pJ9*)4vK3|#K6+C76|=CyFE$cG|Fst8SY7xK zU4xxBcjcK6yJpd6fG_R^s&bL*enm14h`F&}w#A$Wt34lTmuK#;?AcR(sQJLp{?$&^1$!QF|B5)r6Px z`llDy?r8LIP8&Mby#By0K>TrpTiz>mJ$1gC?0iZ_|5$5AMtN+cb|8=B{k`qh*#*Tt zl`m0RZWsBDBK)pPm2R&{O75>3tP=a4d0qS#&mssG@bzl>Ksv(}Uq0^(8F3F^XoP+O zQ16Xg!((NCM3?-Lm9)ZHJ3y6Y4v6+i@ovwe5{Tut0Q$x~;br2Dqm5ebp;7 zgI5BfckG1*C9iH?$27%%9PPySrLyN01?$eBH7s$0Y~Bsa?bAV4sRHTYiB(lva^2_< zv2i>_tg3RS+CUH!{ae)Q@6+8YLRHltKwQ6aK%xrpI9K8UeDtuAayh-`GF7s*s9)>e zJdMk$MMUqm$L*G&^z~%0seQ%QVRm ztsiB~GW#d`JAj09d2B4ax@@Xi;~(o8qzA=w@i8YT%|>nphc1Y-DJGl?63~*2VbaaX zp%li0wNLj4;R@BH$3R;~@yxM`66J<7v0E?er7^kiK3DfpeDIJyeAz3!Vbj`y>PoFk zneJnvVJZoR1#=Kj>ewM;NK97QYJVcH1=M1$CB(3v*^*z1D^rLhVr6z~eQCdY(fh;V z9O{GQsBL5+-3%uKaCfP#+Kb$URtvGFrxTC ziY0x{Nz72>{+;Su*W+*kG+rBPa9iMOU&$?;p{%`tla>{tKdsvWB!Nun{ zjV{euMnxMkZZuez%A8NEwVdy$F3Mq(Jl>EkvI0$!}`%yim)ipd9pN*a2pKDO2V(q51-OoRKk3Mufs{}X&MU}d?L+cxI{WZlJ?Z0pEIY^A;)(aFTS*5@CagwSe^ zmQ0yFl4AOjrz046nLM@mnfmNx3w?b1l}9x!C=sPOXguoTtTZ+NbnuT5Kh z5Ywkq=B>V&*i)O(v9aFVU9$bESDrHU;IQDDA=>%Xs4+Aqi39!Ugf2OSVQQ^r=lyD> zXp!{BvPzS#pv-M4nJJ4{(VZD>HQ*-@_gNX)Gc|L~j1=|U;aJPUH8wsm(vlxCRMjZk zVHkWLtVo%s+0)i^G;MHp@uZ2K3Hcm&&FwOt2?Ef*Sup%Ku`{SFM(vL;AnyD{iC6NT z2e!>P&48UsFv{aZLv9wj&Z>^_yPuTMm^YLiBqW2+jCEqKf_dGv@3;aa6+TrN4BF$) z@*V)Wiyj%FWy%B3N8RUU?}2$J@SA%Vw|>eq=wK9lB2l#=hPOhrvL)FzvKCXa<$D!> zpl`y?w8GGx%E=r3@AC;`FrqLKF`uLn^Xc+w7cDzyN3$QkNthPc5;2Pos1HIC&c7pk zRLuTG>p>mcJ<@9wP#9gqtClU$x!8-UQ46oCy%r$O)M$cG*_BYV(UJI`=&^J9xMwcPPykL5*S6SX!Te&a*L0{`Zar+bTN}Ihhx8* zkUe?xgkLx+77eLfK?l#1uJW@nRlts?VW4r28H}BPD^W^&H(|@Tfu({S3-{tPrD!j3V%fsXRr zjG6&X27VvqLS3?y?Z6AB0mQ1dD#96uyQ~;`X1b9%4D1K;?;A*Qsl;N18ZRz|yuTZ7 zGfqVkYG{T^rK@JW!vlZT6f$H*MAu~Do8R3<-P2L}Fd4UkvUmGw(C&E@h8vS8X>qSK z8s`Hwd3{*CUqt%NIkoaEW_2y=1`^wp>CZ4^;FB?SHb1%ZAY>oYPSxh6d-$l?{SCvl z)S4pnzO=KxL~9U7#R%LXmudkmvIiG-&@{G1MfR?&%H}*#Bz+ytK%&Xz;Ii6=lM~|? z8fU6j;aZt{re#%)%OzKACJ0*QCDZau2kTut@UVxQ)O=fOAM5X?@4u+4{t+7mh4K9V z;FvqWAYjLz=eW+Nh7jx@2ilaVaIp*YS`{y?Mk?gMZ2g)#2DUD0T=P-3tJq$lgwg^`q0FS2cz~M>whhi=Wa`v zB8`@Orp-014S%nzgBWeDXhqrODHe{_zQBtyQlU5Wv)b_+1w~St-*#)I73zn47$MKn zG&f@+xV4$M!J-@wHUe@LvwalwgqMyEUnGoWiH~zpOnAw)5A|NDcwP)wm6*&FqS~Uo zA4gG~*WXZcmr$?2K_=Fm`j&B&A-*Eol?xO(hBge0aqgJ?;~=&vQx7$RnUs>KcP<3f zZ$@>s0(Y;xfuLoLjusTo{s?*qCVG#+S}2&&18w~Roa-ccsqPtuYq1w=|-bcaR~ zx^Js?q_Ms|U|%RvtFI9R?g1Ji)H?S~u48xT54)A_LWGOn!-ha8EqyifuHM&81Ko8%E3!i7g zX_IN59$sj_L?lVA@|B0Bd2{TV0CaDZIC^2~B2C!NvX4@Hnu|y|2Yk|awELw;z^aT@ zYMY75n`=|yZ4(>2X5*OKmu@xtm9E?7FYa!dO--Ymf3tFfieF%E@UWi!afNgYEm~IU zv~K@)r3O>%M(cF_!uE8) z7V-SBkuINSG;yrL+vBXvNb;f!9@DwfY=5J7gdbPMjqnAY1W4l+Lwl6R%4VSz7h2iz zv33g8nD5zum15T~Z;pGPmDzYaN?Q0Kk-EZ{oVS2ZiB5RzhMrw@NY`1k7Gk#gXz3gb z_^w*|jmyPKFYj@`XQRJ=VUuPnGJoEB&*mQaWv+aI_4&|rI)zaEIH&hIZrd0Ig zBKBlrQ*wsm-52zgKGU1F@5`hlzaf8kixt+KH0Qp`5X}$p9Q3|A z=J+OM;rT)ojsuF{Z1_NmE}wCX>s`TjY?NOLUW~ZmQ01kq9km#Tj7GCHSBKt?uOR3Dh{MxY^y8J4c@goYhmzBA1cQk0hw?p9S_fMXJyz zq6noCv5Dew3@%Z1+kG`vcSaocln)sE%K zl5G+pA~{1kpB!r-wjcH-syyaTPc7q1>t@i*FBslZ!&{JAd_;j4`n zvHN*OOi@R_cU}^)%lw6ox9hSoJ~po$Up{$$x#4y-X+@(?&a5X%V%P+l&Q7UVhJ+1c zRqT^e_gWh{`8^8dOEJucSi~HSwgt(opd_7eR(X7#Lh;Q-oot@Z@2(~&?WS#jdga%H6QRARw>uBy5vP56gaduLkTK#Q>Hven%w2xE z5YB3?DsKS9;*B@?O3r#+HfXueAs39k(WA{+$#C7K?7s4Ov5*mLseLh*mQ)=3p?-JM z2H>zLRbC9OezSf~fEb}@@Cy!{o`-~1+Rs~RDPka32laiM)va^=vmW!mClcq3-B2!S zd99!?zy7IvzehsmY=nYy#vhR}fYbS%`%O3M4 z(Z&_IiN-6(Z5P!GOt%?yacMM@hHky+#wDQT4ELV+IxA!OCMDP<1!Wti*t|}cNw)e> zX$OD31l696#_T5cC+CB{d*jOOmYPDQpu0V1?%EPp3!ck0TI;a)@TPe*wl>Ap@}9 zufB#nw|e^$+$z8IK!Bo*glZ39JlK5Q_2HLGQBmB@d5KT?(EM3e z8eJP#mgl}E4BcpoSMl@i%Gi$DA$z57`dA~4R=%-Rmx@1RCO(8ND^f`T_HY89-ztl} zxj&>tK%C5hqPC8vm7lsp5ihPztpm!FwBywNu`yDp?%CTlSfOu7Rh>EGP)M}OP`wrm zzdF)$vgQM)F5JMDAFW*Dp%Xd`0vsrnojqA0Gpm zV(w9@B!Y;?%@)@mH;Z`L>=-?&hT~nh@qp-H{pplv8bN0Z$H%J=jn%b2tQCY`_NCgt zuCBZ0-s4;QoHQE0#eeF`btd77aYh0)CeZD=J$?c;7Vm?rx}0BY&)MAJnO=p`pWBO0 zzsXL$zqa~y;!We&)jdz^v&~N%CrM!IwbM+z&l)vI%Q?;Q#cgVWrOG7Ab4cg8@5N<5 zC5(oD)Gp+(I=HYP*rN$@>c}~G#ZTBVPg7Tx=6Z>i%McIbAI@(5m)^&zXfJQY6E!7(!gL*g~2RqEsPe3w>9XkP|hxfSB4>x zGD2#-du{bnCm#l9y|t-GS_vuj&|A=&dWu67-i_^NQjR$9O7}t=8*FM*u8pXG2zkHK zE|ZH|HU*{9!yio+B$KCP`hJcs7S|Qv;H2)YCXq@jTU))QRPFYX1xu1oBi)N`Jg;K- z^;mfoQ3-tY0Xh%0W?pFnQIl?AoAxs3k~+!I?eiOD3>HJAVRq+xXU`kZ89jLs1#@<3=uRb;&c2s0_id>QfkNso4aviR0`u(o^{&;yu#vLip#)5Z z0V`ab?hftxB-$76i>NK8+iym68pz;3DTH&p+H~bVOZVyST+kXmjeRWl>;m- z)`hRtdWI-=XGhN`xr2K297AkyuOA3RW6n%YFU4zXXK z&7uzWBqm72?K-=-3&=^!iSpY;ky07A%0+$F z$8R4kXvlia`SNm`EyO}*h1h-of3~2R+nB&^Ij#~oz>STK(I!X&%R;f14a&`6-PoJ30x?R<(Aed%m@v`vc(*@9drKIx+_!opZ2M{I z)vyxLeD{^SWcp44zeKbin3=IL9DPQ_8uSLw6 z{M~6NZN+}R`oO2Vt?MPn>K{+mCjPMw;kGAA6I~_R8FCRL@fp#C|8ztU(qOlsR?a3c z?yxI(bpR6S?Ig(4(Ck4M-jZ`S+|cdM4nGl!nu?nW8VoZPj$ICHtcb@;Jv%sP24zn% z*JZ)8e5z{OdpV3~k;mHHxxsQ-sN%Vua1}W}`xO#WjG-p~vg~BEWYgIuMJvVi22?!9 zap6t0M)gIsNqY&>#HU009Ssppj~DNd#cnl;(?{KL)*Ce9<2;LZ3G!rrt3XABJS^b+ z3w=~3nZ5NlrA>`nwVz4@SC+AV+9V1}_=#H2Kh&p{t?BVnPo#xwWM7HOMp(B!A~GrP zXZrjm4Oya^7}K8D3m^^{*kFgdoxLs?ew!ta7*dZ`IElLtv~e6BWRoxT&1kgNXU;>B zS!Icj))gIVD?A&=-StQ&xVc{2gE3}Puy6wlof1z<)*Ms5yC$x+IZSe*h)O}k`SVxL z=dPWO2liY;gwRp~AJ^m!y36E@Jud{YMw2glYW7zpjAylu^p&m;OFXk7XMMQIt;CDT zU#+#-HVH4xub0fjG@D1Yo3i7GGe6_CJ35X2EP11=-2NkKI-0i~h&oOz;;p`}Z4-6| zVVMwE3Xe;U)rvArFn|PhW8p)#q(OD{Yf1$ySJ(2&mmW!Pm)-n*iWWdd_BQ%#W8PX` zMT3@3Rhwa{T>|ey%c4}3d>~FSIiyjQtoIic*aGD8pH?}rfxZS9LlB{*Q;b_?FY+4s0^dZ@RJ&44|%Q00|+mZ(Or#n$zZ zcegecDeK`c9eekI9z_F7sUrZI-EABN_s556Sg~utQ89hN>WU*CBBY%n4gpvGH^C4Gunp8KF``oegO8x0b6ImLk6_73G@ggicl=7lE{6G|vcvS) zj-02eD~#2wZ`?dlMwn6r-*naH_9%?(NZl2-yu~3^gb{o(0?;F% zsAu??@u}{TXGBu-R!CrGiqwTLq3l;nIWpn3{+5$vd6JEWAMC~QlU15i$@=>cVYj`*)YUKXWs@&RuuUnoFgJ;`n!itlxU{bsOULvj^OM zI_mF;cUU0!dB0Vt|I0&3PMv;Jz|&sKM;F^`s1#PtX-gg{8@VVVR za`nXfwH9vx1c99knsX(E8dFUV68RfCpu7`<3JXH^^!DtF^QP~Y3lbHa?|;3C^YskF zsE+ZyOkxkZ#Q7YVY$$IZAC?JK%-uc?#cZGa-frHp&-1hF)aNS*$tpoNHXHe2lDxg< zL@#iAcZfoAUj|YGD^jF9vzH&@iDx`kSbNiYVNZY;Gw&;9i<>Xk>?fiZIm;a|=}2nz zsdv$#`l+sq_ni7exLpVD+7^HIL!m6)MK7qt3}k;Z7st3xSvNYHD9z@PHGG44!1++o z!S-^lnDmQB1P}rLmH{y>uF*{^rROpN_H=X?)d>$g>e<#+J~8neG`!sVD|7wN%OAi$ zGhthZ1q^u;F}Wrv>v0m3I_R>YFL*Ftm-*>0S!lL(nG01N~a6a)%`g%Pn| z0U-cf$OHz40Kss62%nG%6aat%f&8~nIoTDIuLFeP00961$fqvX%EiIc-O2%PA{p|^ znKbwq=66=OYFKr5xy*jOCs9rCyU#-}(*nMGzOr1%GhbAl7nJHfG%$YC^BoF)BIB`p z5iTc|qf=^#A9zedNSVgAcA`88%^=$;HH45UC?v!O;uC;~fFS_5urL@ZA`IsPfe=5z zLU4rU;9vj@2)Tu-*wU=30T43&rW$p*j?VUWu5N^)+T>qqu&F3_bSfhBHG_t-qeIYo zWF5#!jOgB9-zm8Z2pr?yhTtwfd(j4YZwc8>$sHk6fFBA1fWUlE5uhL+7%0Fm2!%nR z06r1KKLJcYd~gUK1Zf>VxSM?Ed4l{MoKG-PM^qF{HA4Eo6OYT=c={I6L1a69Cm{%n z6czvq0stn0KmZ>Y02Bf63BkZ3a3MiKkN^xO02G3o+(ONbxPsV6h-D0CNrv#RMk!>U zBev%@O5wy- zWZ_->Zib6|H^nz!4L$ork1oJPP+C7H0#)IV?Z*o_KTS+}xD|F$(KwrdWL37zDNP}l zZ&O1&6KB_mU}d=R;g)sv=RND2ZsG2r;fw{|Czn?CUxZV2IxiM|$_k$za%WB<@k04B zSK&Bg7U7rh)vtw1bgX|gYz8|p65MvAy_4?cDa}Su@R->kWk$2x%ta$c1KCbFA_$o< zKBx&CY$75E5f%mj5r4uFGeigg1qca4`2KZyfw#y!SS(%TH%xxnQQGl1CqUv=utm}E z9-Eh2|DQEU5Oz$#NSULfG5R$K}OI~SzzT|FJMtFjQ z(>0OjQ|DidZ;(EUL2bZsXkl*gc2D)#W@uMSi|3B>zLZD-#fs`r5mI&cMj0Ccsax@S!5t{=9DkOqf zZ-n?vL=YA(Vj=<;2EsuCaA5&KS7Dy$%~BtR^`x`bw z;rt-P-%vgwD4z*PL;%PS2k|4eryqML_`Bzz-qfktq|C)5&)xG2AAq?UWXRkcn_9K_Do<00ag{cq$?w0X`rY#1BKboBSdsNVi;AKm>GT zA@KiVA!t!D^%vds>TjSh@DL6kkuUlGOb?Ue(*r5fe+K7z1A;iRosv94CQOhI1Q8NO zEF6MDh2k`R?2nq^A;U>Uu-kYKg;$SLWzQtam3Xbd!;!`8hBdf%? z*c}`_h{x>Kom3^&%j5)n=oVV5)V5G200`#I&6HAj7BZDPiJO~3Pcsx;AV1|-NU7qo z)ev6XSD&(9eDBGN=2nL6`ltjNX=>IK*mo4R76HfG6$Ms($kA znCs_@_f7aDt3>I%Q34B~u18~nT!ay7`|CU9!ftYMVZY5l`}7?`Dzcq+Ou)Pl5ePq6 z7|PENg76_eI0Oz8h6+&p;H0J)g zg_jpad=^BCfxWj7?+4hqx5O|Ncy4V==&|TMD6Op>4AOo$5!_8EaI3g^$Dc({M&z7+ zsw~Ytb@O6xL>*c;)U@j{svJpw)(4!cGl4(w+wi7t0zc9 zyI_I6n;i#kv$Gr&im@+=x0zedo6$+xX=kBCC~)>$_b!b$96tRt8qX{{7)wt<+~6CZ zPHQy7d39tv)YHMA<+hT;mrtFfpN-m=wh0BmU&jXzP}CEwR*%N$|21z+jxDQ5nMUsO zVgKXiYhuF72ZJF_IRc0s1t0(efB}5`!ay)s7-+&L1OW=bAR+=F#PR2^W!3c0H{btu zc)t%}YCh7^|LFh=KfbggW$MSPz5E}wgpg?h6A%{Shl622un?b!5D+LR1Ovf9f*_!X zkO>69FMv3b2qF&e-@+UJ#YOoq8<64m4M-_Dv{$|(fK@3?Nvksvycji+xMT1h2c^l2 zA>l|%C(|n;i23;kZ#Dc30-4(!OSAm*L5WjJwF5&fkJ;!p!bWFV7RcBUeMGiDOg5-$ z$jjbDCL0717WzBKlw*;glWO|ItjUQm_y1^`$DZ=|IgsBY+&Iprd8|K_BmQRtc}(W_ z;5K1xAu0+z4tl|eZB6nPHQv_Yd4c#I^$ViWA)RY7&~#(|tytn2_n#g39-r)psv`e6 zI;Zcz_kgc}!0*LR{$-T@FeC9z2TtH)2`&^Aq|M!GYo=pBs1wy@%ybndRrU%@7%cPkx%xBB7P$NAH;wEiv!L#K)O7xd0GSz9ishynAZ`8cr(Z3 z2O{UUz}|^~7aJD-_lTF8A}SgQ3JF5|KjX^Cz})xm+>hVC$M?q*Lw^^1@{u8=M1)x( zej=aO`2)d!e{$%k|G$1`2qF6i3^LLC2Qc4X9Xc)^IrC3G33MbLjQU67k3A4{gz@V) zevU9U{tN@T!W|cWa_K@o?(_X4M*Px6+n zzK$sU`jwj_Oh!cc*dJ5+$D21N@lHN}a)jrGxG((2c>nb=l#{q8Z@VAiq9I=H`eWRG z-hDp_c=FEq5#Z9P01=gwM+5rf^3h4mlUJ{gF!j%zhU8z@2LB7*$s3?YcvsJ#67LuH zK~J(gc_s1)H50KE|M^hV)p6(IbqKNz}i zwPZ)q|LLM5J=*Uda$DFy1fKs$`ZxFg@4LduIxD2~@4JE&!pHbi=|8Hjj#D_9Yx+9{ zX|6v4`BB((L;-BYmrR%LO-7Kw4P&fln4c8Z>S zD@-`jI}+n$X~GfP?Nej?UZKKqw!g}?9a$L$A_8|Bw#X`hBeqD4lXU_|Y;{kK@q6L8 z<30KJ6(kDrp7ANze#^oiu|;B>%)=kCojEne?`7qWv;9?4=4fm~L{G)`TkidcEfV8o z_Wg+M=&3P&FBgBD?XPm8M{ElaHNmGC+iyAaBeuWFq93uvK*TOjhw*zk_2X>+ecl$F zt|#9z=0|Li7$I}y_i?uWzDhwapROm!MDh_^B*w{9 z@)6tDr^fib#Pac;{QKBqOP!7_G9`P&7Kw2(DSO1$;M5qum!du1lYjSNxe<4&Phn-> zQmaR7kr*eFt4C~oPL1(C5jQ@-(I?eJZv;Qlv+G{~aakbSOVkrbj5h zN}3|Md_R~U{u#<&Db#<{7UJ;z<3no8UFMIp^^XX~zgu3@DWv~8cyTg!ilp#eN7UE; zoWZZ-7QarC9w8;38tI=Qi<8#%_uvw}?4NV`ks1BFX`RfC9+7eUZHVKU(j&wAbt?2o g{?u>F|65{IO%W53uR%ToaTVnYHDWd+Uw}mU50LphPXGV_ literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-files-one-commit.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-files-one-commit.zip new file mode 100644 index 0000000000000000000000000000000000000000..d90349a63438135177d1f458b3028abd0ef44732 GIT binary patch literal 18077 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 literal 0 HcmV?d00001 diff --git a/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-merge-commits.zip b/sonar-scanner-engine/src/test/resources/org/sonar/scm/git/test-repos/two-merge-commits.zip new file mode 100644 index 0000000000000000000000000000000000000000..3f8c40fe8ca9122375040d48480c3b22123ed2c3 GIT binary patch literal 26802 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