You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by mi...@apache.org on 2022/07/24 16:51:27 UTC

[maven-scm] branch master updated: [SCM-925] Implement RemoveCommand in maven-scm-provider-jgit with TCK test for all providers

This is an automated email from the ASF dual-hosted git repository.

michaelo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-scm.git


The following commit(s) were added to refs/heads/master by this push:
     new 2a70033c4 [SCM-925] Implement RemoveCommand in maven-scm-provider-jgit with TCK test for all providers
2a70033c4 is described below

commit 2a70033c4bcb5bdf28892292a6f8566c56abd7d2
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Fri May 3 07:43:05 2019 +0200

    [SCM-925] Implement RemoveCommand in maven-scm-provider-jgit with TCK test for all providers
    
    Co-authored-by: Georg Tsakumagos <ts...@gmail.com>
    
    This closes #144 and closes #156
---
 .../org/apache/maven/scm/manager/ScmManager.java   |   9 +-
 .../gitexe/command/remove/GitRemoveCommand.java    |   6 +-
 .../gitexe/command/remove/GitRemoveConsumer.java   |  16 ++-
 .../gitexe/command/status/GitStatusConsumer.java   |   2 +-
 .../command/remove/GitExeRemoveCommandTckTest.java |  52 ++++++++++
 .../command/remove/GitRemoveConsumerTest.java      |  32 ++++--
 .../command/remove/GitRemoveCommandTckTest.java    |  46 +++++++++
 .../scm/provider/git/jgit/JGitScmProvider.java     |   3 +-
 .../scm/provider/git/jgit/command/JGitUtils.java   | 107 ++++++++++++++-------
 .../jgit/command/checkin/JGitCheckInCommand.java   |  24 ++++-
 .../git/jgit/command/remove/JGitRemoveCommand.java |  81 ++++++++++++++++
 .../remoteinfo/JGitRemoteInfoCommandTckTest.java   |   5 +-
 .../JGitRemoveCommandTckTest.java}                 |  37 ++-----
 .../svnexe/command/remove/SvnRemoveConsumer.java   |   2 +-
 .../command/remove/SvnExeRemoveCommandTckTest.java |  37 +++++++
 .../command/remove/SvnRemoveCommandTckTest.java    |  46 +++++++++
 .../java/org/apache/maven/scm/ScmTckTestCase.java  |  17 +++-
 .../tck/command/remove/RemoveCommandTckTest.java   |  92 ++++++++++++++++++
 pom.xml                                            |   5 +
 src/site/xdoc/matrix.xml                           |   2 +-
 20 files changed, 530 insertions(+), 91 deletions(-)

diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java
index cbbdb9bc3..7ff10b862 100644
--- a/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/manager/ScmManager.java
@@ -274,7 +274,8 @@ public interface ScmManager
      * @param repository the source control system
      * @param fileSet    the files to check in (sometimes called commit)
      * @param message    a string that is a comment on the changes that where done
-     * @return result object encapsulating all file paths (relative to {@code fileSet.getBasedir()})
+     * @return  a {@link CheckInScmResult} that contains the file paths (relative to {@code fileSet.getBasedir()}) that
+     * have been checked in.
      * @throws ScmException if any
      */
     CheckInScmResult checkIn( ScmRepository repository, ScmFileSet fileSet, String message )
@@ -291,7 +292,8 @@ public interface ScmManager
      * @param fileSet    the files to check in (sometimes called commit)
      * @param revision   branch/tag/revision
      * @param message    a string that is a comment on the changes that where done
-     * @return result object encapsulating all file paths (relative to {@code fileSet.getBasedir()})
+     * @return  a {@link CheckInScmResult} that contains the file paths (relative to {@code fileSet.getBasedir()}) that
+     * have been checked in.
      * @throws ScmException if any
      */
     CheckInScmResult checkIn( ScmRepository repository, ScmFileSet fileSet, ScmVersion revision, String message )
@@ -453,7 +455,8 @@ public interface ScmManager
      * @param repository the source control system
      * @param fileSet    the files to be removed
      * @param message TODO
-     * @return TODO
+     * @return a {@link RemoveScmResult} that contains the file paths (relative to {@code fileSet.getBasedir()}) that
+     * have been removed
      * @throws ScmException if any
      */
     RemoveScmResult remove( ScmRepository repository, ScmFileSet fileSet, String message )
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/remove/GitRemoveCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveCommand.java
index 7178a2f87..d790ae08f 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveCommand.java
@@ -27,10 +27,12 @@ import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.provider.ScmProviderRepository;
 import org.apache.maven.scm.provider.git.command.GitCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.GitCommandLineUtils;
+import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
 import org.codehaus.plexus.util.cli.CommandLineUtils;
 import org.codehaus.plexus.util.cli.Commandline;
 
 import java.io.File;
+import java.net.URI;
 import java.util.List;
 
 /**
@@ -56,7 +58,9 @@ public class GitRemoveCommand
 
         Commandline cl = createCommandLine( fileSet.getBasedir(), fileSet.getFileList() );
 
-        GitRemoveConsumer consumer = new GitRemoveConsumer();
+        // git-rm uses repositoryRoot instead of workingDirectory, adjust it with relativeRepositoryPath
+        URI relativeRepositoryPath = GitStatusCommand.getRelativeCWD( logger, fileSet );
+        GitRemoveConsumer consumer = new GitRemoveConsumer( relativeRepositoryPath );
 
         CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
 
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/remove/GitRemoveConsumer.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumer.java
index c8c8882a9..c3d385000 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumer.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumer.java
@@ -21,8 +21,10 @@ package org.apache.maven.scm.provider.git.gitexe.command.remove;
 
 import org.apache.maven.scm.ScmFile;
 import org.apache.maven.scm.ScmFileStatus;
+import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
 import org.apache.maven.scm.util.AbstractConsumer;
 
+import java.net.URI;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Matcher;
@@ -43,10 +45,22 @@ public class GitRemoveConsumer
 
     private final List<ScmFile> removedFiles = new ArrayList<>();
 
+    private final URI relativeRepositoryPath;
+
     // ----------------------------------------------------------------------
     // StreamConsumer Implementation
     // ----------------------------------------------------------------------
 
+    public GitRemoveConsumer()
+    {
+        this( null );
+    }
+
+    public GitRemoveConsumer( URI relativeRepositoryPath )
+    {
+        this.relativeRepositoryPath = relativeRepositoryPath;
+    }
+
     /**
      * {@inheritDoc}
      */
@@ -60,7 +74,7 @@ public class GitRemoveConsumer
         Matcher matcher = REMOVED_PATTERN.matcher( line );
         if ( matcher.matches() )
         {
-            String file = matcher.group( 1 );
+            String file = GitStatusConsumer.resolvePath( matcher.group( 1 ), relativeRepositoryPath );
             removedFiles.add( new ScmFile( file, ScmFileStatus.DELETED ) );
         }
         else
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 dd90a9676..13f2764b1 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
@@ -279,7 +279,7 @@ public class GitStatusConsumer
         return targetFile.isFile();
     }
 
-    protected static String resolvePath( String fileEntry, URI path )
+    public static String resolvePath( String fileEntry, URI path )
     {
         /* Quotes may be included (from the git status line) when an fileEntry includes spaces */
         String cleanedEntry = stripQuotes( fileEntry );
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/remove/GitExeRemoveCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitExeRemoveCommandTckTest.java
new file mode 100644
index 000000000..4b74e0bfe
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitExeRemoveCommandTckTest.java
@@ -0,0 +1,52 @@
+package org.apache.maven.scm.provider.git.gitexe.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.provider.git.command.remove.GitRemoveCommandTckTest;
+import org.apache.maven.scm.provider.git.GitScmTestUtils;
+import org.apache.maven.scm.repository.ScmRepository;
+
+import static org.apache.maven.scm.provider.git.GitScmTestUtils.GIT_COMMAND_LINE;
+
+public class GitExeRemoveCommandTckTest
+    extends GitRemoveCommandTckTest
+{
+    @Override
+    public String getScmProviderCommand()
+    {
+        return GIT_COMMAND_LINE;
+    }
+
+    @Override
+    protected CheckOutScmResult checkOut( File workingDirectory, ScmRepository repository ) throws Exception
+    {
+        try
+        {
+            return super.checkOut( workingDirectory, repository );
+        }
+        finally
+        {
+            GitScmTestUtils.setDefaultUser( workingDirectory );
+        }
+    }
+}
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/remove/GitRemoveConsumerTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumerTest.java
index 64be3cf3f..bb9544bb5 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumerTest.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/remove/GitRemoveConsumerTest.java
@@ -22,6 +22,7 @@ package org.apache.maven.scm.provider.git.gitexe.command.remove;
 import org.apache.maven.scm.ScmFile;
 import org.apache.maven.scm.ScmFileStatus;
 import org.apache.maven.scm.ScmTestCase;
+import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusConsumer;
 import org.apache.maven.scm.util.ConsumerUtils;
 import org.junit.Test;
 
@@ -42,13 +43,28 @@ public class GitRemoveConsumerTest
     public void testConsumerRemovedFile()
     {
         GitRemoveConsumer consumer = new GitRemoveConsumer();
-        
+
         consumer.consumeLine( "rm 'project.xml'" );
-        
+
         List<ScmFile> changedFiles = consumer.getRemovedFiles();
-        
+
         assertNotNull( changedFiles );
         assertEquals( 1, changedFiles.size() );
+        assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
+    }
+
+    @Test
+    public void testConsumerRemovedFileInDifferentDir()
+    {
+        GitRemoveConsumer consumer = new GitRemoveConsumer( GitStatusConsumer.uriFromPath( "main" ) );
+
+        consumer.consumeLine( "rm 'main/project.xml'" );
+
+        List<ScmFile> changedFiles = consumer.getRemovedFiles();
+
+        assertNotNull( changedFiles );
+        assertEquals( 1, changedFiles.size() );
+        assertEquals( "project.xml", changedFiles.get( 0 ).getPath() );
     }
 
     @Test
@@ -62,7 +78,7 @@ public class GitRemoveConsumerTest
         ConsumerUtils.consumeFile( f, consumer );
 
         List<ScmFile> changedFiles = consumer.getRemovedFiles();
-        
+
         assertEquals( 2, changedFiles.size() );
 
         testScmFile( (ScmFile) changedFiles.get( 0 ), "src/main/java/Application.java", ScmFileStatus.DELETED );
@@ -80,14 +96,14 @@ public class GitRemoveConsumerTest
         ConsumerUtils.consumeFile( f, consumer );
 
         List<ScmFile> changedFiles = consumer.getRemovedFiles();
-        
+
         assertEquals( 0, changedFiles.size() );
-   }    
-    
+   }
+
     private void testScmFile( ScmFile fileToTest, String expectedFilePath, ScmFileStatus expectedStatus )
     {
         assertEquals( expectedFilePath, fileToTest.getPath() );
         assertEquals( expectedStatus, fileToTest.getStatus() );
     }
- 
+
 }
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/remove/GitRemoveCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/remove/GitRemoveCommandTckTest.java
new file mode 100644
index 000000000..38ee122da
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/remove/GitRemoveCommandTckTest.java
@@ -0,0 +1,46 @@
+package org.apache.maven.scm.provider.git.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.scm.provider.git.GitScmTestUtils;
+import org.apache.maven.scm.tck.command.remove.RemoveCommandTckTest;
+
+/**
+ * This test tests the remove command.
+ *
+ * @author Georg Tsakumagos
+ */
+public abstract class GitRemoveCommandTckTest
+    extends RemoveCommandTckTest
+{
+    /** {@inheritDoc} */
+    public String getScmUrl()
+        throws Exception
+    {
+        return GitScmTestUtils.getScmUrl( getRepositoryRoot(), "git" );
+    }
+
+    /** {@inheritDoc} */
+    public void initRepo()
+        throws Exception
+    {
+        GitScmTestUtils.initRepo( "src/test/resources/repository/", getRepositoryRoot(), getWorkingDirectory() );
+    }
+}
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java
index f95f9d14a..874b62403 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/JGitScmProvider.java
@@ -41,6 +41,7 @@ import org.apache.maven.scm.provider.git.jgit.command.diff.JGitDiffCommand;
 import org.apache.maven.scm.provider.git.jgit.command.info.JGitInfoCommand;
 import org.apache.maven.scm.provider.git.jgit.command.list.JGitListCommand;
 import org.apache.maven.scm.provider.git.jgit.command.remoteinfo.JGitRemoteInfoCommand;
+import org.apache.maven.scm.provider.git.jgit.command.remove.JGitRemoveCommand;
 import org.apache.maven.scm.provider.git.jgit.command.status.JGitStatusCommand;
 import org.apache.maven.scm.provider.git.jgit.command.tag.JGitTagCommand;
 import org.apache.maven.scm.provider.git.jgit.command.untag.JGitUntagCommand;
@@ -142,7 +143,7 @@ public class JGitScmProvider
     @Override
     protected GitCommand getRemoveCommand()
     {
-        throw new UnsupportedOperationException( "getRemoveCommand" );
+        return new JGitRemoveCommand();
     }
 
     /**
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
index 00216a0e9..baab4ff10 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java
@@ -23,15 +23,14 @@ import org.apache.maven.scm.ScmFile;
 import org.apache.maven.scm.ScmFileSet;
 import org.apache.maven.scm.ScmFileStatus;
 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
-import org.apache.maven.scm.util.FilenameUtils;
 import org.codehaus.plexus.util.StringUtils;
 import org.eclipse.jgit.api.AddCommand;
 import org.eclipse.jgit.api.Git;
 import org.eclipse.jgit.api.PushCommand;
+import org.eclipse.jgit.api.RmCommand;
 import org.eclipse.jgit.api.Status;
 import org.eclipse.jgit.api.errors.GitAPIException;
 import org.eclipse.jgit.api.errors.InvalidRemoteException;
-import org.eclipse.jgit.api.errors.NoFilepatternException;
 import org.eclipse.jgit.api.errors.TransportException;
 import org.eclipse.jgit.diff.DiffEntry;
 import org.eclipse.jgit.diff.DiffEntry.ChangeType;
@@ -76,7 +75,7 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-
+import java.util.function.BiConsumer;
 import static org.eclipse.jgit.lib.Constants.R_TAGS;
 
 /**
@@ -322,26 +321,19 @@ public class JGitUtils
      *                relative to the basedir of this fileset
      * @return a list of added files
      * @throws GitAPIException
-     * @throws NoFilepatternException
      */
     public static List<ScmFile> addAllFiles( Git git, ScmFileSet fileSet )
-        throws GitAPIException, NoFilepatternException
+        throws GitAPIException
     {
         URI workingCopyRootUri = git.getRepository().getWorkTree().toURI();
         AddCommand add = git.add();
-        for ( File file : fileSet.getFileList() )
-        {
-            if ( !file.isAbsolute() )
-            {
-                file = new File( fileSet.getBasedir().getPath(), file.getPath() );
-            }
-
-            if ( file.exists() )
+        callWithRepositoryRelativeFilePath( ( relativeFile, absoluteFile ) ->
             {
-                String path = relativize( workingCopyRootUri, file );
-                add.addFilepattern( path );
-            }
-        }
+                if ( absoluteFile.exists() )
+                {
+                    add.addFilepattern( relativeFile );
+                }
+            }, workingCopyRootUri, fileSet );
         add.call();
 
         Status status = git.status().call();
@@ -349,33 +341,75 @@ public class JGitUtils
         Set<String> allInIndex = new HashSet<>();
         allInIndex.addAll( status.getAdded() );
         allInIndex.addAll( status.getChanged() );
+        return getScmFilesForAllFileSetFilesContainedInRepoPath( workingCopyRootUri, fileSet, allInIndex,
+                                                                 ScmFileStatus.ADDED );
+    }
+
+    /**
+     * Remove all files in the given fileSet from the repository.
+     *
+     * @param git     the repo to remove the files from
+     * @param fileSet the set of files within the workspace, the files are removed
+     *                relative to the basedir of this fileset
+     * @return a list of removed files
+     * @throws GitAPIException
+     */
+    public static List<ScmFile> removeAllFiles( Git git, ScmFileSet fileSet )
+        throws GitAPIException
+    {
+        URI workingCopyRootUri = git.getRepository().getWorkTree().toURI();
+        RmCommand remove = git.rm();
+        callWithRepositoryRelativeFilePath( ( relativeFile, absoluteFile ) ->
+            remove.addFilepattern( relativeFile ), workingCopyRootUri, fileSet );
+        remove.call();
 
-        // System.out.println("All in index: "+allInIndex.size());
+        Status status = git.status().call();
 
-        List<ScmFile> addedFiles = new ArrayList<>( allInIndex.size() );
+        Set<String> allInIndex = new HashSet<>( status.getRemoved() );
+        return getScmFilesForAllFileSetFilesContainedInRepoPath( workingCopyRootUri, fileSet, allInIndex,
+                                                                 ScmFileStatus.DELETED );
+    }
 
-        // rewrite all detected files to now have status 'checked_in'
-        for ( String entry : allInIndex )
+    /**
+     * For each file in the {@code fileSet} call the {@code fileCallback} with the file path relative to the repository
+     * root (forward slashes as separator) and the absolute file path.
+     * @param repoFileCallback the callback to call for each file in the fileset
+     * @param git the git repository
+     * @param fileSet the file set to traverse
+     */
+    private static void callWithRepositoryRelativeFilePath( BiConsumer<String, File> fileCallback,
+                                                            URI workingCopyRootUri, ScmFileSet fileSet )
+    {
+        for ( File file : fileSet.getFileList() )
         {
-            // if a specific fileSet is given, we have to check if the file is
-            // really tracked
-            for ( File file : fileSet.getFileList() )
+            if ( !file.isAbsolute() )
             {
-                if ( !file.isAbsolute() )
-                {
-                    file = new File( fileSet.getBasedir(), file.getPath() );
-                }
-                String path = FilenameUtils.normalizeFilename( relativize( workingCopyRootUri, file ) );
-                if ( path.equals( FilenameUtils.normalizeFilename( entry ) ) )
+                file = new File( fileSet.getBasedir().getPath(), file.getPath() );
+            }
+            String path = relativize( workingCopyRootUri, file );
+            fileCallback.accept( path, file );
+        }
+    }
+
+    private static List<ScmFile> getScmFilesForAllFileSetFilesContainedInRepoPath( URI workingCopyRootUri,
+                                                                                   ScmFileSet fileSet,
+                                                                                   Set<String> repoFilePaths,
+                                                                                   ScmFileStatus fileStatus )
+    {
+        List<ScmFile> files = new ArrayList<>( repoFilePaths.size() );
+        callWithRepositoryRelativeFilePath( ( relativeFile, absoluteFile ) ->
+            {
+                // check if repo relative path is contained
+                if ( repoFilePaths.contains( relativeFile ) )
                 {
                     // returned ScmFiles should be relative to given fileset's basedir
-                    ScmFile scmfile = new ScmFile( relativize( fileSet.getBasedir().toURI(), file ),
-                            ScmFileStatus.ADDED );
-                    addedFiles.add( scmfile );
+                    ScmFile scmfile = new ScmFile( relativize( fileSet.getBasedir().toURI(), absoluteFile ),
+                                                   fileStatus );
+                    files.add( scmfile );
                 }
-            }
-        }
-        return addedFiles;
+            },
+            workingCopyRootUri, fileSet );
+        return files;
     }
 
     private static String relativize( URI baseUri, File f )
@@ -527,4 +561,5 @@ public class JGitUtils
         }
         return result;
     }
+
 }
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
index 8e0d91c2f..cedfd0314 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java
@@ -33,6 +33,7 @@ import org.codehaus.plexus.util.StringUtils;
 import org.eclipse.jgit.api.AddCommand;
 import org.eclipse.jgit.api.CommitCommand;
 import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.Status;
 import org.eclipse.jgit.lib.Constants;
 import org.eclipse.jgit.lib.UserConfig;
 import org.eclipse.jgit.revwalk.RevCommit;
