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

git-plugin: rev-parse dereferencing tags breaks on Windows

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: Major Major
    • git-plugin
    • None
    • Windows 2008 R2 slave launched with cygwin ssh, cygwin git

      The change to GitAPI.java in commit 13f6038acc4fa5b5a62413155da6fc8cfcad3fe0 seems to break the git plugin for Windows, at least in some circumstances. The syntax rev^

      {commit} gets mangled by cmd because ^ is a quote character. This means that cmd passes rev{commit}

      to git, which as a cygwin executable being run from Windows, further tries to do wildcard expansion and maps this to revcommit. Putting "" around rev^

      {commit} empirically seems to work, though I haven't tried it in the git plugin itself.

      This C fragment:
      #include <stdio.h>
      int main(int argc, char* argv[])
      {
          int i;
          for (i = 0; i < argc; ++i)
          {
              printf("%s\n", argv[i]);
          }
          return 0;
      }
      


      when compiled with mingw to a native Windows application (a.exe) and invoked from cmd as a.exe a^{b} prints a{b}. When the same fragment is compiled with cygwin gcc to cygwin executable a.exe and is invoked the same way from cmd, it prints ab. Both print a^{b} when invoked from cmd as a.exe "a^{b}".

      I'm not sure what the fix is here other than perhaps detecting that this is windows and putting quotes around the argument in Windows.

      On another note, I left the Affects Version/s field blank. My Jenkins installation claims that it is using version 1.1.6. Looking at the git repo for the plugin, it appears that 1.1.6 should not have the ^{commit}

      fix, yet running strings on plugins/git/WEB-INF/classes/hudson/plugins/git/GitAPI.class clearly shows that my git plugin has that change in it.

          [JENKINS-13417] git-plugin: rev-parse dereferencing tags breaks on Windows

          In case anyone is searching for this, I should mention that this problem manifests itself as this error message in the build output:

          ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job.

          This is because the command "git rev-parse mastercommit" (in the case of the default, which is to use the master branch) is failing.

          Jay Berkenbilt added a comment - In case anyone is searching for this, I should mention that this problem manifests itself as this error message in the build output: ERROR: Couldn't find any revision to build. Verify the repository and branch configuration for this job. This is because the command "git rev-parse mastercommit" (in the case of the default, which is to use the master branch) is failing.

          Dan Savilonis added a comment -

          I can confirm I see this problem with git plugin 1.1.6 as well. I had to revert to 1.1.5 to unbreak our installation.

          Dan Savilonis added a comment - I can confirm I see this problem with git plugin 1.1.6 as well. I had to revert to 1.1.5 to unbreak our installation.

          Nick Floyd added a comment -

          Confirmed that this is an issue in git plugin v1.1.17; like @djs we reverted back to 1.1.15.

          Nick Floyd added a comment - Confirmed that this is an issue in git plugin v1.1.17; like @djs we reverted back to 1.1.15.

          The exact behavior of how rev^

          {commit}

          is interpreted seems to depend on several factors including whether git is invoked by explicit path or by being found in %PATH% and whether it is cygwin or not. For the case of git being invoked by explicit path, the ^ doesn't disappear. My workaround, for now, to avoid downgrading to 1.1.15, is to compile this C program:

          #include <stdio.h>
          #include <string.h>
          #include <stdlib.h>
          
          int needs_quotes(char* arg)
          {
              if (strchr(arg, ' ') ||
                  strchr(arg, '^') ||
                  strchr(arg, '[') ||
                  strchr(arg, ']') ||
                  strchr(arg, '{') ||
                  strchr(arg, '}') ||
                  strchr(arg, '*') ||
                  strchr(arg, '?'))
              {
                  return 1;
              }
              return 0;
          }
          
          int main(int argc, char* argv[])
          {
              int i;
              int cmdlen = 0;
              char* newcmd = 0;
              char* git = "C:\\cygwin\\bin\\git.exe";
          
              cmdlen += strlen(git) + 1;
          
              for (i = 1; i < argc; ++i)
              {
          	cmdlen += strlen(argv[i]) + 1;
                  if (needs_quotes(argv[i]))
                  {
          	    /* add characters for quotation marks */
          	    cmdlen += 2;
          	}
              }
          
              newcmd = malloc(cmdlen);
              strcpy(newcmd, git);
              for (i = 1; i < argc; ++i)
              {
          	strcat(newcmd, " ");
          	if (needs_quotes(argv[i]))
          	{
          	    strcat(newcmd, "\"");
          	    strcat(newcmd, argv[i]);
          	    strcat(newcmd, "\"");
          	}
          	else
          	{
          	    strcat(newcmd, argv[i]);
          	}
              }
              return system(newcmd);
          }
          

          to git-wrapper.exe using mingw (so it doesn't have any cygwin in it) and to install it in C:\cygwin\bin\git-wrapper.exe. Then I set up a git executable in the general Jenkins configuration called windows-git-wrapper with the executable as C:\cygwin\bin\git-wrapper.exe, and make that the git that I use in Windows jobs. That particular formula works fine for regular jobs tied to git as well as for building parameterized downstream jobs and passing the git commit through. All the above code does is put double quotes around arguments that have special characters in them.

          I'm not sure what the correct fix to the git plugin would be since it seems like it would have to detect too many things to know what it needs to do. However, perhaps putting double quotes around the argument to rev-parse may be sufficient for Windows and may probably be harmless, though I haven't tested it in under other conditions. Ultimately it seems like the code should work for both cygwin and non-cygwin git.exe both in %PATH% and executed by explicit path.

          Jay Berkenbilt added a comment - The exact behavior of how rev^ {commit} is interpreted seems to depend on several factors including whether git is invoked by explicit path or by being found in %PATH% and whether it is cygwin or not. For the case of git being invoked by explicit path, the ^ doesn't disappear. My workaround, for now, to avoid downgrading to 1.1.15, is to compile this C program: #include <stdio.h> #include <string.h> #include <stdlib.h> int needs_quotes( char * arg) { if (strchr(arg, ' ' ) || strchr(arg, '^' ) || strchr(arg, '[' ) || strchr(arg, ']' ) || strchr(arg, '{' ) || strchr(arg, '}' ) || strchr(arg, '*' ) || strchr(arg, '?' )) { return 1; } return 0; } int main( int argc, char * argv[]) { int i; int cmdlen = 0; char * newcmd = 0; char * git = "C:\\cygwin\\bin\\git.exe" ; cmdlen += strlen(git) + 1; for (i = 1; i < argc; ++i) { cmdlen += strlen(argv[i]) + 1; if (needs_quotes(argv[i])) { /* add characters for quotation marks */ cmdlen += 2; } } newcmd = malloc(cmdlen); strcpy(newcmd, git); for (i = 1; i < argc; ++i) { strcat(newcmd, " " ); if (needs_quotes(argv[i])) { strcat(newcmd, "\" "); strcat(newcmd, argv[i]); strcat(newcmd, "\" "); } else { strcat(newcmd, argv[i]); } } return system(newcmd); } to git-wrapper.exe using mingw (so it doesn't have any cygwin in it) and to install it in C:\cygwin\bin\git-wrapper.exe. Then I set up a git executable in the general Jenkins configuration called windows-git-wrapper with the executable as C:\cygwin\bin\git-wrapper.exe, and make that the git that I use in Windows jobs. That particular formula works fine for regular jobs tied to git as well as for building parameterized downstream jobs and passing the git commit through. All the above code does is put double quotes around arguments that have special characters in them. I'm not sure what the correct fix to the git plugin would be since it seems like it would have to detect too many things to know what it needs to do. However, perhaps putting double quotes around the argument to rev-parse may be sufficient for Windows and may probably be harmless, though I haven't tested it in under other conditions. Ultimately it seems like the code should work for both cygwin and non-cygwin git.exe both in %PATH% and executed by explicit path.

          chanti vlad added a comment -

          Problem confirmed using cygwin git on windows:

          • no problem for a manual git clone / checkout as a build step
          • "ERROR: Couldn't find any revision to build" using git plugin 1.1.18

          I downgraded to git plugin 1.1.15 (built from source for Jenkins 1.463) and this worked.

          chanti vlad added a comment - Problem confirmed using cygwin git on windows: no problem for a manual git clone / checkout as a build step "ERROR: Couldn't find any revision to build" using git plugin 1.1.18 I downgraded to git plugin 1.1.15 (built from source for Jenkins 1.463) and this worked.

          Same problem here - took me hours to find this...

          Workaround: Downloaded 1.1.15 from http://updates.jenkins-ci.org/download/plugins/git/, renamed to git.jpi, put into JENKINS_HOME/plugins, then restarted - works fine.

          Lars Corneliussen added a comment - Same problem here - took me hours to find this... Workaround: Downloaded 1.1.15 from http://updates.jenkins-ci.org/download/plugins/git/ , renamed to git.jpi, put into JENKINS_HOME/plugins, then restarted - works fine.

          Mark Waite added a comment -

          The Jenkins git plugin does not test with cygwin git and does not plan to add support for cygwin git.

          Git for Windows is well maintained and well supported and is known to work with the Jenkins git plugin.

          Mark Waite added a comment - The Jenkins git plugin does not test with cygwin git and does not plan to add support for cygwin git. Git for Windows is well maintained and well supported and is known to work with the Jenkins git plugin.

            Unassigned Unassigned
            jberkenbilt Jay Berkenbilt
            Votes:
            5 Vote for this issue
            Watchers:
            6 Start watching this issue

              Created:
              Updated:
              Resolved: