diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java index 4f6e2b85b..f76822ea5 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/ReadTreeTest.java @@ -615,11 +615,7 @@ public void testUntrackedConflicts() throws IOException { writeTrashFile("foo/blahblah", ""); go(); - // TODO: In DirCacheCheckout the following assertion would pass. But - // old WorkDirCheckout fails on this. For now I leave it out. Find out - // what's the correct behavior. - // assertConflict("foo"); - + assertConflict("foo"); assertConflict("foo/bar/baz"); assertConflict("foo/blahblah"); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckoutTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckoutTest.java deleted file mode 100644 index 1136d6a2c..000000000 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckoutTest.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2007, Dave Watson - * Copyright (C) 2006, Shawn O. Pearce - * 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.lib; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; - -import org.eclipse.jgit.errors.CheckoutConflictException; -import org.junit.Test; - -public class WorkDirCheckoutTest extends RepositoryTestCase { - @Test - public void testFindingConflicts() throws IOException { - GitIndex index = new GitIndex(db); - index.add(trash, writeTrashFile("bar", "bar")); - index.add(trash, writeTrashFile("foo/bar/baz/qux", "foo/bar")); - recursiveDelete(new File(trash, "bar")); - recursiveDelete(new File(trash, "foo")); - writeTrashFile("bar/baz/qux/foo", "another nasty one"); - writeTrashFile("foo", "troublesome little bugger"); - - WorkDirCheckout workDirCheckout = new WorkDirCheckout(db, trash, index, - index); - workDirCheckout.prescanOneTree(); - ArrayList conflictingEntries = workDirCheckout - .getConflicts(); - ArrayList removedEntries = workDirCheckout.getRemoved(); - assertEquals("bar/baz/qux/foo", conflictingEntries.get(0)); - assertEquals("foo", conflictingEntries.get(1)); - - GitIndex index2 = new GitIndex(db); - recursiveDelete(new File(trash, "bar")); - recursiveDelete(new File(trash, "foo")); - - index2.add(trash, writeTrashFile("bar/baz/qux/foo", "bar")); - index2.add(trash, writeTrashFile("foo", "lalala")); - - workDirCheckout = new WorkDirCheckout(db, trash, index2, index); - workDirCheckout.prescanOneTree(); - - conflictingEntries = workDirCheckout.getConflicts(); - removedEntries = workDirCheckout.getRemoved(); - assertTrue(conflictingEntries.isEmpty()); - assertTrue(removedEntries.contains("bar/baz/qux/foo")); - assertTrue(removedEntries.contains("foo")); - } - - @Test - public void testCheckingOutWithConflicts() throws IOException { - GitIndex index = new GitIndex(db); - index.add(trash, writeTrashFile("bar", "bar")); - index.add(trash, writeTrashFile("foo/bar/baz/qux", "foo/bar")); - recursiveDelete(new File(trash, "bar")); - recursiveDelete(new File(trash, "foo")); - writeTrashFile("bar/baz/qux/foo", "another nasty one"); - writeTrashFile("foo", "troublesome little bugger"); - - try { - WorkDirCheckout workDirCheckout = new WorkDirCheckout(db, trash, - index, index); - workDirCheckout.checkout(); - fail("Should have thrown exception"); - } catch (CheckoutConflictException e) { - // all is well - } - - WorkDirCheckout workDirCheckout = new WorkDirCheckout(db, trash, index, - index); - workDirCheckout.setFailOnConflict(false); - workDirCheckout.checkout(); - - assertTrue(new File(trash, "bar").isFile()); - assertTrue(new File(trash, "foo/bar/baz/qux").isFile()); - - GitIndex index2 = new GitIndex(db); - recursiveDelete(new File(trash, "bar")); - recursiveDelete(new File(trash, "foo")); - index2.add(trash, writeTrashFile("bar/baz/qux/foo", "bar")); - writeTrashFile("bar/baz/qux/bar", "evil? I thought it said WEEVIL!"); - index2.add(trash, writeTrashFile("foo", "lalala")); - - workDirCheckout = new WorkDirCheckout(db, trash, index2, index); - workDirCheckout.setFailOnConflict(false); - workDirCheckout.checkout(); - - assertTrue(new File(trash, "bar").isFile()); - assertTrue(new File(trash, "foo/bar/baz/qux").isFile()); - assertNotNull(index2.getEntry("bar")); - assertNotNull(index2.getEntry("foo/bar/baz/qux")); - assertNull(index2.getEntry("bar/baz/qux/foo")); - assertNull(index2.getEntry("foo")); - } -} diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckout_ReadTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckout_ReadTreeTest.java deleted file mode 100644 index c41a04cc9..000000000 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/lib/WorkDirCheckout_ReadTreeTest.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (C) 2010, Christian Halstrick - * 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.lib; - -import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; - -/** - * Test cases for ReadTree operations as implemented in WorkDirCheckout - */ -public class WorkDirCheckout_ReadTreeTest extends ReadTreeTest { - private WorkDirCheckout wdc; - public void prescanTwoTrees(Tree head, Tree merge) throws IllegalStateException, IOException { - wdc = new WorkDirCheckout(db, db.getWorkTree(), head, db.getIndex(), merge); - wdc.prescanTwoTrees(); - } - - public void checkout() throws IOException { - GitIndex index = db.getIndex(); - wdc = new WorkDirCheckout(db, db.getWorkTree(), theHead, index, theMerge); - wdc.checkout(); - index.write(); - } - - public ArrayList getRemoved() { - return wdc.getRemoved(); - } - - public HashMap getUpdated() { - return wdc.updated; - } - - public ArrayList getConflicts() { - return wdc.getConflicts(); - } -} - diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java index 8df583cc6..e3c225ff6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheCheckout.java @@ -74,12 +74,7 @@ import org.eclipse.jgit.util.FileUtils; /** - * This class handles checking out one or two trees merging with the index. This - * class does similar things as {@code WorkDirCheckout} but uses - * {@link DirCache} instead of {@code GitIndex} - *

- * The initial implementation of this class was refactored from - * WorkDirCheckout}. + * This class handles checking out one or two trees merging with the index. */ public class DirCacheCheckout { private Repository repo; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkDirCheckout.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkDirCheckout.java deleted file mode 100644 index beab61abe..000000000 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/WorkDirCheckout.java +++ /dev/null @@ -1,411 +0,0 @@ -/* - * Copyright (C) 2007, Dave Watson - * Copyright (C) 2008, Robin Rosenberg - * Copyright (C) 2008, Roger C. Soares - * Copyright (C) 2006, Shawn O. Pearce - * 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.lib; - -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.HashMap; - -import org.eclipse.jgit.JGitText; -import org.eclipse.jgit.errors.CheckoutConflictException; -import org.eclipse.jgit.lib.GitIndex.Entry; - -/** - * This class handles checking out one or two trees merging - * with the index (actually a tree too). - * - * Three-way merges are no performed. See {@link #setFailOnConflict(boolean)}. - * - * @deprecated Use org.eclipse.jgit.dircache.DirCacheCheckout. - */ -@Deprecated -public class WorkDirCheckout { - File root; - - GitIndex index; - - private boolean failOnConflict = true; - - Tree merge; - - - /** - * If true, will scan first to see if it's possible to check out, - * otherwise throw {@link CheckoutConflictException}. If false, - * it will silently deal with the problem. - * @param failOnConflict - */ - public void setFailOnConflict(boolean failOnConflict) { - this.failOnConflict = failOnConflict; - } - - WorkDirCheckout(Repository repo, File workDir, - GitIndex oldIndex, GitIndex newIndex) throws IOException { - this.root = workDir; - this.index = oldIndex; - this.merge = repo.mapTree(newIndex.writeTree()); - } - - /** - * Create a checkout class for checking out one tree, merging with the index - * - * @param repo - * @param root workdir - * @param index current index - * @param merge tree to check out - */ - public WorkDirCheckout(Repository repo, File root, - GitIndex index, Tree merge) { - this.root = root; - this.index = index; - this.merge = merge; - } - - /** - * Create a checkout class for merging and checking our two trees and the index. - * - * @param repo - * @param root workdir - * @param head - * @param index - * @param merge - */ - public WorkDirCheckout(Repository repo, File root, Tree head, GitIndex index, Tree merge) { - this(repo, root, index, merge); - this.head = head; - } - - /** - * Execute this checkout - * - * @throws IOException - */ - public void checkout() throws IOException { - if (head == null) - prescanOneTree(); - else prescanTwoTrees(); - if (!conflicts.isEmpty()) { - if (failOnConflict) { - String[] entries = conflicts.toArray(new String[0]); - throw new CheckoutConflictException(entries); - } - } - - cleanUpConflicts(); - if (head == null) - checkoutOutIndexNoHead(); - else checkoutTwoTrees(); - } - - private void checkoutTwoTrees() throws FileNotFoundException, IOException { - for (String path : removed) { - index.remove(root, new File(root, path)); - } - - for (java.util.Map.Entry entry : updated.entrySet()) { - Entry newEntry = index.addEntry(merge.findBlobMember(entry.getKey())); - index.checkoutEntry(root, newEntry); - } - } - - ArrayList conflicts = new ArrayList(); - ArrayList removed = new ArrayList(); - - Tree head = null; - - HashMap updated = new HashMap(); - - private void checkoutOutIndexNoHead() throws IOException { - new IndexTreeWalker(index, merge, root, new AbstractIndexTreeVisitor() { - public void visitEntry(TreeEntry m, Entry i, File f) throws IOException { - // TODO remove this once we support submodules - if (f.getName().equals(".gitmodules")) - throw new UnsupportedOperationException( - JGitText.get().submodulesNotSupported); - if (m == null) { - index.remove(root, f); - return; - } - - boolean needsCheckout = false; - if (i == null) - needsCheckout = true; - else if (i.getObjectId().equals(m.getId())) { - if (i.isModified(root, true)) - needsCheckout = true; - } else needsCheckout = true; - - if (needsCheckout) { - Entry newEntry = index.addEntry(m); - index.checkoutEntry(root, newEntry); - } - } - }).walk(); - } - - private void cleanUpConflicts() throws CheckoutConflictException { - for (String c : conflicts) { - File conflict = new File(root, c); - if (!conflict.delete()) - throw new CheckoutConflictException(MessageFormat.format(JGitText.get().cannotDeleteFile, c)); - removeEmptyParents(conflict); - } - for (String r : removed) { - File file = new File(root, r); - file.delete(); - removeEmptyParents(file); - } - } - - private void removeEmptyParents(File f) { - File parentFile = f.getParentFile(); - while (!parentFile.equals(root)) { - if (parentFile.list().length == 0) - parentFile.delete(); - else break; - - parentFile = parentFile.getParentFile(); - } - } - - void prescanOneTree() throws IOException { - new IndexTreeWalker(index, merge, root, new AbstractIndexTreeVisitor() { - public void visitEntry(TreeEntry m, Entry i, File file) throws IOException { - if (m != null) { - if (!file.isFile()) { - checkConflictsWithFile(file); - } - } else { - if (file.exists()) { - removed.add(i.getName()); - conflicts.remove(i.getName()); - } - } - } - }).walk(); - conflicts.removeAll(removed); - } - - private ArrayList listFiles(File file) { - ArrayList list = new ArrayList(); - listFiles(file, list); - return list; - } - - private void listFiles(File dir, ArrayList list) { - for (File f : dir.listFiles()) { - if (f.isDirectory()) - listFiles(f, list); - else { - list.add(Repository.stripWorkDir(root, f)); - } - } - } - - /** - * @return a list of conflicts created by this checkout - */ - public ArrayList getConflicts() { - return conflicts; - } - - /** - * @return a list of all files removed by this checkout - */ - public ArrayList getRemoved() { - return removed; - } - - void prescanTwoTrees() throws IOException { - new IndexTreeWalker(index, head, merge, root, new AbstractIndexTreeVisitor() { - public void visitEntry(TreeEntry treeEntry, TreeEntry auxEntry, - Entry indexEntry, File file) throws IOException { - if (treeEntry instanceof Tree || auxEntry instanceof Tree) { - throw new IllegalArgumentException(JGitText.get().cantPassMeATree); - } - processEntry(treeEntry, auxEntry, indexEntry); - } - - @Override - public void finishVisitTree(Tree tree, Tree auxTree, String curDir) throws IOException { - if (curDir.length() == 0) return; - - if (auxTree != null) { - if (index.getEntry(curDir) != null) - removed.add(curDir); - } - } - - }).walk(); - - // if there's a conflict, don't list it under - // to-be-removed, since that messed up our next - // section - removed.removeAll(conflicts); - - for (String path : updated.keySet()) { - if (index.getEntry(path) == null) { - File file = new File(root, path); - if (file.isFile()) - conflicts.add(path); - else if (file.isDirectory()) { - checkConflictsWithFile(file); - } - } - } - - - conflicts.removeAll(removed); - } - - void processEntry(TreeEntry h, TreeEntry m, Entry i) throws IOException { - ObjectId iId = (i == null ? null : i.getObjectId()); - ObjectId mId = (m == null ? null : m.getId()); - ObjectId hId = (h == null ? null : h.getId()); - - String name = (i != null ? i.getName() : - (h != null ? h.getFullName() : - m.getFullName())); - - if (i == null) { - /* - I (index) H M Result - ------------------------------------------------------- - 0 nothing nothing nothing (does not happen) - 1 nothing nothing exists use M - 2 nothing exists nothing remove path from index - 3 nothing exists exists use M */ - - if (h == null) { - updated.put(name,mId); - } else if (m == null) { - removed.add(name); - } else { - updated.put(name, mId); - } - } else if (h == null) { - /* - clean I==H I==M H M Result - ----------------------------------------------------- - 4 yes N/A N/A nothing nothing keep index - 5 no N/A N/A nothing nothing keep index - - 6 yes N/A yes nothing exists keep index - 7 no N/A yes nothing exists keep index - 8 yes N/A no nothing exists fail - 9 no N/A no nothing exists fail */ - - if (m == null || mId.equals(iId)) { - if (hasParentBlob(merge, name)) { - if (i.isModified(root, true)) { - conflicts.add(name); - } else { - removed.add(name); - } - } - } else { - conflicts.add(name); - } - } else if (m == null) { - /* - 10 yes yes N/A exists nothing remove path from index - 11 no yes N/A exists nothing fail - 12 yes no N/A exists nothing fail - 13 no no N/A exists nothing fail - */ - - if (hId.equals(iId)) { - if (i.isModified(root, true)) { - conflicts.add(name); - } else { - removed.add(name); - } - } else { - conflicts.add(name); - } - } else { - if (!hId.equals(mId) && !hId.equals(iId) - && !mId.equals(iId)) { - conflicts.add(name); - } else if (hId.equals(iId) && !mId.equals(iId)) { - if (i.isModified(root, true)) - conflicts.add(name); - else updated.put(name, mId); - } - } - } - - private boolean hasParentBlob(Tree t, String name) throws IOException { - if (name.indexOf("/") == -1) return false; - - String parent = name.substring(0, name.lastIndexOf("/")); - if (t.findBlobMember(parent) != null) - return true; - return hasParentBlob(t, parent); - } - - private void checkConflictsWithFile(File file) { - if (file.isDirectory()) { - ArrayList childFiles = listFiles(file); - conflicts.addAll(childFiles); - } else { - File parent = file.getParentFile(); - while (!parent.equals(root)) { - if (parent.isDirectory()) - break; - if (parent.isFile()) { - conflicts.add(Repository.stripWorkDir(root, parent)); - break; - } - parent = parent.getParentFile(); - } - } - } -}