SonarScanner blame falling back to GIT_NATIVE_BLAME - how to debug?

  • ALM used: GitHub
  • CI system used: Github Actions
  • Scanner command used:
sonar-scanner 
   -Dsonar.projectVersion=1.35.13
   -Dsonar.branch.name=feature/abc 
   -Dsonar.cfamily.gcov.reportsPath=.builddir/.builddir-test-unit-coverage/ 
   -Dsonar.cfamily.compile-commands=.builddir/.builddir-test-unit-coverage/compile_commands.json
   -X 
  • Languages of the repository: C++
  • Error observed:
07:43:05.695 INFO: Sensor gcov [cpp] (done) | time=7865ms
07:43:05.695 INFO: Sensor Zero Coverage Sensor
07:43:05.722 INFO: Sensor Zero Coverage Sensor (done) | time=27ms
07:43:05.726 INFO: SCM Publisher SCM provider for this project is: git
07:43:05.727 INFO: SCM Publisher 3 source files to be analyzed
07:43:05.728 DEBUG: loading config FileBasedConfig[/home/devenv/.config/jgit/config]
07:43:05.730 DEBUG: Collecting committed files
07:43:05.750 DEBUG: Collecting committed files (done) | time=21ms
07:43:05.751 DEBUG: Using GIT_NATIVE_BLAME strategy to blame files
07:43:05.755 DEBUG: Failed to find git native client
java.io.IOException: Cannot run program "git": error=2, No such file or directory
        at java.base/java.lang.ProcessBuilder.start(Unknown Source)
        at java.base/java.lang.ProcessBuilder.start(Unknown Source)
        at org.sonar.scm.git.ProcessWrapperFactory$ProcessWrapper.execute(ProcessWrapperFactory.java:50)
        at org.sonar.scm.git.GitBlameCommand.checkIfEnabled(GitBlameCommand.java:66)
        at org.sonar.scm.git.CompositeBlameCommand.blameWithNativeGitCommand(CompositeBlameCommand.java:107)
        at org.sonar.scm.git.CompositeBlameCommand.blame(CompositeBlameCommand.java:86)
        at org.sonar.scanner.scm.ScmPublisher.publish(ScmPublisher.java:76)
        at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:164)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
        at org.sonar.scanner.bootstrap.ScannerContainer.doAfterStart(ScannerContainer.java:399)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
        at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:131)
        at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:123)
        at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:109)
        at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:60)
        at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:54)
        at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.base/java.lang.reflect.Method.invoke(Unknown Source)
        at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
        at jdk.proxy1/jdk.proxy1.$Proxy0.execute(Unknown Source)
        at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
        at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:126)
        at org.sonarsource.scanner.cli.Main.execute(Main.java:81)
        at org.sonarsource.scanner.cli.Main.main(Main.java:62)
Caused by: java.io.IOException: error=2, No such file or directory
        at java.base/java.lang.ProcessImpl.forkAndExec(Native Method)
        at java.base/java.lang.ProcessImpl.<init>(Unknown Source)
        at java.base/java.lang.ProcessImpl.start(Unknown Source)
        ... 30 common frames omitted

07:43:05.757 DEBUG: Blame file (JGit) src/libname/a.hpp
07:43:05.757 DEBUG: Blame file (JGit) src/test/a_test.cpp
07:43:05.758 DEBUG: Blame file (JGit) src/test/b_test.cpp
07:43:05.886 INFO: SCM Publisher 3/3 source files have been analyzed (done) | time=159ms

Environment in which I run SonarScanner CLI indeed does not have git and installing git seems to resolve the error, but as stated in another post, using native Git client for blame information comes at a performance penalty so I’d really like to understand what is wrong with JGit. However I’m not seeing any indications as to why SonarScanner switched to GIT_NATIVE_BLAME.

I’ve seen some FAQs on the topic and tried running git fetch --no-filter --refetch but it has no effect.

Here’s some info about the SonarScanner version that I’m using:

08:05:38.876 INFO: SonarScanner 5.0.1.3006
08:05:38.876 INFO: Java 17.0.7 Eclipse Adoptium (64-bit)
08:05:38.876 INFO: Linux 6.8.0-76060800daily20240311-generic amd64

Hi,

There is a heuristic (same for SonarQube and SonarCloud) based on the number of files to blame and the number of available CPUs to decide whether to use our JGit extension (able to blame multiple files in a single call) or the native git CLI to blame files individually.
It seems in your case the choice was made to favor the single-blame option.

You can influence this decision by setting the scanner property: sonar.scm.use.blame.algorithm=GIT_FILES_BLAME

So is it GIT_FILES_BLAME or GIT_NATIVE_BLAME as suggested here?

Also, I’m trying to keep a lean Docker image on which SonarScanner is running. Is there a way to pin the blame algorithm to use JGit in a similar manner? I can’t find any documentation on the sonar.scm.use.blame.algorithm at all (not even on the Analysis parameters page which has some of the sonar.scm.* parameters documented) so I don’t know what the allowed values are.

Just checked the link, is my understanding correct that:

  • sonar.scm.use.blame.algorithm can one of the 2 values: GIT_NATIVE_BLAME or GIT_FILES_BLAME
  • GIT_NATIVE_BLAME uses git
  • GIT_FILES_BLAME uses JGit
    ?

This is not documented, because it is probably not something we want to put in stone. Consider it more as a workaround, or a way to test the performance of the 2 options.

By the way, in your original log, the stacktrace you see is simply a DEBUG message. Except if you measure a performance penalty, I would trust the heuristic and keep the default behavior.

You haven’t answered how I can do that. To measure difference in performance I need ability to force SonarScanner to use either git or JGit. Will sonar.scm.use.blame.algorithm=GIT_FILES_BLAME force the use of JGit?

yes, it will use our customer blame algorithm based on JGit.

1 Like

Btw, what is the purpose of calculating the blame? How is it used for the purposes of code scanning or coverage analysis?

I could not find the equivalent in the SonarCloud documentation, but this is the same purpose as for SonarQube:

  • Automatic Issue Assignment
  • Code annotation (blame data) in the Code Viewer
  • SCM-driven detection of new code (to help with Clean as You Code). Without SCM data, SonarCloud determines new code using analysis dates (to timestamp modification of lines).

Thank you!

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.