Skip to content

Commit

Permalink
[SCM-859] Subversion commands don't work if path or URL contains '@'
Browse files Browse the repository at this point in the history
There are some oddities where @ escaping is necessary or whether the
path can have a peg revision or not. A discussion on this has been
raised: http://mail-archives.apache.org/mod_mbox/subversion-users/201809.mbox/%3C5f96ccf9-fe6a-8291-4c5a-c90f8e1c70bc%40apache.org%3E

We might need to revise the code after some time when the issues have
been resolved by the Subversion team.

This closes #58
  • Loading branch information
michael-o committed Sep 9, 2018
1 parent 184e6fe commit 66a260a
Show file tree
Hide file tree
Showing 18 changed files with 90 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class SvnBranchCommand
extends AbstractBranchCommand
implements SvnCommand
{

public ScmResult executeBranchCommand( ScmProviderRepository repo, ScmFileSet fileSet, String branch,
ScmBranchParameters scmBranchParameters )
throws ScmException
Expand Down Expand Up @@ -150,7 +150,7 @@ public ScmResult executeBranchCommand( ScmProviderRepository repo, ScmFileSet fi

return new BranchScmResult( cl.toString(), fileList );
}

/** {@inheritDoc} */
public ScmResult executeBranchCommand( ScmProviderRepository repo, ScmFileSet fileSet, String branch,
String message )
Expand All @@ -172,7 +172,7 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
scmBranchParameters.setPinExternals( false );
return createCommandLine( repository, workingDirectory, branch, messageFile, scmBranchParameters );
}

public static Commandline createCommandLine( SvnScmProviderRepository repository, File workingDirectory,
String branch, File messageFile,
ScmBranchParameters scmBranchParameters )
Expand Down Expand Up @@ -203,15 +203,17 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
cl.createArg().setValue( "--revision" );
cl.createArg().setValue( scmBranchParameters.getScmRevision() );
}
cl.createArg().setValue( SvnCommandUtils.fixUrl( repository.getUrl(), repository.getUser() ) );
String url = SvnCommandUtils.fixUrl( repository.getUrl(), repository.getUser() );
cl.createArg().setValue( url + "@" );
}
else
{
cl.createArg().setValue( "." );
}
// Note: this currently assumes you have the branch base checked out too
String branchUrl = SvnTagBranchUtils.resolveBranchUrl( repository, new ScmBranch( branch ) );
cl.createArg().setValue( SvnCommandUtils.fixUrl( branchUrl, repository.getUser() ) );
branchUrl = SvnCommandUtils.fixUrl( branchUrl, repository.getUser() );
cl.createArg().setValue( branchUrl + "@" );

return cl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -209,17 +209,19 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
// the changelog of that branch, but limit it to paths that also occur in this repository.
if ( branch instanceof ScmTag )
{
cl.createArg().setValue( SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) branch ) );
String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) branch );
cl.createArg().setValue( tagUrl + "@" );
}
else
{
cl.createArg().setValue( SvnTagBranchUtils.resolveBranchUrl( repository, branch ) );
String branchUrl = SvnTagBranchUtils.resolveBranchUrl( repository, branch );
cl.createArg().setValue( branchUrl + "@" );
}
}

if ( endVersion == null || !StringUtils.equals( "BASE", endVersion.getName() ) )
{
cl.createArg().setValue( repository.getUrl() );
cl.createArg().setValue( repository.getUrl() + "@" );
}

return cl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
}
}

cl.createArg().setValue( url );
cl.createArg().setValue( url + "@" );

cl.createArg().setValue( workingDirectory.getAbsolutePath() );

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,15 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
cl.createArg().setValue( version.getName() );
}
}

//support exporting to an existing directory
cl.createArg().setValue( "--force" );

cl.createArg().setValue( url );
cl.createArg().setValue( url + "@" );

if ( StringUtils.isNotEmpty( outputSirectory ) )
{
cl.createArg().setValue( outputSirectory );
cl.createArg().setValue( outputSirectory + "@" );
}