@@ -91,24 +92,39 @@ public class JGitCheckInCommand
 
             if ( !fileSet.getFileList().isEmpty() )
             {
+                // add files first
                 doCommit = JGitUtils.addAllFiles( git, fileSet ).size() > 0;
+                if ( !doCommit )
+                {
+                    doCommit = git.status().call().hasUncommittedChanges();
+                }
             }
             else
             {
                 // add all tracked files which are modified manually
+                Status status = git.status().call();
                 Set<String> changeds = git.status().call().getModified();
                 if ( changeds.isEmpty() )
                 {
-                    // warn there is nothing to add
-                    logger.warn( "there are no files to be added" );
-                    doCommit = false;
+                    if ( !status.hasUncommittedChanges() )
+                    {
+                        // warn there is nothing to add
+                        logger.warn( "There are neither files to be added nor any uncommitted changes" );
+                        doCommit = false;
+                    }
+                    else
+                    {
+                        logger.debug( "There are uncommitted changes in the git index" );
+                        doCommit = true;
+                    }
                 }
                 else
                 {
+                    // TODO: gitexe only adds if fileSet is not empty
                     AddCommand add = git.add();
                     for ( String changed : changeds )
                     {
-                        logger.debug( "add manualy: " + changed );
+                        logger.debug( "Add manually: {}", changed );
                         add.addFilepattern( changed );
                         doCommit = true;
                     }
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommand.java
new file mode 100644
index 000000000..21e0e52f7
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommand.java
@@ -0,0 +1,81 @@
+package org.apache.maven.scm.provider.git.jgit.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.util.List;
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.remove.AbstractRemoveCommand;
+import org.apache.maven.scm.command.remove.RemoveScmResult;
+import org.apache.maven.scm.provider.ScmProviderRepository;
+import org.apache.maven.scm.provider.git.command.GitCommand;
+import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
+import org.eclipse.jgit.api.Git;
+
+/**
+ * @author Georg Tsakumagos
+ * @since 2.0.0-M2
+ */
+public class JGitRemoveCommand
+    extends AbstractRemoveCommand
+    implements GitCommand
+{
+
+    @Override
+    protected ScmResult executeRemoveCommand( ScmProviderRepository repository, ScmFileSet fileSet, String message )
+        throws ScmException
+    {
+
+        if ( fileSet.getFileList().isEmpty() )
+        {
+            throw new ScmException( "You must provide at least one file/directory to remove" );
+        }
+        Git git = null;
+        try
+        {
+            git = JGitUtils.openRepo( fileSet.getBasedir() );
+
+            List<ScmFile> removedFiles = JGitUtils.removeAllFiles( git, fileSet );
+
+            if ( logger.isDebugEnabled() )
+            {
+                for ( ScmFile scmFile : removedFiles )
+                {
+                    logger.info( "Removed file: " + scmFile );
+                }
+            }
+
+            return new RemoveScmResult( "JGit remove", removedFiles );
+
+        }
+        catch ( Exception e )
+        {
+            throw new ScmException( "JGit remove failure!", e );
+        }
+        finally
+        {
+            JGitUtils.closeRepo( git );
+        }
+    }
+
+}
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java
index 714bc8e7b..48101f5f7 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java
@@ -32,7 +32,7 @@ import org.eclipse.jgit.util.FileUtils;
 import static org.junit.Assert.assertEquals;
 
 /**
- * 
+ *
  * @author Dominik Bartholdi (imod)
  */
 public class JGitRemoteInfoCommandTckTest extends AbstractGitRemoteInfoCommandTckTest
@@ -52,8 +52,7 @@ public class JGitRemoteInfoCommandTckTest extends AbstractGitRemoteInfoCommandTc
     public String getScmUrl()
         throws Exception
     {
-    	String scmUrl = GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
-    	System.out.println("SCM: "+scmUrl);
+        String scmUrl = GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
         return scmUrl;
     }
 
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommandTckTest.java
similarity index 51%
copy from maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java
copy to maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommandTckTest.java
index 714bc8e7b..0338dd942 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remoteinfo/JGitRemoteInfoCommandTckTest.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/remove/JGitRemoveCommandTckTest.java
@@ -1,4 +1,4 @@
-package org.apache.maven.scm.provider.git.jgit.command.remoteinfo;
+package org.apache.maven.scm.provider.git.jgit.command.remove;
 
 /*
  * Licensed to the Apache Software Foundation (ASF) under one
@@ -22,53 +22,30 @@ package org.apache.maven.scm.provider.git.jgit.command.remoteinfo;
 import java.io.File;
 import java.io.IOException;
 
-import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
-import org.apache.maven.scm.provider.ScmProviderRepository;
 import org.apache.maven.scm.provider.git.GitScmTestUtils;
-import org.apache.maven.scm.provider.git.command.remoteinfo.AbstractGitRemoteInfoCommandTckTest;
-import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
+import org.apache.maven.scm.provider.git.command.remove.GitRemoveCommandTckTest;
 import org.eclipse.jgit.util.FileUtils;
 
-import static org.junit.Assert.assertEquals;
-
 /**
- * 
- * @author Dominik Bartholdi (imod)
+ * @author Georg Tsakumagos
  */
-public class JGitRemoteInfoCommandTckTest extends AbstractGitRemoteInfoCommandTckTest
+public class JGitRemoveCommandTckTest
+    extends GitRemoveCommandTckTest
 {
-    @Override
-    protected void checkResult( RemoteInfoScmResult result )
-    {
-        assertEquals( 1, result.getBranches().size() );
-        assertEquals( "92f139dfec4d1dfb79c3cd2f94e83bf13129668b", result.getBranches().get( "master" ) );
-
-        assertEquals( 0, result.getTags().size() );
-    }
-
     /**
      * {@inheritDoc}
      */
     public String getScmUrl()
         throws Exception
     {
-    	String scmUrl = GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
-    	System.out.println("SCM: "+scmUrl);
-        return scmUrl;
-    }
-
-    @Override
-    protected ScmProviderRepository getScmProviderRepository()
-        throws Exception
-    {
-        return new GitScmProviderRepository( getScmUrl().substring( "scm:jgit:".length() ) );
+        return GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
     }
 
     @Override
     protected void deleteDirectory( File directory )
         throws IOException
     {
-        if ( directory.exists() )
+        if( directory.exists() )
         {
             FileUtils.delete( directory, FileUtils.RECURSIVE | FileUtils.RETRY );
         }
diff --git a/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnRemoveConsumer.java b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnRemoveConsumer.java
index 90b92dc45..c5e63491e 100644
--- a/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnRemoveConsumer.java
+++ b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/main/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnRemoveConsumer.java
@@ -56,7 +56,7 @@ public class SvnRemoveConsumer
 
         String statusString = line.substring( 0, 1 );
 
-        String file = line.substring( 3 );
+        String file = line.substring( 3 ).trim();
 
         ScmFileStatus status;
 
diff --git a/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/test/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnExeRemoveCommandTckTest.java b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/test/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnExeRemoveCommandTckTest.java
new file mode 100644
index 000000000..3dcf4c408
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svnexe/src/test/java/org/apache/maven/scm/provider/svn/svnexe/command/remove/SvnExeRemoveCommandTckTest.java
@@ -0,0 +1,37 @@
+package org.apache.maven.scm.provider.svn.svnexe.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.scm.provider.svn.command.remove.SvnRemoveCommandTckTest;
+
+import static org.apache.maven.scm.provider.svn.SvnScmTestUtils.SVN_COMMAND_LINE;
+
+/**
+ *
+ */
+public class SvnExeRemoveCommandTckTest
+    extends SvnRemoveCommandTckTest
+{
+    @Override
+    public String getScmProviderCommand()
+    {
+        return SVN_COMMAND_LINE;
+    }
+}
diff --git a/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svntest/src/main/java/org/apache/maven/scm/provider/svn/command/remove/SvnRemoveCommandTckTest.java b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svntest/src/main/java/org/apache/maven/scm/provider/svn/command/remove/SvnRemoveCommandTckTest.java
new file mode 100644
index 000000000..8cc48ec2e
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-svn/maven-scm-provider-svntest/src/main/java/org/apache/maven/scm/provider/svn/command/remove/SvnRemoveCommandTckTest.java
@@ -0,0 +1,46 @@
+package org.apache.maven.scm.provider.svn.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import org.apache.maven.scm.provider.svn.SvnScmTestUtils;
+import org.apache.maven.scm.tck.command.remove.RemoveCommandTckTest;
+
+import java.io.File;
+
+/**
+ *
+ */
+public class SvnRemoveCommandTckTest
+    extends RemoveCommandTckTest
+{
+    /** {@inheritDoc} */
+    public String getScmUrl()
+        throws Exception
+    {
+        return SvnScmTestUtils.getScmUrl( new File( getRepositoryRoot(), "trunk" ) );
+    }
+
+    /** {@inheritDoc} */
+    public void initRepo()
+        throws Exception
+    {
+        SvnScmTestUtils.initializeRepository( getRepositoryRoot() );
+    }
+}
diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTckTestCase.java b/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTckTestCase.java
index e6e76b368..059cd014f 100644
--- a/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTckTestCase.java
+++ b/maven-scm-test/src/main/java/org/apache/maven/scm/ScmTckTestCase.java
@@ -30,6 +30,7 @@ import org.apache.maven.scm.command.add.AddScmResult;
 import org.apache.maven.scm.command.checkin.CheckInScmResult;
 import org.apache.maven.scm.command.checkout.CheckOutScmResult;
 import org.apache.maven.scm.command.edit.EditScmResult;
+import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.provider.ScmProvider;
 import org.apache.maven.scm.repository.ScmRepository;
 import org.codehaus.plexus.util.StringUtils;
@@ -217,7 +218,21 @@ public abstract class ScmTckTestCase
 
         return result;
     }
-    
+
+    /**
+     * Convenience method to remove files from the repository
+     */
+    protected RemoveScmResult remove( File workingDirectory, ScmRepository repository )
+            throws Exception
+    {
+        RemoveScmResult result = getScmManager().getProviderByUrl( getScmUrl() )
+            .remove( repository, new ScmFileSet( workingDirectory ), "Initial Checkin" );
+
+        assertTrue( "Remove result was successful, output: " + result.getCommandOutput(), result.isSuccess() );
+
+        return result;
+    }
+
     /**
      * Convenience method to add a file to the working tree at the working directory
      */
diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/remove/RemoveCommandTckTest.java b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/remove/RemoveCommandTckTest.java
new file mode 100644
index 000000000..a338f748e
--- /dev/null
+++ b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/remove/RemoveCommandTckTest.java
@@ -0,0 +1,92 @@
+package org.apache.maven.scm.tck.command.remove;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import java.io.File;
+import java.util.List;
+
+import org.apache.maven.scm.ScmFile;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmFileStatus;
+import org.apache.maven.scm.ScmTckTestCase;
+import org.apache.maven.scm.command.checkin.CheckInScmResult;
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.command.remove.RemoveScmResult;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+
+/** This test tests the remove command. */
+public abstract class RemoveCommandTckTest
+    extends ScmTckTestCase
+{
+    @Test
+    public void testRemoveCommand()
+        throws Exception
+    {
+        // existence has been tested in ScmTckTestCase.setup() already
+        ScmFileSet fileSet = new ScmFileSet( getWorkingCopy(), "src/main/java/Application.java" );
+        RemoveScmResult removeResult = getScmManager().remove( getScmRepository(), fileSet, "remove1" );
+
+        assertResultIsSuccess( removeResult );
+        // check removed files
+        List<ScmFile> files = removeResult.getRemovedFiles();
+        assertNotNull( files );
+        assertEquals( 1, files.size() );
+        ScmFile file1 = files.get( 0 );
+        assertEquals( ScmFileStatus.DELETED, file1.getStatus() );
+        assertPath( "src/main/java/Application.java", file1.getPath() );
+
+        // remove file with different basedir
+        fileSet = new ScmFileSet( new File( getWorkingCopy(), "src" ), new File( "test/java/Test.java" ) );
+        removeResult = getScmManager().remove( getScmRepository(), fileSet, "remove2" );
+
+        assertResultIsSuccess( removeResult );
+        // check removed files
+        files = removeResult.getRemovedFiles();
+        assertNotNull( files );
+        assertEquals( 1, files.size() );
+        file1 = files.get( 0 );
+        assertEquals( ScmFileStatus.DELETED, file1.getStatus() );
+        assertPath( "test/java/Test.java", file1.getPath() );
+
+        // checkin changes
+        CheckInScmResult checkinResult =
+            getScmManager().checkIn( getScmRepository(), new ScmFileSet( getWorkingCopy() ), "Commit message" );
+
+        assertResultIsSuccess( checkinResult );
+
+        // do a new checkout
+        CheckOutScmResult checkoutResult =
+            getScmManager().checkOut( getScmRepository(), new ScmFileSet( getAssertionCopy() ) );
+
+        assertResultIsSuccess( checkoutResult );
+
+        File applicationJava = new File( getAssertionCopy(), "src/main/java/Application.java" );
+
+        assertFalse( "Application.java does exist even though it has been removed before", applicationJava.canRead() );
+
+        File testJava = new File( getAssertionCopy(), "src/test/java/Test.java" );
+
+        assertFalse( "Test.java does exist even though it has been removed before", testJava.canRead() );
+    }
+}
diff --git a/pom.xml b/pom.xml
index 3ffa4873c..189858b85 100644
--- a/pom.xml
+++ b/pom.xml
@@ -378,6 +378,11 @@
     <contributor>
       <name>Niels Basjes</name>
     </contributor>
+    <contributor>
+      <name>Georg Tsakumagos</name>
+      <email>tsakumagos@gmail.com</email>
+      <timezone>Europe/Berlin</timezone>
+    </contributor>
   </contributors>
 
   <profiles>
diff --git a/src/site/xdoc/matrix.xml b/src/site/xdoc/matrix.xml
index 7b7634c21..8da8c6a2e 100644
--- a/src/site/xdoc/matrix.xml
+++ b/src/site/xdoc/matrix.xml
@@ -52,7 +52,7 @@ under the License.
           </tr>
           <tr>
             <!-- SCM -->
-            <td> GIT </td>
+            <td> Git </td>
             <td>
               <!-- add -->
               <img src="./images/check.gif" />