Answers: <p><code>git.exe rev-parse --resolve-git-dir C:\workspace\.git # timeout=10:</code> This command checks if the current directory is a Git repository. This is an initial sanity check.</p>
  <p><code>git.exe config remote.origin.url https://github/repo.git # timeout=10:</code> This command sets the URL for the remote repository where your code is located.</p>
  <p><code>git.exe rev-parse --verify HEAD # timeout=10:</code> This command is verifying the currently checked-out commit.</p>
  <p><code>git.exe reset --hard # timeout=10:</code> This command resets the workspace to match the HEAD commit.</p>
  <p><code>git.exe clean -ffdx # timeout=10:</code> This command removes untracked files from the workspace.</p>
  <p><code>git.exe --version # timeout=10</code> and <code>git --version #</code> 'git version 2.36.0.windows.1': These commands display the git version.</p>
  <p><code>git.exe fetch --tags --force --progress --depth=1 -- https://github/repot.git +refs/heads/*:refs/remotes/origin/* # timeout=10:</code> This command fetches the changes from the remote repository, limiting the depth of the history to 1 commit which is helpful for saving time and space.</p>
  <p><code>git.exe rev-parse &quot;refs/remotes/origin/branch^{commit}&quot; # timeout=10:</code> This command is checking out the exact commit in the branch &quot;branch&quot;.</p>
  <p><code>git.exe config core.sparsecheckout # timeout=10:</code> This command checks if sparse checkout is enabled, which would mean only certain specified directories are checked out instead of the whole repository.</p>
  <p><code>git.exe checkout -f 1fb75f0e6daf5********0db829b97b9bee3</code> # timeout=2000: This command checks out the specified commit.</p>
  <p><code>git.exe config --get remote.origin.url # timeout=10:</code> This command gets the remote URL of the repository.</p>
  
Answers: CC BY-SA 4.0
Answers: 2023-07-10T08:58:25.287Z
Answers: 2023-07-10T08:58:25.287Z
Answers: Narek Hambardzumyan
Body: <p>When I execute my pipeline and I go and see on the actual Jenkins slave, the checked out commit doesn't have latest changes. But the logs and actual files in the workspace on the Jenkins slave running this build are confusing me.</p>
  <p>In the logs Jenkins shows it is resolving commit id for the previous commit on the branch (notice the carrot at the end):</p>
  <pre><code>/usr/bin/git rev-parse refs/remotes/origin/BranchName^
  </code></pre>
  <p>but in a log line after this it shows a fetch command with correct latest commit id and latest commit message.</p>
  <pre><code>/usr/bin/git checkout -f 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  Commit message: &quot;Latest commit message&quot;
  </code></pre>
  <p><strong>I HAVE</strong></p>
  <pre><code>always { 
              cleanWs()
          } 
  </code></pre>
  <p>in the post stage <strong>SO THIS IS NOT WORKSPACE CLEAN UP ISSUE.</strong> Workspace is getting cleaned after every build I checked it in logs and also on the server.</p>
  <p>Other thing that I did is, when build was triggered I did SSH into the Jenkins slave machine where build was running and checked the files in actual workspace but the files were old and the head was is detached state pointing to the correct latest commit. As mentioned above the log was showing Jenkins executed git -f checkout . (Full log is provided below)</p>
  <p>Why the git and checkout steps in the Jenkins pipeline take the code from the repository this way?</p>
  <p>I want to understand why this plugin does all these steps in the log below, why can't it just clone new repo, pull a latest commit using reference and that's it.</p>
  <p>I have following step in my declarative pipeline:</p>
  <pre><code>dir(&quot;${branch_name}/somedir&quot;){
                      checkout(
                          [
                              $class: 'GitSCM', 
                              branches: [[name: 'refs/heads/${branch_name}']], 
                              doGenerateSubmoduleConfigurations: false, 
                              extensions: [], submoduleCfg: [], 
                              userRemoteConfigs: [
                                  [
                                  credentialsId: 'XXXXXX',
                                  name: 'origin', 
                                  refspec: '+refs/heads/${branch_name}:refs/remotes/origin/${branch_name}', 
                                  url: 'https://github.com/xyz/repo.git'
                                  ]
                              ]
                          ])
                  }
  </code></pre>
  <p>And in the logs I see following:</p>
  <pre><code>    Cloning the remote Git repository
  Cloning repository https://github.com/xyz/repo.git
   &gt; /usr/bin/git init /pathToWorkspace/somedir # timeout=10
  Fetching upstream changes from https://github.com/xyz/repo.git
   &gt; /usr/bin/git --version # timeout=10
   &gt; git --version # 'git version 2.23.4'
  using GIT_ASKPASS to set credentials Used to pull the code from GitHub as JenkinsUser user
   &gt; /usr/bin/git fetch --tags --force --progress -- https://github.com/xyz/repo.git +refs/heads/*:refs/remotes/origin/* # timeout=10
  Checking out Revision 25d8dd262b61a8f703912db297kuhg76768 (refs/remotes/origin/BranchName)
   &gt; /usr/bin/git config remote.origin.url https://github.com/xyz/repo.git # timeout=10
   &gt; /usr/bin/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
   &gt; /usr/bin/git config remote.origin.url https://github.com/xyz/repo.git # timeout=10
  Fetching upstream changes from https://github.com/xyz/repo.git
  using GIT_ASKPASS to set credentials Used to pull the code from GitHub as JenkinsUser user
   &gt; /usr/bin/git fetch --tags --force --progress -- https://github.com/xyz/repo.git +refs/heads/BranchName:refs/remotes/origin/BranchName # timeout=10
   &gt; /usr/bin/git rev-parse refs/remotes/origin/BranchName^{commit} # timeout=10
   &gt; /usr/bin/git rev-parse refs/remotes/origin/refs/heads/BranchName^{commit} # timeout=10
   &gt; /usr/bin/git config core.sparsecheckout # timeout=10
   &gt; /usr/bin/git checkout -f 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  Commit message: &quot;Latest commit message&quot;
   &gt; /usr/bin/git rev-list --no-walk 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  </code></pre>
  
Comments: CC BY-SA 4.0
Comments: 2022-08-02T13:34:14.833Z
Comments: Set `branches` to `[[name: branch_name]]` and for `userRemoteConfigs` remove the `name` and `refspec` keys. Then re-run your build and see if it happens again.
Comments: Levi
Comments: CC BY-SA 4.0
Comments: 2022-08-06T05:58:14.287Z
Comments: [gitSCM logic](https://github.com/jenkinsci/git-plugin/blob/master/src/main/java/hudson/plugins/git/extensions/GitSCMExtension.java). The git plugin also flips between git and jgit based on [optimized performance](https://www.jenkins.io/blog/2020/08/29/git-performance-improvement-phase3/)
Comments: Ian W
Tags: <jenkins><jenkins-pipeline><git><jenkins-plugins><github>
Title: Jenkins checkout GitSCM and git step how does it work internally and why
UserDisplayName: Akshay Hiremath
ThreadText: # Jenkins checkout GitSCM and git step how does it work internally and why
  
  (Asked by: username_0 on 2022-06-16)
  
  When I execute my pipeline and I go and see on the actual Jenkins slave, the checked out commit doesn't have latest changes. But the logs and actual files in the workspace on the Jenkins slave running this build are confusing me.
  
  In the logs Jenkins shows it is resolving commit id for the previous commit on the branch (notice the carrot at the end):
  
  ```
  /usr/bin/git rev-parse refs/remotes/origin/BranchName^
  
  ```
  
  but in a log line after this it shows a fetch command with correct latest commit id and latest commit message.
  
  ```
  /usr/bin/git checkout -f 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  Commit message: "Latest commit message"
  
  ```
  
  **I HAVE**
  
  ```
  always { 
              cleanWs()
          } 
  
  ```
  
  in the post stage **SO THIS IS NOT WORKSPACE CLEAN UP ISSUE.** Workspace is getting cleaned after every build I checked it in logs and also on the server.
  
  Other thing that I did is, when build was triggered I did SSH into the Jenkins slave machine where build was running and checked the files in actual workspace but the files were old and the head was is detached state pointing to the correct latest commit. As mentioned above the log was showing Jenkins executed git -f checkout . (Full log is provided below)
  
  Why the git and checkout steps in the Jenkins pipeline take the code from the repository this way?
  
  I want to understand why this plugin does all these steps in the log below, why can't it just clone new repo, pull a latest commit using reference and that's it.
  
  I have following step in my declarative pipeline:
  
  ```
  dir("${branch_name}/somedir"){
                      checkout(
                          [
                              $class: 'GitSCM', 
                              branches: [[name: 'refs/heads/${branch_name}']], 
                              doGenerateSubmoduleConfigurations: false, 
                              extensions: [], submoduleCfg: [], 
                              userRemoteConfigs: [
                                  [
                                  credentialsId: 'XXXXXX',
                                  name: 'origin', 
                                  refspec: '+refs/heads/${branch_name}:refs/remotes/origin/${branch_name}', 
                                  url: 'https://github.com/xyz/repo.git'
                                  ]
                              ]
                          ])
                  }
  
  ```
  
  And in the logs I see following:
  
  ```
      Cloning the remote Git repository
  Cloning repository https://github.com/xyz/repo.git
   > /usr/bin/git init /pathToWorkspace/somedir # timeout=10
  Fetching upstream changes from https://github.com/xyz/repo.git
   > /usr/bin/git --version # timeout=10
   > git --version # 'git version 2.23.4'
  using GIT_ASKPASS to set credentials Used to pull the code from GitHub as JenkinsUser user
   > /usr/bin/git fetch --tags --force --progress -- https://github.com/xyz/repo.git +refs/heads/*:refs/remotes/origin/* # timeout=10
  Checking out Revision 25d8dd262b61a8f703912db297kuhg76768 (refs/remotes/origin/BranchName)
   > /usr/bin/git config remote.origin.url https://github.com/xyz/repo.git # timeout=10
   > /usr/bin/git config --add remote.origin.fetch +refs/heads/*:refs/remotes/origin/* # timeout=10
   > /usr/bin/git config remote.origin.url https://github.com/xyz/repo.git # timeout=10
  Fetching upstream changes from https://github.com/xyz/repo.git
  using GIT_ASKPASS to set credentials Used to pull the code from GitHub as JenkinsUser user
   > /usr/bin/git fetch --tags --force --progress -- https://github.com/xyz/repo.git +refs/heads/BranchName:refs/remotes/origin/BranchName # timeout=10
   > /usr/bin/git rev-parse refs/remotes/origin/BranchName^{commit} # timeout=10
   > /usr/bin/git rev-parse refs/remotes/origin/refs/heads/BranchName^{commit} # timeout=10
   > /usr/bin/git config core.sparsecheckout # timeout=10
   > /usr/bin/git checkout -f 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  Commit message: "Latest commit message"
   > /usr/bin/git rev-list --no-walk 25d8dd262b61a8f703912db297kuhg76768 # timeout=10
  
  ```
  
  **Tags:** jenkins, jenkins-pipeline, git, jenkins-plugins, github
  
  > **Comments:**
  > **username_1**: Set `branches` to `[[name: branch_name]]` and for `userRemoteConfigs` remove the `name` and `refspec` keys. Then re-run your build and see if it happens again.  
  > **username_2**: [gitSCM logic](https://github.com/jenkinsci/git-plugin/blob/master/src/main/java/hudson/plugins/git/extensions/GitSCMExtension.java). The git plugin also flips between git and jgit based on [optimized performance](https://www.jenkins.io/blog/2020/08/29/git-performance-improvement-phase3/)  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_3 on 2023-07-10. Score: 0
  
  `git.exe rev-parse --resolve-git-dir C:\workspace\.git # timeout=10:` This command checks if the current directory is a Git repository. This is an initial sanity check.
  
  `git.exe config remote.origin.url https://github/repo.git # timeout=10:` This command sets the URL for the remote repository where your code is located.
  
  `git.exe rev-parse --verify HEAD # timeout=10:` This command is verifying the currently checked-out commit.
  
  `git.exe reset --hard # timeout=10:` This command resets the workspace to match the HEAD commit.
  
  `git.exe clean -ffdx # timeout=10:` This command removes untracked files from the workspace.
  
  `git.exe --version # timeout=10` and `git --version #` 'git version 2.36.0.windows.1': These commands display the git version.
  
  `git.exe fetch --tags --force --progress --depth=1 -- https://github/repot.git +refs/heads/*:refs/remotes/origin/* # timeout=10:` This command fetches the changes from the remote repository, limiting the depth of the history to 1 commit which is helpful for saving time and space.
  
  `git.exe rev-parse "refs/remotes/origin/branch^{commit}" # timeout=10:` This command is checking out the exact commit in the branch "branch".
  
  `git.exe config core.sparsecheckout # timeout=10:` This command checks if sparse checkout is enabled, which would mean only certain specified directories are checked out instead of the whole repository.
  
  `git.exe checkout -f 1fb75f0e6daf5********0db829b97b9bee3` # timeout=2000: This command checks out the specified commit.
  
  `git.exe config --get remote.origin.url # timeout=10:` This command gets the remote URL of the repository.
  
  
  ---
  
  