Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-54612

Reference repo not used for Git clones on Windows SSH agents

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Critical Critical
    • git-plugin
    • Jenkins 2.138.2
      Git Plugin 3.9.1
      Windows 2012r2
      Cygwin Git 2.17.0

      We use a reference repo on all our agents to speed up our clones. This seems to work on all agents we have except for our Windows nodes. I first noticed that the fetch times were slower on the Windows nodes. I then confirmed by checking the size of the .git folder on each machine after the clone. All non-windows nodes were 11MB whereas the .git folder on Windows was 1.9GB.

      Our Windows agents are connected over ssh (Cygwin). The Remote Root is on C:\ (windows style path) and the reference repository is also on C:\. We use the Checkout/SCM pipeline step in order to take advantage of extra options not available using the Git step.

      This is a simplified snippet of what we use I pulled from the Syntax generator.

      checkout([
           $class: 'GitSCM',
           branches: [[name: '$BRANCH']],
           doGenerateSubmoduleConfigurations: false,
           extensions: [[$class: 'CloneOption',
               depth: 0,
               noTags: false,
               reference: '$REFERENCE_REPO',
               shallow: false]],
           gitTool: 'Default',
           submoduleCfg: [],
           userRemoteConfigs: [[url: '$REPO']]])
      

      The console output tries to convince me it's using the reference repo but it appears it isn't (3:20 to fetch).

      00:41:39.279 Cloning the remote Git repository
      00:41:39.355 Cloning repository https://github.com/***/***.git
      00:41:39.368  > git init C:\Users\jenkins\workspace\Build # timeout=10
      00:41:39.574 Using reference repository: C:\repo_cache
      00:41:39.574 Fetching upstream changes from https://github.com/***/***.git
      00:41:39.574  > git --version # timeout=10
      00:41:39.606  > git fetch --tags --progress https://github.com/***/***.git +refs/heads/*:refs/remotes/origin/* # timeout=30
      00:45:00.369  > git config remote.origin.url https://github.com/***/***.git # timeout=10
      00:45:00.431  > git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
      00:45:00.603  > git config remote.origin.url https://github.com/***/***.git # timeout=10
      00:45:00.775 Fetching upstream changes from https://github.com/***/***.git
      00:45:00.776  > git fetch --tags --progress https://github.com/***/***.git +refs/heads/*:refs/remotes/origin/* # timeout=30
      00:45:02.416  > git rev-parse "origin/master^{commit}" # timeout=10
      00:45:02.448 Checking out Revision *** (origin/master)
      00:45:02.588  > git config core.sparsecheckout # timeout=10
      00:45:02.619  > git checkout -f *** # timeout=30
      00:46:45.479 Commit message: "Merge pull request #63 from ***/***"
      

      I've tried various things like using Windows Git to populate the reference repo, using a Jenkins git step to populate the repo, using cygwin style paths for both the ref repo location and/or the remote root dir for the agent. Not sure what else I can try but I assume its going to be something related to windows vs cygwin vs path styles vs line-endings.

       

      Edit: I can use an sh step to clone using the ref repo successfully.

          [JENKINS-54612] Reference repo not used for Git clones on Windows SSH agents

          dheeraj reddy added a comment -

          I am also facing the exact issue(same environment also) while using git plugin (either as pipeline code or freestyle job).

          Using cmd  or sh script I am able to clone it utilizing reference repo. 

          May I know is there any bug on the git plugin ??

          dheeraj reddy added a comment - I am also facing the exact issue(same environment also) while using git plugin (either as pipeline code or freestyle job). Using cmd  or sh script I am able to clone it utilizing reference repo.  May I know is there any bug on the git plugin ??

          Timor Raiman added a comment -

          I'm seeing this with the pipeline only. (freestyle works).

           

          Timor Raiman added a comment - I'm seeing this with the pipeline only. (freestyle works).  

          I am seeing a similar problem, but with ubuntu agents.
          It works with freestyle, but on declarative pipeline it doesn't work. It does not even try to load the reference repo for me.

          Vincenzo Melandri added a comment - I am seeing a similar problem, but with ubuntu agents. It works with freestyle, but on declarative pipeline it doesn't work. It does not even try to load the reference repo for me.

          Tim Patterson added a comment -

          I thought it wasn't working on my PC (running Windows) until I noticed that there is a file `.git/objects/info/alternates` in each of the repos that have a reference repository set in Jenkins. The `alternates` file points to the reference repository... The resulting `.git/objects/pack` folders are smaller, but still not empty even with a very up-to-date reference repository. The resulting full clones are a fair bit faster, though - from 37 minutes to 24 minutes.

          Tim Patterson added a comment - I thought it wasn't working on my PC (running Windows) until I noticed that there is a file `.git/objects/info/alternates` in each of the repos that have a reference repository set in Jenkins. The `alternates` file points to the reference repository... The resulting `.git/objects/pack` folders are smaller, but still not empty even with a very up-to-date reference repository. The resulting full clones are a fair bit faster, though - from 37 minutes to 24 minutes.

          Maciej Sitarz added a comment - - edited

          I managed to work around this problem and instead of calling `checkout scm` I run a modified version, but also preserving the prameters set from the pipeline settings:

           

          def userRemoteConfig = scm.getUserRemoteConfigs()[0]
          def repoMirrorDir = scm.extensions[0].reference
          def newUserRemoteConfig = new hudson.plugins.git.UserRemoteConfig(repoMirrorDir, userRemoteConfig.getName(), userRemoteConfig.getRefspec(), userRemoteConfig.getCredentialsId())
          checkout([
              $class: 'GitSCM',
              branches: scm.branches,
              doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,
              extensions: scm.extensions,
              userRemoteConfigs: [ newUserRemoteConfig ]
          ])
          

          EDIT:
          After further testing it seems that all is fine, the above workaround is not needed. `git fetch` properly gets the objects from the reference repository, not from remote.

          Maciej Sitarz added a comment - - edited I managed to work around this problem and instead of calling `checkout scm` I run a modified version, but also preserving the prameters set from the pipeline settings:   def userRemoteConfig = scm.getUserRemoteConfigs()[0] def repoMirrorDir = scm.extensions[0].reference def newUserRemoteConfig = new hudson.plugins.git.UserRemoteConfig(repoMirrorDir, userRemoteConfig.getName(), userRemoteConfig.getRefspec(), userRemoteConfig.getCredentialsId()) checkout([     $class: 'GitSCM' ,     branches: scm.branches,     doGenerateSubmoduleConfigurations: scm.doGenerateSubmoduleConfigurations,     extensions: scm.extensions,   userRemoteConfigs: [ newUserRemoteConfig ] ]) EDIT: After further testing it seems that all is fine, the above workaround is not needed. `git fetch` properly gets the objects from the reference repository, not from remote.

            Unassigned Unassigned
            broussar Adam Brousseau
            Votes:
            6 Vote for this issue
            Watchers:
            12 Start watching this issue

              Created:
              Updated: