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 2018/12/30 22:42:22 UTC

[maven-scm] branch SCM-318 updated (866c13f -> 4946751)

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

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


 discard 866c13f  [SCM-318] Allow tags to be removed with Git implementation
     new 4946751  [SCM-318] Allow tags to be removed with Git implementation

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (866c13f)
            \
             N -- N -- N   refs/heads/SCM-318 (4946751)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../src/test/resources/mojos/untag/{tag.xml => checkout.xml}         | 5 ++---
 .../src/test/resources/mojos/untag/{tag.xml => untag.xml}            | 0
 2 files changed, 2 insertions(+), 3 deletions(-)
 copy maven-scm-plugin/src/test/resources/mojos/untag/{tag.xml => checkout.xml} (93%)
 copy maven-scm-plugin/src/test/resources/mojos/untag/{tag.xml => untag.xml} (100%)


[maven-scm] 01/01: [SCM-318] Allow tags to be removed with Git implementation

Posted by mi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

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

commit 4946751a00adae028a76bba7cd8c8a49d208d693
Author: Chris Hennick <49...@users.noreply.github.com>
AuthorDate: Tue Jul 31 00:08:53 2018 -0700

    [SCM-318] Allow tags to be removed with Git implementation
    
    This closes #79
---
 .../maven/scm/command/tag/AbstractTagCommand.java  |   8 +-
 .../scm/command/untag/AbstractUntagCommand.java    |  48 ++++++++
 .../maven/scm/command/untag/UntagScmResult.java    |  44 ++++++++
 .../maven/scm/provider/AbstractScmProvider.java    |  12 ++
 .../org/apache/maven/scm/provider/ScmProvider.java |  13 +++
 maven-scm-plugin/pom.xml                           |   5 +
 .../org/apache/maven/scm/plugin/UntagMojo.java     |  76 +++++++++++++
 .../org/apache/maven/scm/plugin/UntagMojoTest.java | 123 +++++++++++++++++++++
 .../src/test/resources/git/.gitattributes          |   3 +
 maven-scm-plugin/src/test/resources/git/HEAD       |   1 +
 maven-scm-plugin/src/test/resources/git/config     |   5 +
 .../src/test/resources/git/description             |   1 +
 .../src/test/resources/git/hooks/empty.txt         |   0
 .../src/test/resources/git/info/exclude            |   6 +
 maven-scm-plugin/src/test/resources/git/logs/HEAD  |   3 +
 .../src/test/resources/git/logs/refs/heads/master  |   3 +
 .../resources/git/logs/refs/remotes/origin/master  |   1 +
 .../17/e953589369a48dcb0a0cbad084a76ef852cd11      | Bin 0 -> 37 bytes
 .../1d/308c3b92eb0df9c0dc76436d50edfd0ca41d18      | Bin 0 -> 199 bytes
 .../3b/459fa9451a94fc1acd10e2e29ab73d93eb816d      | Bin 0 -> 75 bytes
 .../3b/d305c57c635aead10cf59f7c1dc51af03edaf7      | Bin 0 -> 116 bytes
 .../3c/f7bb86c15554148bf5b0b12bfd639e54a77e58      | Bin 0 -> 46 bytes
 .../61/4a3fd04313593d67f4154855a06941046326b3      | Bin 0 -> 23 bytes
 .../61/a0d22b023d6e31894d736cca8c1a47b6edd822      | Bin 0 -> 45 bytes
 .../92/09a983605d6e43e5cf841a1ea18a1914bb7407      | Bin 0 -> 54 bytes
 .../92/f139dfec4d1dfb79c3cd2f94e83bf13129668b      |   1 +
 .../94/d3d586e355f318d67e3da6bb16a91be7aad1a7      | Bin 0 -> 28 bytes
 .../9e/131cfc732b0d9f42b9b712a528d0632d9bcca7      | Bin 0 -> 43 bytes
 .../b5/3306f849b69ef0459ddf5cccff06b5fbb08c23      | Bin 0 -> 36 bytes
 .../ba/a229a9193371fad604444f64c4f26f8ff702f3      |   1 +
 .../ba/cd4ee105073117b30e5dcdba5150373b6b53c6      | Bin 0 -> 60 bytes
 .../c3/8b0351660113545db270ba6918cc22a9eb17ce      | Bin 0 -> 46 bytes
 .../c5/1dcd33e7b71897603c203b5e0afc1d75f70051      | Bin 0 -> 147 bytes
 .../dc/4204852765c12f398ef4a5fbcabf23cf17a183      | Bin 0 -> 116 bytes
 .../f7/1429f9ff9214a546b438c611ae942c9cf5a49e      | Bin 0 -> 46 bytes
 .../fd/39fa3de0f63bc5c78eca219e74e0a8531bd3e6      | Bin 0 -> 24 bytes
 .../fe/a16119a5b4ec0562d4f65b4237314250773bf8      | Bin 0 -> 27 bytes
 .../src/test/resources/git/refs/heads/master       |   1 +
 .../test/resources/git/refs/remotes/origin/HEAD    |   1 +
 .../test/resources/git/refs/remotes/origin/master  |   1 +
 .../test/resources/mojos/untag/checkout-tag.xml    |  36 ++++++
 .../src/test/resources/mojos/untag/checkout.xml    |  34 ++++++
 .../src/test/resources/mojos/untag/tag.xml         |  35 ++++++
 .../src/test/resources/mojos/untag/untag.xml       |  35 ++++++
 .../scm/provider/git/AbstractGitScmProvider.java   |  12 ++
 .../maven/scm/provider/git/TestGitScmProvider.java |   5 +
 .../scm/provider/git/gitexe/GitExeScmProvider.java |   7 ++
 .../git/gitexe/command/untag/GitUntagCommand.java  | 110 ++++++++++++++++++
 .../command/untag/GitExeUntagCommandTckTest.java   |  34 ++++++
 .../git/command/untag/GitUntagCommandTckTest.java  |  51 +++++++++
 .../scm/provider/git/jgit/JGitScmProvider.java     |   9 ++
 .../git/jgit/command/untag/JGitUntagCommand.java   | 102 +++++++++++++++++
 .../command/untag/JGitUntagCommandTckTest.java     |  52 +++++++++
 .../apache/maven/scm/provider/ScmProviderStub.java |  20 ++++
 .../scm/tck/command/untag/UntagCommandTckTest.java |  84 ++++++++++++++
 55 files changed, 979 insertions(+), 4 deletions(-)

diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/command/tag/AbstractTagCommand.java b/maven-scm-api/src/main/java/org/apache/maven/scm/command/tag/AbstractTagCommand.java
index 41493d2..c0b4d56 100644
--- a/maven-scm-api/src/main/java/org/apache/maven/scm/command/tag/AbstractTagCommand.java
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/command/tag/AbstractTagCommand.java
@@ -37,7 +37,7 @@ public abstract class AbstractTagCommand
     extends AbstractCommand
 {
     /**
-     * @deprecated use method {@link #executeTagCommand(ScmProviderRepository, ScmFileSet, String, ScmTagParameters)} 
+     * @deprecated use method {@link #executeTagCommand(ScmProviderRepository, ScmFileSet, String, ScmTagParameters)}
      * @param repository
      * @param fileSet
      * @param tagName
@@ -54,8 +54,8 @@ public abstract class AbstractTagCommand
 
     protected abstract ScmResult executeTagCommand( ScmProviderRepository repository, ScmFileSet fileSet,
                                                     String tagName, ScmTagParameters scmTagParameters )
-        throws ScmException;    
-    
+        throws ScmException;
+
     /** {@inheritDoc} */
     public ScmResult executeCommand( ScmProviderRepository repository, ScmFileSet fileSet,
                                      CommandParameters parameters )
@@ -81,5 +81,5 @@ public abstract class AbstractTagCommand
 
         return executeTagCommand( repository, fileSet, tagName, scmTagParameters );
     }
-    
+
 }
diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/AbstractUntagCommand.java b/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/AbstractUntagCommand.java
new file mode 100644
index 0000000..bbbb0c8
--- /dev/null
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/AbstractUntagCommand.java
@@ -0,0 +1,48 @@
+package org.apache.maven.scm.command.untag;
+
+/*
+ * 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.CommandParameter;
+import org.apache.maven.scm.CommandParameters;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.AbstractCommand;
+import org.apache.maven.scm.provider.ScmProviderRepository;
+
+/** {@inheritDoc} */
+public abstract class AbstractUntagCommand
+    extends AbstractCommand
+{
+    protected abstract ScmResult executeUntagCommand( ScmProviderRepository repository,
+        ScmFileSet fileSet, String tagName )
+        throws ScmException;
+
+    /** {@inheritDoc} */
+    public ScmResult executeCommand( ScmProviderRepository repository, ScmFileSet fileSet,
+                                     CommandParameters parameters )
+        throws ScmException
+    {
+        String tagName = parameters.getString( CommandParameter.TAG_NAME );
+
+        return executeUntagCommand( repository, fileSet, tagName );
+    }
+
+}
diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/UntagScmResult.java b/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/UntagScmResult.java
new file mode 100644
index 0000000..47babaf
--- /dev/null
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/command/untag/UntagScmResult.java
@@ -0,0 +1,44 @@
+package org.apache.maven.scm.command.untag;
+
+/*
+ * 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.ScmResult;
+
+/** {@inheritDoc} */
+public class UntagScmResult
+    extends ScmResult
+{
+    private static final long serialVersionUID = -5068975000282095635L;
+
+    public UntagScmResult( String commandLine, String providerMessage, String commandOutput, boolean success )
+    {
+        super( commandLine, providerMessage, commandOutput, success );
+    }
+
+    public UntagScmResult( String commandLine )
+    {
+        super( commandLine, null, null, true );
+    }
+
+    public UntagScmResult( ScmResult result )
+    {
+        super( result );
+    }
+}
diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/AbstractScmProvider.java b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/AbstractScmProvider.java
index dfcc88d..dcacd11 100644
--- a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/AbstractScmProvider.java
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/AbstractScmProvider.java
@@ -49,6 +49,7 @@ import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.command.status.StatusScmResult;
 import org.apache.maven.scm.command.tag.TagScmResult;
 import org.apache.maven.scm.command.unedit.UnEditScmResult;
+import org.apache.maven.scm.command.untag.UntagScmResult;
 import org.apache.maven.scm.command.update.UpdateScmResult;
 import org.apache.maven.scm.log.ScmLogDispatcher;
 import org.apache.maven.scm.log.ScmLogger;
@@ -901,6 +902,17 @@ public abstract class AbstractScmProvider
 
     /**
      * {@inheritDoc}
+     */
+    public UntagScmResult untag( ScmRepository repository, ScmFileSet fileSet,
+        CommandParameters parameters )
+        throws ScmException
+    {
+        getLogger().warn( "Provider " + this.getScmType() + " does not support untag operation." );
+        return new UntagScmResult( "", null, null, true );
+    }
+
+    /**
+     * {@inheritDoc}
      *
      * @deprecated
      */
diff --git a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java
index a2d005f..168c846 100644
--- a/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java
+++ b/maven-scm-api/src/main/java/org/apache/maven/scm/provider/ScmProvider.java
@@ -45,6 +45,7 @@ import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.command.status.StatusScmResult;
 import org.apache.maven.scm.command.tag.TagScmResult;
 import org.apache.maven.scm.command.unedit.UnEditScmResult;
+import org.apache.maven.scm.command.untag.UntagScmResult;
 import org.apache.maven.scm.command.update.UpdateScmResult;
 import org.apache.maven.scm.log.ScmLogger;
 import org.apache.maven.scm.repository.ScmRepository;
@@ -642,6 +643,18 @@ public interface ScmProvider
         throws ScmException;
 
     /**
+     * Deletes a tag.
+     *
+     * @param repository the source control system
+     * @param fileSet    a fileset with the relevant working directory as basedir
+     * @param parameters
+     * @return
+     * @throws ScmException if any
+     */
+    UntagScmResult untag( ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters )
+        throws ScmException;
+
+    /**
      * Tag (or label in some systems) will tag the source file with a certain tag
      *
      * @param repository the source control system
diff --git a/maven-scm-plugin/pom.xml b/maven-scm-plugin/pom.xml
index 9df467a..f865c36 100644
--- a/maven-scm-plugin/pom.xml
+++ b/maven-scm-plugin/pom.xml
@@ -128,6 +128,11 @@
       <artifactId>maven-scm-provider-svntest</artifactId>
       <scope>test</scope>
     </dependency>
+      <dependency>
+          <groupId>org.apache.maven.scm</groupId>
+          <artifactId>maven-scm-provider-gittest</artifactId>
+          <scope>test</scope>
+      </dependency>
   </dependencies>
 
   <build>
diff --git a/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/UntagMojo.java b/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/UntagMojo.java
new file mode 100644
index 0000000..3368b53
--- /dev/null
+++ b/maven-scm-plugin/src/main/java/org/apache/maven/scm/plugin/UntagMojo.java
@@ -0,0 +1,76 @@
+package org.apache.maven.scm.plugin;
+
+/*
+ * 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.IOException;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.scm.CommandParameter;
+import org.apache.maven.scm.CommandParameters;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.command.untag.UntagScmResult;
+import org.apache.maven.scm.provider.ScmProvider;
+import org.apache.maven.scm.repository.ScmRepository;
+
+/**
+ * Untag the project.
+ */
+@Mojo( name = "untag", aggregator = true )
+public class UntagMojo
+    extends AbstractScmMojo
+{
+    /**
+     * The tag name.
+     */
+    @Parameter( property = "tag", required = true )
+    private String tag;
+
+    /** {@inheritDoc} */
+    public void execute()
+        throws MojoExecutionException
+    {
+        super.execute();
+
+        try
+        {
+            ScmRepository repository = getScmRepository();
+            ScmProvider provider = getScmManager().getProviderByRepository( repository );
+
+            String finalTag = provider.sanitizeTagName( tag );
+            getLog().info( "Final Tag Name: '" + finalTag + "'" );
+
+            CommandParameters parameters = new CommandParameters();
+            parameters.setString( CommandParameter.TAG_NAME, finalTag );
+
+            UntagScmResult result = provider.untag( repository, getFileSet(), parameters );
+
+            checkResult( result );
+        }
+        catch ( IOException e )
+        {
+            throw new MojoExecutionException( "Cannot run untag command", e );
+        }
+        catch ( ScmException e )
+        {
+            throw new MojoExecutionException( "Cannot run untag command", e );
+        }
+    }
+}
diff --git a/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/UntagMojoTest.java b/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/UntagMojoTest.java
new file mode 100644
index 0000000..d7e1313
--- /dev/null
+++ b/maven-scm-plugin/src/test/java/org/apache/maven/scm/plugin/UntagMojoTest.java
@@ -0,0 +1,123 @@
+package org.apache.maven.scm.plugin;
+
+/*
+ * 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.plugin.testing.AbstractMojoTestCase;
+import org.apache.maven.scm.provider.git.GitScmTestUtils;
+import org.codehaus.plexus.util.FileUtils;
+import org.codehaus.plexus.util.StringUtils;
+
+/**
+ * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
+ *
+ */
+public class UntagMojoTest
+    extends AbstractMojoTestCase
+{
+    File checkoutDir;
+
+    File repository;
+
+    File assertionDir;
+
+    protected void setUp()
+        throws Exception
+    {
+        super.setUp();
+
+        checkoutDir = getTestFile( "target/checkout" );
+
+        FileUtils.forceDelete( checkoutDir );
+
+        repository = getTestFile( "target/repository" );
+
+        FileUtils.forceDelete( repository );
+
+        assertionDir = getTestFile( "target/assert" );
+
+        FileUtils.forceDelete( assertionDir );
+
+        GitScmTestUtils.initRepo( "src/test/resources/git", checkoutDir, assertionDir );
+
+        CheckoutMojo checkoutMojo = (CheckoutMojo) lookupMojo( "checkout", getTestFile(
+            "src/test/resources/mojos/untag/checkout.xml" ) );
+        checkoutMojo.setWorkingDirectory( checkoutDir );
+
+        String connectionUrl = checkoutMojo.getConnectionUrl();
+        connectionUrl = StringUtils.replace( connectionUrl, "${basedir}", getBasedir() );
+        connectionUrl = StringUtils.replace( connectionUrl, "\\", "/" );
+        checkoutMojo.setConnectionUrl( connectionUrl );
+
+        checkoutMojo.setCheckoutDirectory( checkoutDir );
+
+        checkoutMojo.execute();
+    }
+
+    public void testUntag()
+        throws Exception
+    {
+
+        TagMojo tagMojo = (TagMojo) lookupMojo( "tag", getTestFile( "src/test/resources/mojos/untag/tag.xml" ) );
+        tagMojo.setWorkingDirectory( checkoutDir );
+        tagMojo.setConnectionUrl( getConnectionLocalAddress( tagMojo ) );
+        tagMojo.execute();
+
+        CheckoutMojo checkoutMojo =
+            (CheckoutMojo) lookupMojo( "checkout", getTestFile( "src/test/resources/mojos/untag/checkout-tag.xml" ) );
+        checkoutMojo.setWorkingDirectory( new File( getBasedir() ) );
+        checkoutMojo.setConnectionUrl( getConnectionLocalAddress( checkoutMojo ) );
+
+        File tagCheckoutDir = getTestFile( "target/tags/mytag" );
+
+        if ( tagCheckoutDir.exists() )
+        {
+            FileUtils.deleteDirectory( tagCheckoutDir );
+        }
+
+        checkoutMojo.setCheckoutDirectory( tagCheckoutDir );
+        checkoutMojo.execute();
+
+        UntagMojo mojo = (UntagMojo) lookupMojo( "untag", getTestFile( "src/test/resources/mojos/untag/untag.xml" ) );
+        mojo.setWorkingDirectory( checkoutDir );
+        mojo.setConnectionUrl( getConnectionLocalAddress( mojo ) );
+
+        mojo.execute();
+
+        FileUtils.deleteDirectory( tagCheckoutDir );
+
+        try
+        {
+            checkoutMojo.execute();
+            fail( "checkoutMojo should have failed to check out deleted tag" );
+        }
+        catch (Exception expected)
+        {
+        }
+    }
+
+    private String getConnectionLocalAddress(AbstractScmMojo mojo)
+    {
+        String connectionUrl = mojo.getConnectionUrl();
+        connectionUrl = StringUtils.replace( connectionUrl, "${basedir}", getBasedir() );
+        connectionUrl = StringUtils.replace( connectionUrl, "\\", "/" );
+        return connectionUrl;
+    }
+}
diff --git a/maven-scm-plugin/src/test/resources/git/.gitattributes b/maven-scm-plugin/src/test/resources/git/.gitattributes
new file mode 100644
index 0000000..5e0feff
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/.gitattributes
@@ -0,0 +1,3 @@
+objects/** binary
+* text eol=lf
+
diff --git a/maven-scm-plugin/src/test/resources/git/HEAD b/maven-scm-plugin/src/test/resources/git/HEAD
new file mode 100644
index 0000000..cb089cd
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/HEAD
@@ -0,0 +1 @@
+ref: refs/heads/master
diff --git a/maven-scm-plugin/src/test/resources/git/config b/maven-scm-plugin/src/test/resources/git/config
new file mode 100644
index 0000000..c53d818
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/config
@@ -0,0 +1,5 @@
+[core]
+	repositoryformatversion = 0
+	filemode = true
+	bare = true
+	ignorecase = true
diff --git a/maven-scm-plugin/src/test/resources/git/description b/maven-scm-plugin/src/test/resources/git/description
new file mode 100644
index 0000000..c6f25e8
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/description
@@ -0,0 +1 @@
+Unnamed repository; edit this file to name it for gitweb.
diff --git a/maven-scm-plugin/src/test/resources/git/hooks/empty.txt b/maven-scm-plugin/src/test/resources/git/hooks/empty.txt
new file mode 100644
index 0000000..e69de29
diff --git a/maven-scm-plugin/src/test/resources/git/info/exclude b/maven-scm-plugin/src/test/resources/git/info/exclude
new file mode 100644
index 0000000..2c87b72
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/info/exclude
@@ -0,0 +1,6 @@
+# git-ls-files --others --exclude-from=.git/info/exclude
+# Lines that start with '#' are comments.
+# For a project mostly in C, the following would be a good set of
+# exclude patterns (uncomment them if you want to use them):
+# *.[oa]
+# *~
diff --git a/maven-scm-plugin/src/test/resources/git/logs/HEAD b/maven-scm-plugin/src/test/resources/git/logs/HEAD
new file mode 100644
index 0000000..3cf80ca
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/logs/HEAD
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c51dcd33e7b71897603c203b5e0afc1d75f70051 Mark Struberg <st...@yahoo.de> 1196106917 +0100
+c51dcd33e7b71897603c203b5e0afc1d75f70051 baa229a9193371fad604444f64c4f26f8ff702f3 Mark Struberg <st...@yahoo.de> 1197041894 +0100	push
+baa229a9193371fad604444f64c4f26f8ff702f3 1d308c3b92eb0df9c0dc76436d50edfd0ca41d18 Mark Struberg <st...@yahoo.de> 1197042012 +0100	push
diff --git a/maven-scm-plugin/src/test/resources/git/logs/refs/heads/master b/maven-scm-plugin/src/test/resources/git/logs/refs/heads/master
new file mode 100644
index 0000000..3cf80ca
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/logs/refs/heads/master
@@ -0,0 +1,3 @@
+0000000000000000000000000000000000000000 c51dcd33e7b71897603c203b5e0afc1d75f70051 Mark Struberg <st...@yahoo.de> 1196106917 +0100
+c51dcd33e7b71897603c203b5e0afc1d75f70051 baa229a9193371fad604444f64c4f26f8ff702f3 Mark Struberg <st...@yahoo.de> 1197041894 +0100	push
+baa229a9193371fad604444f64c4f26f8ff702f3 1d308c3b92eb0df9c0dc76436d50edfd0ca41d18 Mark Struberg <st...@yahoo.de> 1197042012 +0100	push
diff --git a/maven-scm-plugin/src/test/resources/git/logs/refs/remotes/origin/master b/maven-scm-plugin/src/test/resources/git/logs/refs/remotes/origin/master
new file mode 100644
index 0000000..6cb21b1
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/logs/refs/remotes/origin/master
@@ -0,0 +1 @@
+0000000000000000000000000000000000000000 c51dcd33e7b71897603c203b5e0afc1d75f70051 Mark Struberg <st...@yahoo.de> 1196106917 +0100	clone: from /home/msx/tmp/maven-git/repository/.git
diff --git a/maven-scm-plugin/src/test/resources/git/objects/17/e953589369a48dcb0a0cbad084a76ef852cd11 b/maven-scm-plugin/src/test/resources/git/objects/17/e953589369a48dcb0a0cbad084a76ef852cd11
new file mode 100644
index 0000000..4c7bbd6
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/17/e953589369a48dcb0a0cbad084a76ef852cd11 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/1d/308c3b92eb0df9c0dc76436d50edfd0ca41d18 b/maven-scm-plugin/src/test/resources/git/objects/1d/308c3b92eb0df9c0dc76436d50edfd0ca41d18
new file mode 100644
index 0000000..7d4c247
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/1d/308c3b92eb0df9c0dc76436d50edfd0ca41d18 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/3b/459fa9451a94fc1acd10e2e29ab73d93eb816d b/maven-scm-plugin/src/test/resources/git/objects/3b/459fa9451a94fc1acd10e2e29ab73d93eb816d
new file mode 100644
index 0000000..6b6bfad
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/3b/459fa9451a94fc1acd10e2e29ab73d93eb816d differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/3b/d305c57c635aead10cf59f7c1dc51af03edaf7 b/maven-scm-plugin/src/test/resources/git/objects/3b/d305c57c635aead10cf59f7c1dc51af03edaf7
new file mode 100644
index 0000000..0a079e7
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/3b/d305c57c635aead10cf59f7c1dc51af03edaf7 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/3c/f7bb86c15554148bf5b0b12bfd639e54a77e58 b/maven-scm-plugin/src/test/resources/git/objects/3c/f7bb86c15554148bf5b0b12bfd639e54a77e58
new file mode 100644
index 0000000..c8859bd
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/3c/f7bb86c15554148bf5b0b12bfd639e54a77e58 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/61/4a3fd04313593d67f4154855a06941046326b3 b/maven-scm-plugin/src/test/resources/git/objects/61/4a3fd04313593d67f4154855a06941046326b3
new file mode 100644
index 0000000..bca48ac
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/61/4a3fd04313593d67f4154855a06941046326b3 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/61/a0d22b023d6e31894d736cca8c1a47b6edd822 b/maven-scm-plugin/src/test/resources/git/objects/61/a0d22b023d6e31894d736cca8c1a47b6edd822
new file mode 100644
index 0000000..26470db
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/61/a0d22b023d6e31894d736cca8c1a47b6edd822 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/92/09a983605d6e43e5cf841a1ea18a1914bb7407 b/maven-scm-plugin/src/test/resources/git/objects/92/09a983605d6e43e5cf841a1ea18a1914bb7407
new file mode 100644
index 0000000..9493985
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/92/09a983605d6e43e5cf841a1ea18a1914bb7407 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/92/f139dfec4d1dfb79c3cd2f94e83bf13129668b b/maven-scm-plugin/src/test/resources/git/objects/92/f139dfec4d1dfb79c3cd2f94e83bf13129668b
new file mode 100644
index 0000000..a352d5a
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/objects/92/f139dfec4d1dfb79c3cd2f94e83bf13129668b
@@ -0,0 +1 @@
+x��1�0@Q��;���	!.��	\ǡ�A��=�ly�R��@k����1H�������p�Q(I ��5q��W�j��;\����_�:�y�u����H=}[$D'ߥ�_ؕ�X���Y����<m
\ No newline at end of file
diff --git a/maven-scm-plugin/src/test/resources/git/objects/94/d3d586e355f318d67e3da6bb16a91be7aad1a7 b/maven-scm-plugin/src/test/resources/git/objects/94/d3d586e355f318d67e3da6bb16a91be7aad1a7
new file mode 100644
index 0000000..ea35629
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/94/d3d586e355f318d67e3da6bb16a91be7aad1a7 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/9e/131cfc732b0d9f42b9b712a528d0632d9bcca7 b/maven-scm-plugin/src/test/resources/git/objects/9e/131cfc732b0d9f42b9b712a528d0632d9bcca7
new file mode 100644
index 0000000..0ba67da
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/9e/131cfc732b0d9f42b9b712a528d0632d9bcca7 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/b5/3306f849b69ef0459ddf5cccff06b5fbb08c23 b/maven-scm-plugin/src/test/resources/git/objects/b5/3306f849b69ef0459ddf5cccff06b5fbb08c23
new file mode 100644
index 0000000..314330e
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/b5/3306f849b69ef0459ddf5cccff06b5fbb08c23 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/ba/a229a9193371fad604444f64c4f26f8ff702f3 b/maven-scm-plugin/src/test/resources/git/objects/ba/a229a9193371fad604444f64c4f26f8ff702f3
new file mode 100644
index 0000000..e94938a
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/objects/ba/a229a9193371fad604444f64c4f26f8ff702f3
@@ -0,0 +1 @@
+x��MN1@a�9����O���XqDZ��ʤ nB����<�~��|��9T�I�K��������ENV��� F��w��IԤ���f*K>b��&E6���e�D������x��9�U����:}����/@�d�TJ���_��͎[��~‡�}����Ƕ���}���jP�
\ No newline at end of file
diff --git a/maven-scm-plugin/src/test/resources/git/objects/ba/cd4ee105073117b30e5dcdba5150373b6b53c6 b/maven-scm-plugin/src/test/resources/git/objects/ba/cd4ee105073117b30e5dcdba5150373b6b53c6
new file mode 100644
index 0000000..fe99cd8
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/ba/cd4ee105073117b30e5dcdba5150373b6b53c6 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/c3/8b0351660113545db270ba6918cc22a9eb17ce b/maven-scm-plugin/src/test/resources/git/objects/c3/8b0351660113545db270ba6918cc22a9eb17ce
new file mode 100644
index 0000000..bb5b1d5
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/c3/8b0351660113545db270ba6918cc22a9eb17ce differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/c5/1dcd33e7b71897603c203b5e0afc1d75f70051 b/maven-scm-plugin/src/test/resources/git/objects/c5/1dcd33e7b71897603c203b5e0afc1d75f70051
new file mode 100644
index 0000000..ec76cb0
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/c5/1dcd33e7b71897603c203b5e0afc1d75f70051 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/dc/4204852765c12f398ef4a5fbcabf23cf17a183 b/maven-scm-plugin/src/test/resources/git/objects/dc/4204852765c12f398ef4a5fbcabf23cf17a183
new file mode 100644
index 0000000..2234dd6
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/dc/4204852765c12f398ef4a5fbcabf23cf17a183 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/f7/1429f9ff9214a546b438c611ae942c9cf5a49e b/maven-scm-plugin/src/test/resources/git/objects/f7/1429f9ff9214a546b438c611ae942c9cf5a49e
new file mode 100644
index 0000000..b543850
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/f7/1429f9ff9214a546b438c611ae942c9cf5a49e differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/fd/39fa3de0f63bc5c78eca219e74e0a8531bd3e6 b/maven-scm-plugin/src/test/resources/git/objects/fd/39fa3de0f63bc5c78eca219e74e0a8531bd3e6
new file mode 100644
index 0000000..1497fff
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/fd/39fa3de0f63bc5c78eca219e74e0a8531bd3e6 differ
diff --git a/maven-scm-plugin/src/test/resources/git/objects/fe/a16119a5b4ec0562d4f65b4237314250773bf8 b/maven-scm-plugin/src/test/resources/git/objects/fe/a16119a5b4ec0562d4f65b4237314250773bf8
new file mode 100644
index 0000000..6c36970
Binary files /dev/null and b/maven-scm-plugin/src/test/resources/git/objects/fe/a16119a5b4ec0562d4f65b4237314250773bf8 differ
diff --git a/maven-scm-plugin/src/test/resources/git/refs/heads/master b/maven-scm-plugin/src/test/resources/git/refs/heads/master
new file mode 100644
index 0000000..d262065
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/refs/heads/master
@@ -0,0 +1 @@
+92f139dfec4d1dfb79c3cd2f94e83bf13129668b
diff --git a/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/HEAD b/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/HEAD
new file mode 100644
index 0000000..6efe28f
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/HEAD
@@ -0,0 +1 @@
+ref: refs/remotes/origin/master
diff --git a/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/master b/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/master
new file mode 100644
index 0000000..b1c9092
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/git/refs/remotes/origin/master
@@ -0,0 +1 @@
+c51dcd33e7b71897603c203b5e0afc1d75f70051
diff --git a/maven-scm-plugin/src/test/resources/mojos/untag/checkout-tag.xml b/maven-scm-plugin/src/test/resources/mojos/untag/checkout-tag.xml
new file mode 100644
index 0000000..cbfad7b
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/mojos/untag/checkout-tag.xml
@@ -0,0 +1,36 @@
+<!--
+  ~ 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.
+  -->
+
+<project>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-scm-plugin</artifactId>
+        <configuration>
+          <settings implementation="org.apache.maven.settings.Settings"/>
+          <checkoutDirectory>target/tags/mytag</checkoutDirectory>
+          <connectionType>connection</connectionType>
+          <scmVersion>mytag</scmVersion>
+          <scmVersionType>tag</scmVersionType>
+          <connectionUrl>scm:git:file:///${basedir}/src/test/resources/git</connectionUrl>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/maven-scm-plugin/src/test/resources/mojos/untag/checkout.xml b/maven-scm-plugin/src/test/resources/mojos/untag/checkout.xml
new file mode 100644
index 0000000..60ca181
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/mojos/untag/checkout.xml
@@ -0,0 +1,34 @@
+<!--
+  ~ 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.
+  -->
+
+<project>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-scm-plugin</artifactId>
+        <configuration>
+          <settings implementation="org.apache.maven.settings.Settings"/>
+          <checkoutDirectory>target/tags/mytag</checkoutDirectory>
+          <connectionType>connection</connectionType>
+          <connectionUrl>scm:git:file:///${basedir}/src/test/resources/git</connectionUrl>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/maven-scm-plugin/src/test/resources/mojos/untag/tag.xml b/maven-scm-plugin/src/test/resources/mojos/untag/tag.xml
new file mode 100644
index 0000000..e23c55b
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/mojos/untag/tag.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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.
+  -->
+
+<project>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-scm-plugin</artifactId>
+        <configuration>
+          <settings implementation="org.apache.maven.settings.Settings"/>
+          <connectionUrl>scm:git:file:///${basedir}/src/test/resources/git</connectionUrl>
+          <connectionType>connection</connectionType>
+          <tag>mytag</tag>
+          <pushChanges>true</pushChanges>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/maven-scm-plugin/src/test/resources/mojos/untag/untag.xml b/maven-scm-plugin/src/test/resources/mojos/untag/untag.xml
new file mode 100644
index 0000000..e23c55b
--- /dev/null
+++ b/maven-scm-plugin/src/test/resources/mojos/untag/untag.xml
@@ -0,0 +1,35 @@
+<!--
+  ~ 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.
+  -->
+
+<project>
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-scm-plugin</artifactId>
+        <configuration>
+          <settings implementation="org.apache.maven.settings.Settings"/>
+          <connectionUrl>scm:git:file:///${basedir}/src/test/resources/git</connectionUrl>
+          <connectionType>connection</connectionType>
+          <tag>mytag</tag>
+          <pushChanges>true</pushChanges>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
\ No newline at end of file
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/main/java/org/apache/maven/scm/provider/git/AbstractGitScmProvider.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/main/java/org/apache/maven/scm/provider/git/AbstractGitScmProvider.java
index dbeadac..73a879c 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/main/java/org/apache/maven/scm/provider/git/AbstractGitScmProvider.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/main/java/org/apache/maven/scm/provider/git/AbstractGitScmProvider.java
@@ -40,11 +40,13 @@ import org.apache.maven.scm.command.remoteinfo.RemoteInfoScmResult;
 import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.command.status.StatusScmResult;
 import org.apache.maven.scm.command.tag.TagScmResult;
+import org.apache.maven.scm.command.untag.UntagScmResult;
 import org.apache.maven.scm.command.update.UpdateScmResult;
 import org.apache.maven.scm.provider.AbstractScmProvider;
 import org.apache.maven.scm.provider.ScmProviderRepository;
 import org.apache.maven.scm.provider.git.command.GitCommand;
 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
+import org.apache.maven.scm.repository.ScmRepository;
 import org.apache.maven.scm.repository.ScmRepositoryException;
 import org.apache.maven.scm.repository.UnknownRepositoryStructure;
 
@@ -272,6 +274,16 @@ public abstract class AbstractGitScmProvider
         return (TagScmResult) executeCommand( getTagCommand(), repository, fileSet, parameters );
     }
 
+    protected abstract GitCommand getUntagCommand();
+
+    /** {@inheritDoc} */
+    public UntagScmResult untag( ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters )
+        throws ScmException
+    {
+        return (UntagScmResult) executeCommand( getUntagCommand(),
+            repository.getProviderRepository(), fileSet, parameters );
+    }
+
     protected abstract GitCommand getUpdateCommand();
 
     /** {@inheritDoc} */
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/test/java/org/apache/maven/scm/provider/git/TestGitScmProvider.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/test/java/org/apache/maven/scm/provider/git/TestGitScmProvider.java
index 3f07e9a..d1f231a 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/test/java/org/apache/maven/scm/provider/git/TestGitScmProvider.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-git-commons/src/test/java/org/apache/maven/scm/provider/git/TestGitScmProvider.java
@@ -76,6 +76,11 @@ public class TestGitScmProvider
         return null;
     }
 