return cl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ protected static Commandline createCommandLine( SvnScmProviderRepository reposit
}
else
{
cl.createArg().setValue( repository.getUrl() + "/" + file.getPath().replace( '\\', '/' ) );
cl.createArg().setValue( repository.getUrl() + "/" + file.getPath().replace( '\\', '/' ) + "@" );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ static Commandline createCommandLine( SvnScmProviderRepository repository, ScmFi
{
File file = it.next();

cl.createArg().setValue( repository.getUrl() + "/" + file.getPath().replace( '\\', '/' ) );
cl.createArg().setValue( repository.getUrl() + "/" + file.getPath().replace( '\\', '/' ) + "@" );
}

return cl;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ protected static Commandline createCommandLine( SvnScmProviderRepository reposit

if ( !createInLocal )
{
cl.createArg().setValue( repository.getUrl() + "/" + dirPath );
cl.createArg().setValue( repository.getUrl() + "/" + dirPath + "@" );

if ( messageFile != null )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public RemoteInfoScmResult executeRemoteInfoCommand( ScmProviderRepository repos

cl.createArg().setValue( "ls" );

cl.createArg().setValue( baseUrl + "/tags" );
cl.createArg().setValue( baseUrl + "/tags" + "@" );

CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();

Expand Down Expand Up @@ -95,7 +95,7 @@ public RemoteInfoScmResult executeRemoteInfoCommand( ScmProviderRepository repos

cl.createArg().setValue( "ls" );

cl.createArg().setValue( baseUrl + "/tags" );
cl.createArg().setValue( baseUrl + "/tags" + "@" );

stderr = new CommandLineUtils.StringStreamConsumer();

Expand Down Expand Up @@ -131,7 +131,7 @@ public boolean remoteUrlExist( ScmProviderRepository repository, CommandParamete

cl.createArg().setValue( "ls" );

cl.createArg().setValue( url );
cl.createArg().setValue( url + "@" );

CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,8 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository

// Note: this currently assumes you have the tag base checked out too
String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, new ScmTag( tag ) );
cl.createArg().setValue( SvnCommandUtils.fixUrl( tagUrl, repository.getUser() ) );
tagUrl = SvnCommandUtils.fixUrl( tagUrl, repository.getUser() );
cl.createArg().setValue( tagUrl + "@" );

return cl;
}
Expand Down Expand Up @@ -261,7 +262,8 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository

if ( scmTagParameters != null && scmTagParameters.isRemoteTagging() )
{
cl.createArg().setValue( SvnCommandUtils.fixUrl( repository.getUrl(), repository.getUser() ) );
String url = SvnCommandUtils.fixUrl( repository.getUrl(), repository.getUser() );
cl.createArg().setValue( url + "@" );
}
else
{
Expand All @@ -270,7 +272,8 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository

// Note: this currently assumes you have the tag base checked out too
String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, new ScmTag( tag ) );
cl.createArg().setValue( SvnCommandUtils.fixUrl( tagUrl, repository.getUser() ) );
tagUrl = SvnCommandUtils.fixUrl( tagUrl, repository.getUser() );
cl.createArg().setValue( tagUrl + "@" );

return cl;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ protected UpdateScmResult executeUpdateCommand( ScmProviderRepository repo, ScmF

UpdateScmResultWithRevision result = new UpdateScmResultWithRevision( cl.toString(), consumer.getUpdatedFiles(),
String.valueOf( consumer.getRevision() ) );

result.setChanges( consumer.getChangeSets() );

if ( getLogger().isDebugEnabled() )
{
getLogger().debug( "changeSets " + consumer.getChangeSets() );
}

return result;
}

Expand Down Expand Up @@ -136,7 +136,7 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
cl.createArg().setValue( version.getName() );
}

cl.createArg().setValue( workingDir );
cl.createArg().setValue( workingDir + "@" );
}
else
{
Expand All @@ -147,14 +147,15 @@ public static Commandline createCommandLine( SvnScmProviderRepository repository
cl.createArg().setValue( "switch" );
if ( version instanceof ScmTag )
{
cl.createArg().setValue( SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) version ) );
String tagUrl = SvnTagBranchUtils.resolveTagUrl( repository, (ScmTag) version );
cl.createArg().setValue( tagUrl + "@" );
}
else
{
cl.createArg().setValue(
SvnTagBranchUtils.resolveBranchUrl( repository, (ScmBranch) version ) );
String branchUrl = SvnTagBranchUtils.resolveBranchUrl( repository, (ScmBranch) version );
cl.createArg().setValue( branchUrl + "@" );
}
cl.createArg().setValue( workingDir );
cl.createArg().setValue( workingDir + "@" );
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void testBranchUserNameSvnHttpsRemoteBranchingWithRev()

testCommandLine( "scm:svn:https://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 --revision 2 https://foo.com/svn/trunk https://foo.com/svn/branches/svnbranch",
+ " --encoding UTF-8 --revision 2 https://foo.com/svn/trunk@ https://foo.com/svn/branches/svnbranch@",
scmBranchParameters );
}

Expand All @@ -67,7 +67,7 @@ public void testBranchUserNameSvnHttpsRemoteBranchingWithRevWithPinExternals()

testCommandLine( "scm:svn:https://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 --pin-externals --revision 2 https://foo.com/svn/trunk https://foo.com/svn/branches/svnbranch",
+ " --encoding UTF-8 --pin-externals --revision 2 https://foo.com/svn/trunk@ https://foo.com/svn/branches/svnbranch@",
scmBranchParameters );
}

Expand All @@ -83,7 +83,7 @@ public void testBranchUserNameSvnHttpsRemoteBranchingNoRev()

testCommandLine( "scm:svn:https://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 https://foo.com/svn/trunk https://foo.com/svn/branches/svnbranch", scmBranchParameters );
+ " --encoding UTF-8 https://foo.com/svn/trunk@ https://foo.com/svn/branches/svnbranch@", scmBranchParameters );
}

