diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RmCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RmCommandTest.java new file mode 100644 index 000000000..3283971d4 --- /dev/null +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RmCommandTest.java @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2010, Chris Aniszczyk + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.api; + +import java.io.IOException; + +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.api.errors.NoFilepatternException; +import org.eclipse.jgit.lib.RepositoryTestCase; + +public class RmCommandTest extends RepositoryTestCase { + + private Git git; + + private static final String FILE = "test.txt"; + + @Override + protected void setUp() throws Exception { + super.setUp(); + git = new Git(db); + // commit something + writeTrashFile(FILE, "Hello world"); + git.add().addFilepattern(FILE).call(); + git.commit().setMessage("Initial commit").call(); + } + + public void testRemove() throws JGitInternalException, + NoFilepatternException, IllegalStateException, IOException { + assertEquals("[test.txt, mode:100644, content:Hello world]", + indexState(CONTENT)); + RmCommand command = git.rm(); + command.addFilepattern(FILE); + command.call(); + assertEquals("", indexState(CONTENT)); + } + +} diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties index e05500e0a..4de5744c8 100644 --- a/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties +++ b/org.eclipse.jgit/resources/org/eclipse/jgit/JGitText.properties @@ -167,6 +167,7 @@ exceptionCaughtDuringExecutionOfFetchCommand=Exception caught during execution o exceptionCaughtDuringExecutionOfMergeCommand=Exception caught during execution of merge command. {0} exceptionCaughtDuringExecutionOfPushCommand=Exception caught during execution of push command exceptionCaughtDuringExecutionOfPullCommand=Exception caught during execution of pull command +exceptionCaughtDuringExecutionOfRmCommand=Exception caught during execution of rm command exceptionCaughtDuringExecutionOfTagCommand=Exception caught during execution of tag command exceptionOccuredDuringAddingOfOptionToALogCommand=Exception occured during adding of {0} as option to a Log command exceptionOccuredDuringReadingOfGIT_DIR=Exception occured during reading of $GIT_DIR/{0}. {1} diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java index 9c4717a81..6ec8ed69e 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/JGitText.java @@ -227,6 +227,7 @@ public class JGitText extends TranslationBundle { /***/ public String exceptionCaughtDuringExecutionOfMergeCommand; /***/ public String exceptionCaughtDuringExecutionOfPushCommand; /***/ public String exceptionCaughtDuringExecutionOfPullCommand; + /***/ public String exceptionCaughtDuringExecutionOfRmCommand; /***/ public String exceptionCaughtDuringExecutionOfTagCommand; /***/ public String exceptionOccuredDuringAddingOfOptionToALogCommand; /***/ public String exceptionOccuredDuringReadingOfGIT_DIR; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java index 2ed173ada..3bcdfc7aa 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/Git.java @@ -256,6 +256,19 @@ public class Git { return new RebaseCommand(repo); } + /** + * Returns a command object to execute a {@code rm} command + * + * @see Git documentation about rm + * @return a {@link RmCommand} used to collect all optional parameters and + * to finally execute the {@code rm} command + */ + public RmCommand rm() { + return new RmCommand(repo); + } + /** * @return the git repository this class is interacting with */ diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java new file mode 100644 index 000000000..98695f3a9 --- /dev/null +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RmCommand.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2010, Chris Aniszczyk + * and other copyright owners as documented in the project's IP log. + * + * This program and the accompanying materials are made available + * under the terms of the Eclipse Distribution License v1.0 which + * accompanies this distribution, is reproduced below, and is + * available at http://www.eclipse.org/org/documents/edl-v10.php + * + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * + * - Neither the name of the Eclipse Foundation, Inc. nor the + * names of its contributors may be used to endorse or promote + * products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.eclipse.jgit.api; + +import java.io.File; +import java.io.IOException; +import java.util.Collection; +import java.util.LinkedList; + +import org.eclipse.jgit.JGitText; +import org.eclipse.jgit.api.errors.JGitInternalException; +import org.eclipse.jgit.api.errors.NoFilepatternException; +import org.eclipse.jgit.dircache.DirCache; +import org.eclipse.jgit.dircache.DirCacheBuildIterator; +import org.eclipse.jgit.dircache.DirCacheBuilder; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.treewalk.filter.PathFilterGroup; + +/** + * A class used to execute a {@code Rm} command. It has setters for all + * supported options and arguments of this command and a {@link #call()} method + * to finally execute the command. Each instance of this class should only be + * used for one invocation of the command (means: one call to {@link #call()}) + * + * @see Git documentation about Rm + */ +public class RmCommand extends GitCommand { + + private Collection filepatterns; + + /** + * + * @param repo + */ + public RmCommand(Repository repo) { + super(repo); + filepatterns = new LinkedList(); + } + + /** + * @param filepattern + * File to remove. + * @return {@code this} + */ + public RmCommand addFilepattern(String filepattern) { + checkCallable(); + filepatterns.add(filepattern); + return this; + } + + /** + * Executes the {@code Rm} command. Each instance of this class should only + * be used for one invocation of the command. Don't call this method twice + * on an instance. + * + * @return the DirCache after Rm + */ + public DirCache call() throws NoFilepatternException { + + if (filepatterns.isEmpty()) + throw new NoFilepatternException(JGitText.get().atLeastOnePatternIsRequired); + checkCallable(); + DirCache dc = null; + + try { + dc = repo.lockDirCache(); + DirCacheBuilder builder = dc.builder(); + final TreeWalk tw = new TreeWalk(repo); + tw.reset(); // drop the first empty tree, which we do not need here + tw.setRecursive(true); + tw.setFilter(PathFilterGroup.createFromStrings(filepatterns)); + tw.addTree(new DirCacheBuildIterator(builder)); + + while (tw.next()) { + final File path = new File(repo.getWorkTree(), + tw.getPathString()); + final FileMode mode = tw.getFileMode(0); + if (mode.getObjectType() == Constants.OBJ_BLOB) { + // Deleting a blob is simply a matter of removing + // the file or symlink named by the tree entry. + delete(path); + } + } + builder.commit(); + setCallable(false); + } catch (IOException e) { + throw new JGitInternalException( + JGitText.get().exceptionCaughtDuringExecutionOfRmCommand, e); + } finally { + if (dc != null) + dc.unlock(); + } + + return dc; + } + + private void delete(File p) { + while (p != null && !p.equals(repo.getWorkTree()) && p.delete()) + p = p.getParentFile(); + } + +}