+    protected GitCommand getUntagCommand()
+    {
+        return null;
+    }
+
     protected GitCommand getUpdateCommand()
     {
         return null;
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/GitExeScmProvider.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/GitExeScmProvider.java
index 2096cad..9cb4334 100644
--- a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/GitExeScmProvider.java
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/GitExeScmProvider.java
@@ -38,6 +38,7 @@ import org.apache.maven.scm.provider.git.gitexe.command.remoteinfo.GitRemoteInfo
 import org.apache.maven.scm.provider.git.gitexe.command.remove.GitRemoveCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.status.GitStatusCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.tag.GitTagCommand;
+import org.apache.maven.scm.provider.git.gitexe.command.untag.GitUntagCommand;
 import org.apache.maven.scm.provider.git.gitexe.command.update.GitUpdateCommand;
 import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
 import org.apache.maven.scm.repository.ScmRepositoryException;
@@ -111,6 +112,12 @@ public class GitExeScmProvider
     }
 
     /** {@inheritDoc} */
+    protected GitCommand getUntagCommand()
+    {
+        return new GitUntagCommand();
+    }
+
+    /** {@inheritDoc} */
     protected GitCommand getUpdateCommand()
     {
         return new GitUpdateCommand();
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/untag/GitUntagCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/untag/GitUntagCommand.java
new file mode 100644
index 0000000..8c8798d
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/main/java/org/apache/maven/scm/provider/git/gitexe/command/untag/GitUntagCommand.java
@@ -0,0 +1,110 @@
+package org.apache.maven.scm.provider.git.gitexe.command.untag;
+
+/*
+ * 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.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.untag.AbstractUntagCommand;
+import org.apache.maven.scm.command.untag.UntagScmResult;
+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.repository.GitScmProviderRepository;
+import org.codehaus.plexus.util.StringUtils;
+import org.codehaus.plexus.util.cli.CommandLineUtils;
+import org.codehaus.plexus.util.cli.Commandline;
+
+/** {@inheritDoc} */
+public class GitUntagCommand
+    extends AbstractUntagCommand
+    implements GitCommand
+{
+
+    /** {@inheritDoc} */
+    public ScmResult executeUntagCommand( ScmProviderRepository repo, ScmFileSet fileSet, String tag )
+        throws ScmException
+    {
+        if ( tag == null || StringUtils.isEmpty( tag.trim() ) )
+        {
+            throw new ScmException( "tag name must be specified" );
+        }
+
+        GitScmProviderRepository repository = (GitScmProviderRepository) repo;
+
+        CommandLineUtils.StringStreamConsumer stdout = new CommandLineUtils.StringStreamConsumer();
+        CommandLineUtils.StringStreamConsumer stderr = new CommandLineUtils.StringStreamConsumer();
+
+        int exitCode;
+
+        Commandline clTag = createCommandLine( repository, fileSet.getBasedir(), tag );
+
+        exitCode = GitCommandLineUtils.execute( clTag, stdout, stderr, getLogger() );
+        if ( exitCode != 0 )
+        {
+            return new UntagScmResult( clTag.toString(), "The git-tag command failed.", stderr.getOutput(), false );
+        }
+
+        if ( repo.isPushChanges() )
+        {
+            // and now push the tag to the configured upstream repository
+            Commandline clPush = createPushCommandLine( repository, fileSet, tag );
+
+            exitCode = GitCommandLineUtils.execute( clPush, stdout, stderr, getLogger() );
+            if ( exitCode != 0 )
+            {
+                return new UntagScmResult( clPush.toString(), "The git-push command failed.", stderr.getOutput(),
+                                         false );
+            }
+        }
+
+        return new UntagScmResult( clTag.toString() );
+    }
+
+    // ----------------------------------------------------------------------
+    //
+    // ----------------------------------------------------------------------
+
+    public static Commandline createCommandLine( GitScmProviderRepository repository, File workingDirectory,
+                                                 String tag )
+    {
+        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( workingDirectory, "tag" );
+
+        cl.createArg().setValue( "-d" );
+        cl.createArg().setValue( tag );
+
+        return cl;
+    }
+
+    public static Commandline createPushCommandLine( GitScmProviderRepository repository, ScmFileSet fileSet,
+                                                     String tag )
+    {
+        Commandline cl = GitCommandLineUtils.getBaseGitCommandLine( fileSet.getBasedir(), "push" );
+
+        cl.createArg().setValue( "--delete" );
+        cl.createArg().setValue( repository.getPushUrl() );
+        cl.createArg().setValue( "refs/tags/" + tag );
+
+        return cl;
+    }
+
+}
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/untag/GitExeUntagCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gitexe/src/test/java/org/apache/maven/scm/provider/git/gitexe/command/untag/GitExeUntagCommandTckTest.java
new file mode 100644
index 0000000..0a19847
--- /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/untag/GitExeUntagCommandTckTest.java
@@ -0,0 +1,34 @@
+package org.apache.maven.scm.provider.git.gitexe.command.untag;
+
+/*
+ * 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.provider.git.command.untag.GitUntagCommandTckTest;
+
+public class GitExeUntagCommandTckTest
+    extends GitUntagCommandTckTest
+{
+        /** {@inheritDoc} */
+        public String getScmUrl()
+            throws Exception
+        {
+            return GitScmTestUtils.getScmUrl( getRepositoryRoot(), "git" );
+        }
+}
diff --git a/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/untag/GitUntagCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/untag/GitUntagCommandTckTest.java
new file mode 100644
index 0000000..7eff053
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-gittest/src/main/java/org/apache/maven/scm/provider/git/command/untag/GitUntagCommandTckTest.java
@@ -0,0 +1,51 @@
+package org.apache.maven.scm.provider.git.command.untag;
+
+/*
+ * 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.GitScmTestUtils;
+import org.apache.maven.scm.repository.ScmRepository;
+import org.apache.maven.scm.tck.command.untag.UntagCommandTckTest;
+
+/** {@inheritDoc} */
+public abstract class GitUntagCommandTckTest
+    extends UntagCommandTckTest
+{
+    /** {@inheritDoc} */
+    public void initRepo()
+        throws Exception
+    {
+        GitScmTestUtils.initRepo( "src/test/resources/repository/", getRepositoryRoot(), getWorkingDirectory() );
+    }
+
+    @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-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 b155dea..0c6d351 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
@@ -39,6 +39,7 @@ 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.status.JGitStatusCommand;
 import org.apache.maven.scm.provider.git.jgit.command.tag.JGitTagCommand;
+import org.apache.maven.scm.provider.git.jgit.command.untag.JGitUntagCommand;
 import org.apache.maven.scm.repository.ScmRepositoryException;
 
 /**
@@ -133,6 +134,14 @@ public class JGitScmProvider
     /**
      * {@inheritDoc}
      */
+    protected GitCommand getUntagCommand()
+    {
+        return new JGitUntagCommand();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
     protected GitCommand getUpdateCommand()
     {
         throw new UnsupportedOperationException( "getUpdateCommand" );
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/untag/JGitUntagCommand.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/main/java/org/apache/maven/scm/provider/git/jgit/command/untag/JGitUntagCommand.java
new file mode 100644
index 0000000..3cc629e
--- /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/untag/JGitUntagCommand.java
@@ -0,0 +1,102 @@
+package org.apache.maven.scm.provider.git.jgit.command.untag;
+
+/*
+ * 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.Collection;
+
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmResult;
+import org.apache.maven.scm.command.untag.AbstractUntagCommand;
+import org.apache.maven.scm.command.untag.UntagScmResult;
+import org.apache.maven.scm.log.ScmLogger;
+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.apache.maven.scm.provider.git.repository.GitScmProviderRepository;
+import org.codehaus.plexus.util.StringUtils;
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.transport.PushResult;
+import org.eclipse.jgit.transport.RefSpec;
+import org.eclipse.jgit.transport.RemoteRefUpdate;
+
+/** {@inheritDoc} */
+public class JGitUntagCommand extends AbstractUntagCommand implements GitCommand
+{
+
+    @Override
+    protected ScmResult executeUntagCommand( ScmProviderRepository repository, ScmFileSet fileSet,
+        String tagName ) throws ScmException
+    {
+        if ( tagName == null || StringUtils.isEmpty( tagName.trim() ) )
+        {
+            throw new ScmException( "tag name must be specified" );
+        }
+        String escapedTagName = tagName.trim().replace( ' ', '_' );
+
+        Git git = null;
+        try
+        {
+            git = JGitUtils.openRepo( fileSet.getBasedir() );
+
+            // delete the tag
+            if ( git.tagDelete().setTags( escapedTagName ).call().isEmpty() )
+            {
+                return new UntagScmResult( "JGit tagDelete", "Failed to delete tag", "", false );
+            }
+
+            if ( repository.isPushChanges() )
+            {
+                // From https://stackoverflow.com/q/11892766/696632
+                RefSpec refSpec = new RefSpec()
+                    .setSource( null )
+                    .setDestination( Constants.R_TAGS + escapedTagName );
+
+                getLogger().info( "push delete tag [" + escapedTagName + "] to remote..." );
+                ScmLogger logger = getLogger();
+
+                Iterable<PushResult> pushResultList
+                        = JGitUtils.push( logger, git, (GitScmProviderRepository) repository, refSpec );
+                if ( logger.isInfoEnabled() )
+                {
+                    for ( PushResult pushResult : pushResultList )
+                    {
+                        Collection<RemoteRefUpdate> ru = pushResult.getRemoteUpdates();
+                        for ( RemoteRefUpdate remoteRefUpdate : ru )
+                        {
+                            logger.info( remoteRefUpdate.getStatus() + " - " + remoteRefUpdate );
+                        }
+                    }
+                }
+            }
+
+            return new UntagScmResult( "JGit tagDelete" );
+        }
+        catch ( Exception e )
+        {
+            throw new ScmException( "JGit tagDelete 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/untag/JGitUntagCommandTckTest.java b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/untag/JGitUntagCommandTckTest.java
new file mode 100644
index 0000000..268ef41
--- /dev/null
+++ b/maven-scm-providers/maven-scm-providers-git/maven-scm-provider-jgit/src/test/java/org/apache/maven/scm/provider/git/jgit/command/untag/JGitUntagCommandTckTest.java
@@ -0,0 +1,52 @@
+package org.apache.maven.scm.provider.git.jgit.command.untag;
+
+/*
+ * 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.io.IOException;
+import org.apache.maven.scm.provider.git.GitScmTestUtils;
+import org.apache.maven.scm.provider.git.command.untag.GitUntagCommandTckTest;
+import org.eclipse.jgit.util.FileUtils;
+
+/**
+ * This test tests the untag command.
+ */
+public class JGitUntagCommandTckTest
+    extends GitUntagCommandTckTest
+{
+    /**
+     * {@inheritDoc}
+     */
+    public String getScmUrl()
+        throws Exception
+    {
+        return GitScmTestUtils.getScmUrl( getRepositoryRoot(), "jgit" );
+    }
+
+    @Override
+    protected void deleteDirectory( File directory )
+        throws IOException
+    {
+        if ( directory.exists() )
+        {
+            FileUtils.delete( directory, FileUtils.RECURSIVE | FileUtils.RETRY );
+        }
+    }
+}
diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/provider/ScmProviderStub.java b/maven-scm-test/src/main/java/org/apache/maven/scm/provider/ScmProviderStub.java
index 9edf2c2..2b6c284 100644
--- a/maven-scm-test/src/main/java/org/apache/maven/scm/provider/ScmProviderStub.java
+++ b/maven-scm-test/src/main/java/org/apache/maven/scm/provider/ScmProviderStub.java
@@ -46,6 +46,7 @@ import org.apache.maven.scm.command.remove.RemoveScmResult;
 import org.apache.maven.scm.command.status.StatusScmResult;
 import org.apache.maven.scm.command.tag.TagScmResult;
 import org.apache.maven.scm.command.unedit.UnEditScmResult;
+import org.apache.maven.scm.command.untag.UntagScmResult;
 import org.apache.maven.scm.command.update.UpdateScmResult;
 import org.apache.maven.scm.log.ScmLogger;
 import org.apache.maven.scm.repository.ScmRepository;
@@ -113,6 +114,8 @@ public class ScmProviderStub
 
     private MkdirScmResult mkdirScmResult;
 
+    private UntagScmResult untagScmResult;
+
     /**
      * Create a new ScmProviderStub with bogus (not null) attributes
      */
@@ -131,6 +134,7 @@ public class ScmProviderStub
         setStatusScmResult( new StatusScmResult( "", "", "", true ) );
         setTagScmResult( new TagScmResult( "", "", "", true ) );
         setUnEditScmResult( new UnEditScmResult( "", "", "", true ) );
+        setUntagScmResult( new UntagScmResult( "", "", "", true ) );
         setUpdateScmResult( new UpdateScmResult( "", "", "", true ) );
         setBlameScmResult( new BlameScmResult( "", "", "", true ) );
         setMkdirScmResult( new MkdirScmResult( "", "", "", true ) );
@@ -258,6 +262,16 @@ public class ScmProviderStub
         return tagScmResult;
     }
 
+    public void setUntagScmResult( UntagScmResult untagScmResult )
+    {
+        this.untagScmResult = untagScmResult;
+    }
+
+    public UntagScmResult getUntagScmResult()
+    {
+        return untagScmResult;
+    }
+
     public void setRemoveScmResult( RemoveScmResult removeScmResult )
     {
         this.removeScmResult = removeScmResult;
@@ -745,6 +759,12 @@ public class ScmProviderStub
         return getTagScmResult();
     }
 
+    public UntagScmResult untag( ScmRepository repository, ScmFileSet fileSet, CommandParameters parameters )
+        throws ScmException
+    {
+        return getUntagScmResult();
+    }
+
     /**
      * {@inheritDoc}
      */
diff --git a/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/untag/UntagCommandTckTest.java b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/untag/UntagCommandTckTest.java
new file mode 100644
index 0000000..2968cac
--- /dev/null
+++ b/maven-scm-test/src/main/java/org/apache/maven/scm/tck/command/untag/UntagCommandTckTest.java
@@ -0,0 +1,84 @@
+package org.apache.maven.scm.tck.command.untag;
+
+/*
+ * 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.CommandParameter;
+import org.apache.maven.scm.CommandParameters;
+import org.apache.maven.scm.ScmException;
+import org.apache.maven.scm.ScmFileSet;
+import org.apache.maven.scm.ScmTag;
+import org.apache.maven.scm.ScmTagParameters;
+import org.apache.maven.scm.ScmTckTestCase;
+import org.apache.maven.scm.command.checkout.CheckOutScmResult;
+import org.apache.maven.scm.command.tag.TagScmResult;
+import org.apache.maven.scm.command.untag.UntagScmResult;
+import org.apache.maven.scm.provider.ScmProvider;
+import org.apache.maven.scm.repository.ScmRepository;
+
+/**
+ * This test tests the untag command.
+ */
+public abstract class UntagCommandTckTest
+    extends ScmTckTestCase
+{
+
+    protected String getTagName()
+    {
+        return "test-untag";
+    }
+
+    public void testUntagCommandTest()
+        throws Exception
+    {
+        String tag = getTagName();
+        ScmProvider scmProvider = getScmManager().getProviderByUrl( getScmUrl() );
+        ScmRepository scmRepository = getScmRepository();
+        ScmFileSet files = new ScmFileSet( getWorkingCopy() );
+        TagScmResult tagResult = scmProvider.tag( scmRepository, files, tag, new ScmTagParameters() );
+
+        assertResultIsSuccess( tagResult );
+        CommandParameters params = new CommandParameters();
+        params.setString( CommandParameter.TAG_NAME, tag );
+
+        UntagScmResult untagResult = scmProvider.untag( scmRepository, files, params );
+
+        assertResultIsSuccess( untagResult );
+
+        try
+        {
+            untagResult = scmProvider.untag( scmRepository, files, params );
+            assertFalse( untagResult.isSuccess() ); // already been deleted
+        }
+        catch ( ScmException ignored )
+        {
+        }
+
+        try
+        {
+            CheckOutScmResult checkoutResult =
+                getScmManager().checkOut( scmRepository, new ScmFileSet( getAssertionCopy() ), new ScmTag( tag ) );
+            assertFalse( checkoutResult.isSuccess() ); // can't check out a deleted tags
+        }
+        catch ( ScmException ignored )
+        {
+        }
+    }
+
+}