"not a git repository" error

Hello everyoone!

I am having the “not a git repository” error when trying to run a multibranch pipeline project. I’m running Jenkins locally on a Windows 11 machine.

I’ve found this post and this article and based on those I’ve changed the permissions on the configured folders, to no avail.

Versions:

  • Jenkins 2.387.2
  • Git plugin 5.0.0

Here’s the Jenkinsfile

pipeline {
  agent {
    node {
      label 'master'
      customWorkspace "C:\\Unreal\\Workspace"//use backward slashes to avoid problems with how Windows uses directories!!
    }
  }//^all this is necessary to run the build in a special workspace.
  environment {
    ue5Path = "C:\\Program Files\\Epic Games\\UE_5.1"
    ue5Project = "CITesting"
    ueProjectFileName = "${ue5Project}.uproject"
    testSuiteToRun = "Game."//the '.' is used to run all tests inside the prettyname. The automation system searches for everything that has 'Game.' in it, so otherGame.'s tests would run too...
    testReportFolder = "TestsReport"
    testsLogName = "RunTests.log"
    pathToTestsLog = "${env.WORKSPACE}" + "\\Saved\\Logs\\" + "${testsLogName}"
    codeCoverageReportName="CodeCoverageReport.xml"
  }
  stages {
    stage('Building') {
      steps {
        echo 'Build Stage Started.'

        bat "BuildWithoutCooking.bat \"${ue5Path}\" \"${env.WORKSPACE}\" \"${ueProjectFilename}\""//builds our project
      }
      post {
        success {
          echo 'Build Stage Successful.'
        }
        failure {
          echo 'Build Stage Unsuccessful.'
        }
      }
    }

    stage('Testing') {
      steps {
        echo 'Testing Stage Started.'

        bat "TestRunnerAndCodeCoverage.bat \"${ue5Path}\" \"${env.WORKSPACE}\" \"${ueProjectFilename}\" \"${testSuiteToRun}\" \"${testReportFolder}\" \"${testsLogName}\" \"${codeCoverageReportName}\""//runs the tests
      }
      post {
        success {
          echo 'Testing Stage Successful.'
        }
        failure {
          echo 'Testing Stage Unsuccessful.'
        }
      }
    }


  }
  post {
    always{
      echo 'Tests finished, printing log.'
      bat "type ${pathToTestsLog}"
      echo 'Formatting TestsReport from JSon to JUnit XML'
      formatUnitTests()

        slackSend channel: "#testing-ci",
          color: '#c2f2d0',
          message: "\n *Tests Report Summary* - Total Tests: ${testReportSummary.totalCount}, Failures: ${testReportSummary.failCount}, Skipped: ${testReportSummary.skipCount}, Passed: ${testReportSummary.passCount}"

      echo "Publish Code Coverage Report."
      cobertura(coberturaReportFile:"${codeCoverageReportName}")

      echo 'Cleaning up workspace:'
      echo '-checking current workspace.'
      powershell label: 'show workspace', script: 'dir $WORKSPACE'
      bat 'git reset --hard'//resets to HEAD, to the commit in the cloned repository.
      bat 'git clean -dffx .'//removes untracked files.
      echo '-checking clean workspace.'
      powershell label: 'show workspace', script: 'dir $WORKSPACE'

      echo 'Result:'
    }
    success{
        echo '!!! SUCCESS !!!'
    }
    unstable{
        echo '!!! UNSTABLE !!!'
    }
    failure{
        echo '!!! FAILURE !!!'
    }
  }
}

/*import groovy.json.JsonSlurper
import groovy.xml.MarkupBuilder

def testReportSummary = 'to be populated...'

def formatUnitTests() {
        convertTestsReport()
        testReportSummary = junit "${testReportFolder}\\junit.xml"
}

def convertTestsReport() {
    def jsonReport = readFile file: "${testReportFolder}\\index.json", encoding: "UTF-8"
    // Needed because the JSON is encoded in UTF-8 with BOM

    jsonReport = jsonReport.replace( "\uFEFF", "" );

    def xmlContent = transformReport( jsonReport )

    writeFile file: "${testReportFolder}\\junit.xml", text: xmlContent.toString()
}

@NonCPS//atomic method
def transformReport( String jsonContent ) {

    def parsedReport = new JsonSlurper().parseText( jsonContent )
    
    def jUnitReport = new StringWriter()
    def builder = new MarkupBuilder( jUnitReport )

    builder.doubleQuotes = true
    builder.mkp.xmlDeclaration version: "1.0", encoding: "utf-8"

    builder.testsuite( tests: parsedReport.succeeded + parsedReport.failed, failures: parsedReport.failed, time: parsedReport.totalDuration ) {
      for ( test in parsedReport.tests ) {
        builder.testcase( name: test.testDisplayName, classname: test.fullTestPath, status: test.state ) {
          if(test.state == "Fail") {
            for ( entry in test.entries ) { 
              if(entry.event.type == "Error") {
                builder.failure( message: entry.event.message, type: entry.event.type, entry.filename + " " + entry.lineNumber )
              }
            }
          }
        }
      }
    } 

    return jUnitReport.toString()
}*/

And the output when running the pipeline

Started by user admin
Running as SYSTEM
Building in workspace C:\Unreal\ThirdPersonAdventure
The recommended git tool is: NONE
using credential b085e6b7-775b-417d-a965-26a369181923
 > git.exe rev-parse --resolve-git-dir C:\Unreal\ThirdPersonAdventure\.git # timeout=10
Fetching changes from the remote Git repository
 > git.exe config remote.origin.url https://github.com/XXXXXXXXXX/ThirdPersonAdventure # timeout=10
ERROR: Error fetching remote repo 'origin'
hudson.plugins.git.GitException: Failed to fetch from https://github.com/XXXXXXXXXX/ThirdPersonAdventure
	at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:1003)
	at hudson.plugins.git.GitSCM.retrieveChanges(GitSCM.java:1245)
	at hudson.plugins.git.GitSCM.checkout(GitSCM.java:1309)
	at hudson.scm.SCM.checkout(SCM.java:540)
	at hudson.model.AbstractProject.checkout(AbstractProject.java:1240)
	at hudson.model.AbstractBuild$AbstractBuildExecution.defaultCheckout(AbstractBuild.java:649)
	at jenkins.scm.SCMCheckoutStrategy.checkout(SCMCheckoutStrategy.java:85)
	at hudson.model.AbstractBuild$AbstractBuildExecution.run(AbstractBuild.java:521)
	at hudson.model.Run.execute(Run.java:1900)
	at hudson.model.FreeStyleBuild.run(FreeStyleBuild.java:44)
	at hudson.model.ResourceController.execute(ResourceController.java:101)
	at hudson.model.Executor.run(Executor.java:442)
Caused by: hudson.plugins.git.GitException: Command "git.exe config remote.origin.url https://github.com/XXXXXXXXXX/ThirdPersonAdventure" returned status code 128:
stdout: 
stderr: fatal: not in a git directory

	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2734)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2660)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommandIn(CliGitAPIImpl.java:2656)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommand(CliGitAPIImpl.java:1981)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.launchCommand(CliGitAPIImpl.java:1993)
	at org.jenkinsci.plugins.gitclient.CliGitAPIImpl.setRemoteUrl(CliGitAPIImpl.java:1601)
	at hudson.plugins.git.GitAPI.setRemoteUrl(GitAPI.java:161)
	at hudson.plugins.git.GitSCM.fetchFrom(GitSCM.java:991)
	... 11 more
ERROR: Error fetching remote repo 'origin'
Finished: FAILURE

Thanks in advance!

This might seem obvious, but are you sure that you are in the correct directory?
Did you do at “dir .” in your workspace to ensure that the “.git” subfolder exist, and that it, in fact, is a git directory you are currently in?

So my workspace has the .git folder, but nothing else in it, which I assumed would be the expected state since I’m unable to fetch the changes from the remote repository?

The workspace used for checkout seems to be different from your custom workspace.

And I am not sure if it will work that way easily.
The multibranch jobs scans the remote repo, then does checkout to get the jenkinsfile (in a temp workspace) , and then would switch to the real workspace . There a new checkout is needed (a checkout: scm step)

I recommend to first get it running without a custom workdir

As @bpedersen2, I was also wondering as to why there is no “checkout scm”-step either.

Do some basic verification, to help you along:

sh('pwd') // Where am I?
sh('git status') // What is the current situation of the local repository?
sh('git remote -v') // What is the remote (upstream) repository?

You don’t need to checkout for declarative (pipeline {}) jobs. It does it automatically

But does this handle switching to a custom workspace?

These seem different. I I think especially the multibranch pipelines will always create the initial checkout in the default workspace( as they need a workspace per branch anyway)