Maven SCM
  1. Maven SCM
  2. SCM-667

mvn release:prepare fails for hierarchical multi-module project on Windows 7 using msysgit with "is outside repository"

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.6
    • Fix Version/s: 1.7
    • Component/s: maven-scm-provider-git
    • Labels:
      None
    • Environment:
    • Complexity:
      Intermediate
    • Number of attachments :
      3

      Description

      Steps to reproduce (provided Maven, Java and Git are installed on your Windows-Machine):

      1. Run:
        git clone git://github.com/1and1/testlink-junit.git testlink-junit2
        cd testlink-junit2
        mvn -DpushChanges=false -e -B release:prepare
        

      Console output:

      [INFO] Checking in modified POMs...
      [INFO] Executing: cmd.exe /X /C "git add -- pom.xml C:\ws\testlink-junit2\tljunit-surefire\pom.xml C:\ws\testlink-junit2\tljunit-eclipse\pom.xml"
      [INFO] Working directory: c:\ws\testlink-junit2
      [INFO] ------------------------------------------------------------------------
      [INFO] Reactor Summary:
      [INFO]
      [INFO] tljunit parent .................................... FAILURE [22.561s]
      [INFO] tljunit surefire RunListeners ..................... SKIPPED
      [INFO] tljunit sample project for running tests from eclipse.  SKIPPED
      [INFO] ------------------------------------------------------------------------
      [INFO] BUILD FAILURE
      [INFO] ------------------------------------------------------------------------
      [INFO] Total time: 24.879s
      [INFO] Finished at: Wed Feb 29 17:58:15 CET 2012
      [INFO] Final Memory: 13M/177M
      [INFO] ------------------------------------------------------------------------
      [ERROR] Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.2.2:prepare (default-cli) on project tljunit-parent: Unable to commit files
      [ERROR] Provider message:
      [ERROR] The git-add command failed.
      [ERROR] Command output:
      [ERROR] fatal: 'C:\ws\testlink-junit2\tljunit-surefire\pom.xml' is outside repository
      [ERROR] -> [Help 1]
      org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-release-plugin:2.2.2:prepare (default-cli) on project tljunit-parent: Unable to commit files
      Provider message:
      The git-add command failed.
      Command output:
      fatal: 'C:\ws\testlink-junit2\tljunit-surefire\pom.xml' is outside repository
      
              at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
              at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
              at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
              at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
              at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
              at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
              at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
              at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
              at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
              at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
              at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
              at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
              at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
              at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
              at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
              at java.lang.reflect.Method.invoke(Method.java:597)
              at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
              at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
              at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
              at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
      Caused by: org.apache.maven.plugin.MojoFailureException: Unable to commit files
      Provider message:
      The git-add command failed.
      Command output:
      fatal: 'C:\ws\testlink-junit2\tljunit-surefire\pom.xml' is outside repository
      
              at org.apache.maven.plugins.release.PrepareReleaseMojo.prepareRelease(PrepareReleaseMojo.java:310)
              at org.apache.maven.plugins.release.PrepareReleaseMojo.execute(PrepareReleaseMojo.java:258)
              at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
              at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
              ... 19 more
      Caused by: org.apache.maven.shared.release.scm.ReleaseScmCommandException: Unable to commit files
      Provider message:
      The git-add command failed.
      Command output:
      fatal: 'C:\ws\testlink-junit2\tljunit-surefire\pom.xml' is outside repository
      
              at org.apache.maven.shared.release.phase.AbstractScmCommitPhase.checkin(AbstractScmCommitPhase.java:168)
              at org.apache.maven.shared.release.phase.AbstractScmCommitPhase.performCheckins(AbstractScmCommitPhase.java:148)
              at org.apache.maven.shared.release.phase.ScmCommitPreparationPhase.runLogic(ScmCommitPreparationPhase.java:75)
              at org.apache.maven.shared.release.phase.AbstractScmCommitPhase.execute(AbstractScmCommitPhase.java:79)
              at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:206)
              at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:142)
              at org.apache.maven.shared.release.DefaultReleaseManager.prepare(DefaultReleaseManager.java:104)
              at org.apache.maven.plugins.release.PrepareReleaseMojo.prepareRelease(PrepareReleaseMojo.java:302)
              ... 22 more
      [ERROR]
      [ERROR] Re-run Maven using the -X switch to enable full debug logging.
      [ERROR]
      [ERROR] For more information about the errors and possible solutions, please read the following articles:
      [ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
      
      1. SCM-667.patch
        3 kB
        Mirko Friedenhagen
      2. SCM-667-with-test.patch
        6 kB
        Mirko Friedenhagen
      3. SCM-667-with-test-svn-format.patch
        6 kB
        Mirko Friedenhagen

        Issue Links

          Activity

          Hide
          Mirko Friedenhagen added a comment -

          Executing:

          • git add – pom.xml tljunit-surefire\pom.xml tljunit-eclipse\pom.xml instead of
          • git add – pom.xml C:\ws\testlink-junit2\tljunit-surefire\pom.xml C:\ws\testlink-junit2\tljunit-eclipse\pom.xml does work so the "basedir" should probably just be skipped.
          Show
          Mirko Friedenhagen added a comment - Executing: git add – pom.xml tljunit-surefire\pom.xml tljunit-eclipse\pom.xml instead of git add – pom.xml C:\ws\testlink-junit2\tljunit-surefire\pom.xml C:\ws\testlink-junit2\tljunit-eclipse\pom.xml does work so the "basedir" should probably just be skipped.
          Hide
          Mirko Friedenhagen added a comment -

          Hello,

          as can be seen in the traceback as well this seems to be a problem with upper and lower case of the drive letter. I checked out the release trunk and added some logging output to maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractScmCommitPhase.java@1295468 in performCheckins. Now I get:

          [INFO] reactorProjects=[MavenProject: net.oneandone.testlinkjunit:tljunit-parent:3.0.2-SNAPSHOT @ c:\ws\testlink-junit2\pom.xml, MavenProject: net.oneandone.testlinkjunit:tljunit-surefire:3.0.2-SNAPSHOT @ C:\ws\testlink-junit2\tljunit-surefire\pom.xml, MavenProject: net.oneandone.testlinkjunit:tljunit-eclipse:3.0.2-SNAPSHOT @ C:\ws\testlink-junit2\tljunit-eclipse\pom.xml]
          [INFO] pomFiles=[c:\ws\testlink-junit2\pom.xml, C:\ws\testlink-junit2\tljunit-surefire\pom.xml, C:\ws\testlink-junit2\tljunit-eclipse\pom.xml]
          [INFO] workingDirectoryAsString=c:\ws\testlink-junit2
          [INFO] workingDirectoryAsFile.getAbsolutePath()=c:\ws\testlink-junit2
          [INFO] Executing: cmd.exe /X /C "git add -- pom.xml C:\ws\testlink-junit2\tljunit-surefire\pom.xml C:\ws\testlink-junit2\tljunit-eclipse\pom.xml"
          

          As can be seen, the drive letter of the "main" reactor project (and it's POM) is lowercase, while the module poms come with an uppercase drive letter. This will break the correct stripping of the basedir later on in org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils.addTarget(Commandline cl, List<File> files)

          So maybe this could even be considered a bug in maven-core (or whoever collects the reactor projects) or maven-scm-provider-gitexe as it implements comparison using strings, see http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java?revision=1241330&view=markup line 46ff. .

          Show
          Mirko Friedenhagen added a comment - Hello, as can be seen in the traceback as well this seems to be a problem with upper and lower case of the drive letter. I checked out the release trunk and added some logging output to maven-release-manager/src/main/java/org/apache/maven/shared/release/phase/AbstractScmCommitPhase.java@1295468 in performCheckins . Now I get: [INFO] reactorProjects=[MavenProject: net.oneandone.testlinkjunit:tljunit-parent:3.0.2-SNAPSHOT @ c:\ws\testlink-junit2\pom.xml, MavenProject: net.oneandone.testlinkjunit:tljunit-surefire:3.0.2-SNAPSHOT @ C:\ws\testlink-junit2\tljunit-surefire\pom.xml, MavenProject: net.oneandone.testlinkjunit:tljunit-eclipse:3.0.2-SNAPSHOT @ C:\ws\testlink-junit2\tljunit-eclipse\pom.xml] [INFO] pomFiles=[c:\ws\testlink-junit2\pom.xml, C:\ws\testlink-junit2\tljunit-surefire\pom.xml, C:\ws\testlink-junit2\tljunit-eclipse\pom.xml] [INFO] workingDirectoryAsString=c:\ws\testlink-junit2 [INFO] workingDirectoryAsFile.getAbsolutePath()=c:\ws\testlink-junit2 [INFO] Executing: cmd.exe /X /C "git add -- pom.xml C:\ws\testlink-junit2\tljunit-surefire\pom.xml C:\ws\testlink-junit2\tljunit-eclipse\pom.xml" As can be seen, the drive letter of the "main" reactor project (and it's POM) is lowercase, while the module poms come with an uppercase drive letter. This will break the correct stripping of the basedir later on in org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils.addTarget(Commandline cl, List<File> files) So maybe this could even be considered a bug in maven-core (or whoever collects the reactor projects) or maven-scm-provider-gitexe as it implements comparison using strings, see http://svn.apache.org/viewvc/maven/scm/trunk/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtils.java?revision=1241330&view=markup line 46ff. .
          Hide
          Mirko Friedenhagen added a comment -

          One simple solution would be to use File.getCanonicalPath() instead of File.getAbsolutePath() in maven-scm-provider-gitexe.

          Show
          Mirko Friedenhagen added a comment - One simple solution would be to use File.getCanonicalPath() instead of File.getAbsolutePath() in maven-scm-provider-gitexe .
          Hide
          Mirko Friedenhagen added a comment -

          An even better solution would probably look like this:

              static String addTarget(final File workingDir, final List<File> files) {
                  
                  try {
                      final URI wdURI = workingDir.getCanonicalFile().toURI();
                      final StringBuilder sb = new StringBuilder();
                      for (final File f : files) {
                          final String relativeFile = wdURI.relativize(f.getCanonicalFile().toURI()).getPath();
                          sb.append(" ").append(relativeFile);
                      }
                      return String.valueOf(sb);
                  } catch (IOException ex) {
                      throw new IllegalArgumentException("arg", ex);
                  }
              }
          

          I will hopefully give it a try this evening and submit a patch.

          Show
          Mirko Friedenhagen added a comment - An even better solution would probably look like this: static String addTarget( final File workingDir, final List<File> files) { try { final URI wdURI = workingDir.getCanonicalFile().toURI(); final StringBuilder sb = new StringBuilder(); for ( final File f : files) { final String relativeFile = wdURI.relativize(f.getCanonicalFile().toURI()).getPath(); sb.append( " " ).append(relativeFile); } return String .valueOf(sb); } catch (IOException ex) { throw new IllegalArgumentException( "arg" , ex); } } I will hopefully give it a try this evening and submit a patch.
          Hide
          Mirko Friedenhagen added a comment -

          Patch against https://svn.apache.org/repos/asf/maven/scm/trunk@1294391 which will use canonicalFile. URI solution did not work for files outside of working directory.
          All unit tests pass.

          Show
          Mirko Friedenhagen added a comment - Patch against https://svn.apache.org/repos/asf/maven/scm/trunk@1294391 which will use canonicalFile. URI solution did not work for files outside of working directory. All unit tests pass.
          Hide
          Robert Scholte added a comment -

          Using the canonicalPath was also one of my first thought, but it has one downside: you must catch its IOException.

          Than again: why compare String}}s? I'd hoped we had learned from {{Date and Integer that you should try to compare their toString()-values. So I was thinking of adding a method isAncestor(), which should loop over every file.parentFile() and checks if it is equal to the workingDirectory. Let the OS do this comparison.
          See also File.equals()

          Are you really sure you can't use URI.relativize()? That would be a real clean solution.

          Btw, it's a public method, so it's quite easy to test. In other words: we'll need some extra tests here. I'm not sure if you can use a Windows-path on a Linux environment, otherwise we'll just have to check the OS first.

          Show
          Robert Scholte added a comment - Using the canonicalPath was also one of my first thought, but it has one downside: you must catch its IOException . Than again: why compare String}}s? I'd hoped we had learned from {{Date and Integer that you should try to compare their toString() -values. So I was thinking of adding a method isAncestor() , which should loop over every file.parentFile() and checks if it is equal to the workingDirectory . Let the OS do this comparison. See also File.equals() Are you really sure you can't use URI.relativize() ? That would be a real clean solution. Btw, it's a public method, so it's quite easy to test. In other words: we'll need some extra tests here. I'm not sure if you can use a Windows-path on a Linux environment, otherwise we'll just have to check the OS first.
          Hide
          Mirko Friedenhagen added a comment - - edited

          Hello Robert,

          • I agree using String compare feels like a hack. On the other side, rethrowing the IOException as IllegalArgumentException is IMO a clean solution in this case, I do not think it should come to this.
          • Using canonicalPath is platform agnostic as well, it will deliver a Linux path on Linux, a MacOSX path on MacOSX and a Windows path on Windows.
          • Tests are running successfully on Mac OS X (you have to trust me on this one ) and on Linux (http://huschteguzzel.de/hudson/job/maven-scm/4/) as well.
          • I use a fork BTW (https://github.com/mfriedenhagen/maven-scm), I will give it a shot to get a working solution using URI or isAncestor this weekend.
          • BTW: the URI solution has to use canonicalFile nonetheless, so the IOException has to be handled anyway.

          Regards
          Mirko

          Show
          Mirko Friedenhagen added a comment - - edited Hello Robert, I agree using String compare feels like a hack. On the other side, rethrowing the IOException as IllegalArgumentException is IMO a clean solution in this case, I do not think it should come to this. Using canonicalPath is platform agnostic as well, it will deliver a Linux path on Linux, a MacOSX path on MacOSX and a Windows path on Windows. Tests are running successfully on Mac OS X (you have to trust me on this one ) and on Linux ( http://huschteguzzel.de/hudson/job/maven-scm/4/ ) as well. I use a fork BTW ( https://github.com/mfriedenhagen/maven-scm ), I will give it a shot to get a working solution using URI or isAncestor this weekend. BTW: the URI solution has to use canonicalFile nonetheless, so the IOException has to be handled anyway. Regards Mirko
          Hide
          Mirko Friedenhagen added a comment -

          Hello Robert,

          • I did try a solution with isAncestor but it looks very clumsy and I needed canonical nonetheless to normalize the drive letter.
          • This second patch at least adds a unit test. Note that I was not able to let the test run on Windows as I am not in the office (and am off for one week for holidays).
          • On Mac OS X and Linux (http://huschteguzzel.de/hudson/job/maven-scm/5/) the tests run successfully.

          Regards
          Mirko

          Show
          Mirko Friedenhagen added a comment - Hello Robert, I did try a solution with isAncestor but it looks very clumsy and I needed canonical nonetheless to normalize the drive letter. This second patch at least adds a unit test. Note that I was not able to let the test run on Windows as I am not in the office (and am off for one week for holidays). On Mac OS X and Linux ( http://huschteguzzel.de/hudson/job/maven-scm/5/ ) the tests run successfully. Regards Mirko
          Hide
          Robert Scholte added a comment -

          Mirko, this seems to be a gif-diff. Could you attach a svn-diff?

          Show
          Robert Scholte added a comment - Mirko, this seems to be a gif-diff. Could you attach a svn-diff?
          Hide
          Mirko Friedenhagen added a comment -

          Hello Robert,

          a svn-diff for the git-provider . I checked out https://svn.apache.org/repos/asf/maven/scm/trunk at revision 1303136, ran mvn clean install (on MacOSX) successfully and applied the git patch with:

          patch -p1 < SCM-667-with-test.patch
          

          Afterwards I ran:

          svn add maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsAddTargetTest.java
          

          , ran mvn clean install
          and now attach the outcome of svn diff.

          Regards
          Mirko

          Show
          Mirko Friedenhagen added a comment - Hello Robert, a svn-diff for the git-provider . I checked out https://svn.apache.org/repos/asf/maven/scm/trunk at revision 1303136, ran mvn clean install (on MacOSX) successfully and applied the git patch with: patch -p1 < SCM-667-with-test.patch Afterwards I ran: svn add maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/GitCommandLineUtilsAddTargetTest.java , ran mvn clean install and now attach the outcome of svn diff . Regards Mirko
          Hide
          Robert Scholte added a comment -

          Fixed in rev. 1303172
          Thanks!

          Show
          Robert Scholte added a comment - Fixed in rev. 1303172 Thanks!
          Hide
          Adrian Stabiszewski added a comment -

          This issue seems to be related to MRELEASE-581. I have installed this patch and it is working for me as well.

          Show
          Adrian Stabiszewski added a comment - This issue seems to be related to MRELEASE-581 . I have installed this patch and it is working for me as well.
          Hide
          Jiri Peinlich added a comment - - edited

          Hi, in our project we still faced this (or very similar) problem on version 1.7 of the plugin. We worked around the issue by being 100% sure, that the command promt is displaying the drive letter in upper case (C:\Workspace\myproject as opposed to c:\Workspace\myproject) before running mvn release:prepare. In case your letter is lowercase you can cd using full path using uppercase letter and the letter will be changed to uppercase.

          Show
          Jiri Peinlich added a comment - - edited Hi, in our project we still faced this (or very similar) problem on version 1.7 of the plugin. We worked around the issue by being 100% sure, that the command promt is displaying the drive letter in upper case (C:\Workspace\myproject as opposed to c:\Workspace\myproject) before running mvn release:prepare. In case your letter is lowercase you can cd using full path using uppercase letter and the letter will be changed to uppercase.

            People

            • Assignee:
              Robert Scholte
              Reporter:
              Mirko Friedenhagen
            • Votes:
              1 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: