asfgit closed pull request #66: [SCM-868] fix gitexe cannot deduce relative path URL: https://github.com/apache/maven-scm/pull/66
This is a PR merged from a forked repository. As GitHub hides the original diff on merge, it is displayed below for the sake of provenance: As this is a foreign pull request (from a fork), the diff is supplied below (as it won't show otherwise due to GitHub magic): diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/add/GitAddCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/add/GitAddCommand.java index 21ad47607..00da32475 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/add/GitAddCommand.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/add/GitAddCommand.java @@ -69,31 +69,12 @@ protected ScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fi { return result; } - + // SCM-709: statusCommand uses repositoryRoot instead of workingDirectory, adjust it with relativeRepositoryPath - Commandline clRevparse = GitStatusCommand.createRevparseShowToplevelCommand( fileSet ); - - CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); - CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); + URI relativeRepositoryPath = GitStatusCommand.getRelativeCWD( this, fileSet ); - URI relativeRepositoryPath = null; - int exitCode; - - exitCode = GitCommandLineUtils.execute( clRevparse, stdout, stderr, getLogger() ); - if ( exitCode != 0 ) - { - // git-status returns non-zero if nothing to do - if ( getLogger().isInfoEnabled() ) - { - getLogger().info( "Could not resolve toplevel" ); - } - } - else - { - relativeRepositoryPath = - GitStatusConsumer.resolveURI( stdout.getOutput().trim(), fileSet.getBasedir().toURI() ); - } + CommandLineUtils.StringStreamConsumer stderr; // git-add doesn't show single files, but only summary :/ // so we must run git-status and consume the output diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java index 1766acabb..30d6c70ea 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommand.java @@ -121,27 +121,7 @@ protected CheckInScmResult executeCheckInCommand( ScmProviderRepository repo, Sc // SCM-709: statusCommand uses repositoryRoot instead of workingDirectory, adjust it with // relativeRepositoryPath - Commandline clRevparse = GitStatusCommand.createRevparseShowToplevelCommand( fileSet ); - - stdout = new CommandLineUtils.StringStreamConsumer(); - stderr = new CommandLineUtils.StringStreamConsumer(); - - URI relativeRepositoryPath = null; - - exitCode = GitCommandLineUtils.execute( clRevparse, stdout, stderr, getLogger() ); - if ( exitCode != 0 ) - { - // git-status returns non-zero if nothing to do - if ( getLogger().isInfoEnabled() ) - { - getLogger().info( "Could not resolve toplevel" ); - } - } - else - { - relativeRepositoryPath = - GitStatusConsumer.resolveURI( stdout.getOutput().trim(), fileSet.getBasedir().toURI() ); - } + URI relativeRepositoryPath = GitStatusCommand.getRelativeCWD( this, fileSet ); // git-commit doesn't show single files, but only summary :/ // so we must run git-status and consume the output diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusCommand.java index c6d8abacf..694f8628a 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusCommand.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusCommand.java @@ -23,6 +23,7 @@ import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFileSet; +import org.apache.maven.scm.command.AbstractCommand; import org.apache.maven.scm.command.status.AbstractStatusCommand; import org.apache.maven.scm.command.status.StatusScmResult; import org.apache.maven.scm.provider.ScmProviderRepository; @@ -44,29 +45,10 @@ protected StatusScmResult executeStatusCommand( ScmProviderRepository repo, ScmFileSet fileSet ) throws ScmException { - Commandline clRevparse = createRevparseShowToplevelCommand( fileSet ); - - CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); - CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); - - URI relativeRepositoryPath = null; - int exitCode; + CommandLineUtils.StringStreamConsumer stderr; - exitCode = GitCommandLineUtils.execute( clRevparse, stdout, stderr, getLogger() ); - if ( exitCode != 0 ) - { - // git-status returns non-zero if nothing to do - if ( getLogger().isInfoEnabled() ) - { - getLogger().info( "Could not resolve toplevel" ); - } - } - else - { - relativeRepositoryPath = - GitStatusConsumer.resolveURI( stdout.getOutput().trim(), fileSet.getBasedir().toURI() ); - } + URI relativeRepositoryPath = getRelativeCWD( this, fileSet ); Commandline cl = createCommandLine( (GitScmProviderRepository) repo, fileSet ); @@ -91,6 +73,40 @@ protected StatusScmResult executeStatusCommand( ScmProviderRepository repo, ScmF // // ---------------------------------------------------------------------- + /** + * Get the dir relative to the repository root. + * + * @param caller the caller command. + * @param fileSet in which subdir to execute. + * @return the relative URI. + * @throws ScmException if execute() fails. + */ + public static URI getRelativeCWD( AbstractCommand caller, ScmFileSet fileSet ) + throws ScmException + { + Commandline clRevparse = createRevparseShowPrefix( fileSet ); + + CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer(); + CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer(); + + URI relativeRepositoryPath = null; + + int exitCode = GitCommandLineUtils.execute( clRevparse, stdout, stderr, caller.getLogger() ); + if ( exitCode != 0 ) + { + // git-status returns non-zero if nothing to do + if ( caller.getLogger().isInfoEnabled() ) + { + caller.getLogger().info( "Could not resolve prefix" ); + } + } + else + { + relativeRepositoryPath = GitStatusConsumer.uriFromPath( stdout.getOutput().trim() ); + } + return relativeRepositoryPath; + } + public static Commandline createCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet ) { Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "status" ); @@ -98,10 +114,10 @@ public static Commandline createCommandLine( GitScmProviderRepository repository return cl; } - public static Commandline createRevparseShowToplevelCommand( ScmFileSet fileSet ) + public static Commandline createRevparseShowPrefix( ScmFileSet fileSet ) { Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "rev-parse" ); - cl.addArguments( new String[] { "--show-toplevel" } ); + cl.addArguments( new String[] { "--show-prefix" } ); return cl; } } diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumer.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumer.java index 7d850da80..8e06a4aaa 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumer.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumer.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.UnsupportedEncodingException; import java.net.URI; +import java.net.URISyntaxException; import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; @@ -98,7 +99,7 @@ public GitStatusConsumer( ScmLogger logger, File workingDirectory ) * @param workingDirectory the working directory * @param relativeRepositoryPath the working directory relative to the repository root * @since 1.9 - * @see GitStatusCommand#createRevparseShowToplevelCommand(org.apache.maven.scm.ScmFileSet) + * @see GitStatusCommand#createRevparseShowPrefix(org.apache.maven.scm.ScmFileSet) */ public GitStatusConsumer( ScmLogger logger, File workingDirectory, URI relativeRepositoryPath ) { @@ -211,15 +212,7 @@ else if ( status == ScmFileStatus.DELETED ) private boolean isFile( String file ) { - File targetFile; - if ( relativeRepositoryPath == null ) - { - targetFile = new File( workingDirectory, file ); - } - else - { - targetFile = new File( relativeRepositoryPath.getPath(), file ); - } + File targetFile = new File( workingDirectory, file ); return targetFile.isFile(); } @@ -248,9 +241,37 @@ public static URI resolveURI( String fileEntry, URI path ) // When using URI.create, spaces need to be escaped but not the slashes, so we can't use // URLEncoder.encode( String, String ) // new File( String ).toURI() results in an absolute URI while path is relative, so that can't be used either. - return path.relativize( URI.create( stripQuotes( fileEntry ).replace( " ", "%20" ) ) ); + return path.relativize( uriFromPath( stripQuotes ( fileEntry ) ) ); } + /** + * Create an URI whose getPath() returns the given path and getScheme() returns null. The path may contain spaces, + * colons, and other special characters. + * + * @param path the path. + * @return the new URI + */ + public static URI uriFromPath( String path ) + { + try + { + if ( path != null && path.indexOf( ':' ) != -1 ) + { + // prefixing the path so the part preceding the colon does not become the scheme + String tmp = new URI( null, null, "/x" + path, null ).toString().substring( 2 ); + // the colon is not escaped by default + return new URI( tmp.replace( ":", "%3A" ) ); + } + else + { + return new URI( null, null, path, null ); + } + } + catch ( URISyntaxException x ) + { + throw new IllegalArgumentException( x.getMessage(), x ); + } + } public List<ScmFile> getChangedFiles() { diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommandNoBranchTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommandNoBranchTest.java index 5781edc0e..bf1d74276 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommandNoBranchTest.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/checkin/GitCheckInCommandNoBranchTest.java @@ -44,7 +44,7 @@ public void setUp() { super.setUp(); - workingDirectory = new File( "target/checkin-nobranch" ); + workingDirectory = new File( getTestOutputDir(), "checkin-nobranch" ); } public void testCheckinNoBranch() diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumerTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumerTest.java index 3b4d153d2..512d2efb3 100644 --- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumerTest.java +++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/status/GitStatusConsumerTest.java @@ -187,15 +187,24 @@ public void testConsumerModifiedFile() assertEquals("test file with spaces and a special \u007f character.xml", changedFiles.get( 0 ).getPath() ); } + public void testURI() + throws Exception + { + String path = "Not%Scheme:/sub dir"; + URI u = GitStatusConsumer.uriFromPath( path ); + assertEquals( path, u.getPath() ); + } + // SCM-740 public void testConsumerModifiedFileInComplexDirectorySetup() throws IOException { File dir = createTempDirectory(); - File subdir = new File( dir.getAbsolutePath() + "/subDirectory/" ); + URI relativeCWD = URI.create( "" ); + File subdir = new File( dir, "subDirectory" ); subdir.mkdir(); FileUtils.write( new File( subdir, "project.xml" ), "data" ); - List<ScmFile> changedFiles = getChangedFiles( "M subDirectory/project.xml", subdir, dir.toURI() ); + List<ScmFile> changedFiles = getChangedFiles( "M subDirectory/project.xml", dir, relativeCWD ); assertNotNull( changedFiles ); assertEquals( 1, changedFiles.size() ); @@ -203,7 +212,8 @@ public void testConsumerModifiedFileInComplexDirectorySetup() throws IOException FileUtils.write( new File( subdir, "test file with spaces and a déjà vu character.xml" ), "data" ); - changedFiles = getChangedFiles( "M \"subDirectory/test file with spaces and a déjà vu character.xml\"", subdir, dir.toURI() ); + changedFiles = + getChangedFiles( "M \"subDirectory/test file with spaces and a déjà vu character.xml\"", dir, relativeCWD ); assertNotNull( changedFiles ); assertEquals( 1, changedFiles.size() ); @@ -215,11 +225,13 @@ public void testConsumerModifiedFileInComplexDirectorySetup() throws IOException public void testConsumerModifiedFileInComplexDirectoryWithSpaces() throws IOException { File dir = createTempDirectory(); - File subdir = new File( dir.getAbsolutePath() + "/sub Directory déjà vu special/" ); + URI relativeCWD = URI.create( "" ); + File subdir = new File( dir, "sub Directory déjà vu special" ); subdir.mkdir(); FileUtils.write( new File( subdir, "project.xml" ), "data" ); - List<ScmFile> changedFiles = getChangedFiles( "M \"sub Directory déjà vu special/project.xml\"", subdir, dir.toURI() ); + List<ScmFile> changedFiles = + getChangedFiles( "M \"sub Directory déjà vu special/project.xml\"", dir, relativeCWD ); assertNotNull( changedFiles ); assertEquals( 1, changedFiles.size() ); @@ -227,7 +239,9 @@ public void testConsumerModifiedFileInComplexDirectoryWithSpaces() throws IOExce FileUtils.write( new File( subdir, "test file with spaces and a déjà vu character.xml" ), "data" ); - changedFiles = getChangedFiles( "M \"sub Directory déjà vu special/test file with spaces and a déjà vu character.xml\"", subdir, dir.toURI() ); + changedFiles = + getChangedFiles( "M \"sub Directory déjà vu special/test file with spaces and a déjà vu character.xml\"", + dir, relativeCWD ); assertNotNull( changedFiles ); assertEquals( 1, changedFiles.size() ); diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTestCase.java b/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTestCase.java index dbec38e26..048b02073 100644 --- a/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTestCase.java +++ b/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTestCase.java @@ -163,6 +163,22 @@ public SecDispatcher getSecDispatcher() return secDispatcher; } + /** + * Create the temporary dir for scm tests. See {@link org.apache.maven.wagon.FileTestUtils#getTestOutputDir()} + * + * @return the created dir + */ + public static File getTestOutputDir() + { + final String baseDir = System.getProperty( "scm.test.tmpdir" ); + + final File retValue = new File( baseDir, "target" ); + + retValue.mkdirs(); + + return retValue; + } + protected ScmRepository makeScmRepository( String scmUrl ) throws Exception { ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org With regards, Apache Git Services