public void testBranchUserNameSvnHttpsRemoteBranchingNoRevWithPinExternals()
Expand All @@ -98,7 +98,7 @@ public void testBranchUserNameSvnHttpsRemoteBranchingNoRevWithPinExternals()

testCommandLine( "scm:svn:https://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 --pin-externals https://foo.com/svn/trunk https://foo.com/svn/branches/svnbranch", scmBranchParameters );
+ " --encoding UTF-8 --pin-externals https://foo.com/svn/trunk@ https://foo.com/svn/branches/svnbranch@", scmBranchParameters );
}

public void testBranchUserNameSvnHttps()
Expand All @@ -109,7 +109,7 @@ public void testBranchUserNameSvnHttps()

testCommandLine( "scm:svn:https://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 . https://foo.com/svn/branches/svnbranch", null );
+ " --encoding UTF-8 . https://foo.com/svn/branches/svnbranch@", null );
}

public void testBranchUserNameSvnSsh()
Expand All @@ -120,7 +120,7 @@ public void testBranchUserNameSvnSsh()

testCommandLine( "scm:svn:svn+ssh://foo.com/svn/trunk", "svnbranch", messageFile, "user",
"svn --username user --no-auth-cache --non-interactive copy --parents --file " + messageFile.getAbsolutePath()
+ " --encoding UTF-8 . svn+ssh://user@foo.com/svn/branches/svnbranch" );
+ " --encoding UTF-8 . svn+ssh://user@foo.com/svn/branches/svnbranch@" );
}

private void testCommandLine( String scmUrl, String branch, File messageFile, String user, String commandLine,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@ public void testCommandLineNoDates()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, null, null,
"svn --non-interactive log -v http://foo.com/svn/trunk" );
"svn --non-interactive log -v http://foo.com/svn/trunk@" );
}

public void testCommandLineNoDatesLimitedCount()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, null, null, 40,
"svn --non-interactive log -v --limit 40 http://foo.com/svn/trunk" );
"svn --non-interactive log -v --limit 40 http://foo.com/svn/trunk@" );
}

public void testCommandLineWithDates()
Expand All @@ -59,7 +59,7 @@ public void testCommandLineWithDates()
Date endDate = getDate( 2003, Calendar.OCTOBER, 10, GMT_TIME_ZONE );

testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, startDate, endDate,
"svn --non-interactive log -v -r \"{2003-09-10 00:00:00 +0000}:{2003-10-10 00:00:00 +0000}\" http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r \"{2003-09-10 00:00:00 +0000}:{2003-10-10 00:00:00 +0000}\" http://foo.com/svn/trunk@" );
}

public void testCommandLineStartDateOnly()
Expand All @@ -68,7 +68,7 @@ public void testCommandLineStartDateOnly()
Date startDate = getDate( 2003, Calendar.SEPTEMBER, 10, 1, 1, 1, GMT_TIME_ZONE );

testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, startDate, null,
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:HEAD\" http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:HEAD\" http://foo.com/svn/trunk@" );
}

public void testCommandLineDateFormat()
Expand All @@ -78,7 +78,7 @@ public void testCommandLineDateFormat()
Date endDate = getDate( 2005, Calendar.NOVEMBER, 13, 23, 23, 23, GMT_TIME_ZONE );

testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, startDate, endDate,
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:{2005-11-13 23:23:23 +0000}\" http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:{2005-11-13 23:23:23 +0000}\" http://foo.com/svn/trunk@" );
}

public void testCommandLineEndDateOnly()
Expand All @@ -88,14 +88,14 @@ public void testCommandLineEndDateOnly()

// Only specifying end date should print no dates at all
testCommandLine( "scm:svn:http://foo.com/svn/trunk", null, null, endDate,
"svn --non-interactive log -v http://foo.com/svn/trunk" );
"svn --non-interactive log -v http://foo.com/svn/trunk@" );
}

public void testCommandLineWithBranchNoDates()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmBranch( "my-test-branch" ), null, null,
"svn --non-interactive log -v http://foo.com/svn/branches/my-test-branch http://foo.com/svn/trunk" );
"svn --non-interactive log -v http://foo.com/svn/branches/my-test-branch@ http://foo.com/svn/trunk@" );
}

public void testCommandLineWithBranchStartDateOnly()
Expand All @@ -104,7 +104,7 @@ public void testCommandLineWithBranchStartDateOnly()
Date startDate = getDate( 2003, Calendar.SEPTEMBER, 10, 1, 1, 1, GMT_TIME_ZONE );

testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmBranch( "my-test-branch" ), startDate, null,
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:HEAD\" http://foo.com/svn/branches/my-test-branch http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r \"{2003-09-10 01:01:01 +0000}:HEAD\" http://foo.com/svn/branches/my-test-branch@ http://foo.com/svn/trunk@" );
}

public void testCommandLineWithBranchEndDateOnly()
Expand All @@ -114,7 +114,7 @@ public void testCommandLineWithBranchEndDateOnly()

// Only specifying end date should print no dates at all
testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmBranch( "my-test-branch" ), null, endDate,
"svn --non-interactive log -v http://foo.com/svn/branches/my-test-branch http://foo.com/svn/trunk" );
"svn --non-interactive log -v http://foo.com/svn/branches/my-test-branch@ http://foo.com/svn/trunk@" );
}

public void testCommandLineWithBranchBothDates()
Expand All @@ -124,28 +124,28 @@ public void testCommandLineWithBranchBothDates()
Date endDate = getDate( 2003, Calendar.OCTOBER, 10, GMT_TIME_ZONE );

testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmBranch( "my-test-branch" ), startDate, endDate,
"svn --non-interactive log -v -r \"{2003-09-10 00:00:00 +0000}:{2003-10-10 00:00:00 +0000}\" http://foo.com/svn/branches/my-test-branch http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r \"{2003-09-10 00:00:00 +0000}:{2003-10-10 00:00:00 +0000}\" http://foo.com/svn/branches/my-test-branch@ http://foo.com/svn/trunk@" );
}

public void testCommandLineWithStartVersion()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmRevision( "1" ), null,
"svn --non-interactive log -v -r 1:HEAD http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r 1:HEAD http://foo.com/svn/trunk@" );
}

public void testCommandLineWithStartVersionAndEndVersion()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmRevision( "1" ), new ScmRevision( "10" ),
"svn --non-interactive log -v -r 1:10 http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r 1:10 http://foo.com/svn/trunk@" );
}

public void testCommandLineWithStartVersionAndEndVersionEquals()
throws Exception
{
testCommandLine( "scm:svn:http://foo.com/svn/trunk", new ScmRevision( "1" ), new ScmRevision( "1" ),
"svn --non-interactive log -v -r 1 http://foo.com/svn/trunk" );
"svn --non-interactive log -v -r 1 http://foo.com/svn/trunk@" );
}

public void testCommandLineWithBaseVersion()
Expand Down
Loading

0 comments on commit 66a260a

Please sign in to comment.