|
|
@ -43,53 +43,51 @@ |
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
package org.eclipse.jgit.lib; |
|
|
|
package org.eclipse.jgit.lib; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.ByteArrayInputStream; |
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
|
|
|
|
import java.io.FileInputStream; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.io.InputStream; |
|
|
|
import java.util.ArrayList; |
|
|
|
import java.util.ArrayList; |
|
|
|
|
|
|
|
import java.util.Arrays; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.HashMap; |
|
|
|
|
|
|
|
|
|
|
|
import org.eclipse.jgit.errors.CheckoutConflictException; |
|
|
|
import org.eclipse.jgit.errors.CheckoutConflictException; |
|
|
|
|
|
|
|
import org.eclipse.jgit.errors.CorruptObjectException; |
|
|
|
|
|
|
|
import org.eclipse.jgit.treewalk.FileTreeIterator; |
|
|
|
|
|
|
|
import org.eclipse.jgit.treewalk.TreeWalk; |
|
|
|
|
|
|
|
import org.eclipse.jgit.util.FS; |
|
|
|
|
|
|
|
|
|
|
|
public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
public abstract class ReadTreeTest extends RepositoryTestCase { |
|
|
|
|
|
|
|
protected Tree theHead; |
|
|
|
|
|
|
|
protected Tree theMerge; |
|
|
|
|
|
|
|
|
|
|
|
private Tree theHead; |
|
|
|
|
|
|
|
private Tree theMerge; |
|
|
|
|
|
|
|
private GitIndex theIndex; |
|
|
|
|
|
|
|
private Checkout theReadTree; |
|
|
|
|
|
|
|
// Each of these rules are from the read-tree manpage
|
|
|
|
// Each of these rules are from the read-tree manpage
|
|
|
|
// go there to see what they mean.
|
|
|
|
// go there to see what they mean.
|
|
|
|
// Rule 0 is left out for obvious reasons :)
|
|
|
|
// Rule 0 is left out for obvious reasons :)
|
|
|
|
public void testRules1thru3_NoIndexEntry() throws IOException { |
|
|
|
public void testRules1thru3_NoIndexEntry() throws IOException { |
|
|
|
GitIndex index = new GitIndex(db); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tree head = new Tree(db); |
|
|
|
Tree head = new Tree(db); |
|
|
|
FileTreeEntry headFile = head.addFile("foo"); |
|
|
|
FileTreeEntry headFile = head.addFile("foo"); |
|
|
|
ObjectId objectId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18e9"); |
|
|
|
ObjectId objectId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18e9"); |
|
|
|
headFile.setId(objectId); |
|
|
|
headFile.setId(objectId); |
|
|
|
Tree merge = new Tree(db); |
|
|
|
Tree merge = new Tree(db); |
|
|
|
|
|
|
|
|
|
|
|
Checkout readTree = getCheckoutImpl(head, index, merge); |
|
|
|
prescanTwoTrees(head, merge); |
|
|
|
readTree.prescanTwoTrees(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertTrue(readTree.removed().contains("foo")); |
|
|
|
assertTrue(getRemoved().contains("foo")); |
|
|
|
|
|
|
|
|
|
|
|
readTree = getCheckoutImpl(merge, index, head); |
|
|
|
prescanTwoTrees(merge, head); |
|
|
|
readTree.prescanTwoTrees(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(objectId, readTree.updated().get("foo")); |
|
|
|
assertEquals(objectId, getUpdated().get("foo")); |
|
|
|
|
|
|
|
|
|
|
|
ObjectId anotherId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18ee"); |
|
|
|
ObjectId anotherId = ObjectId.fromString("ba78e065e2c261d4f7b8f42107588051e87e18ee"); |
|
|
|
merge.addFile("foo").setId(anotherId); |
|
|
|
merge.addFile("foo").setId(anotherId); |
|
|
|
|
|
|
|
|
|
|
|
readTree = getCheckoutImpl(head, index, merge); |
|
|
|
prescanTwoTrees(head, merge); |
|
|
|
readTree.prescanTwoTrees(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertEquals(anotherId, readTree.updated().get("foo")); |
|
|
|
assertEquals(anotherId, getUpdated().get("foo")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void setupCase(HashMap<String, String> headEntries, |
|
|
|
void setupCase(HashMap<String, String> headEntries, |
|
|
@ -97,28 +95,36 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
HashMap<String, String> indexEntries) throws IOException { |
|
|
|
HashMap<String, String> indexEntries) throws IOException { |
|
|
|
theHead = buildTree(headEntries); |
|
|
|
theHead = buildTree(headEntries); |
|
|
|
theMerge = buildTree(mergeEntries); |
|
|
|
theMerge = buildTree(mergeEntries); |
|
|
|
theIndex = buildIndex(indexEntries); |
|
|
|
buildIndex(indexEntries); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private GitIndex buildIndex(HashMap<String, String> indexEntries) throws IOException { |
|
|
|
private void buildIndex(HashMap<String, String> indexEntries) throws IOException { |
|
|
|
GitIndex index = new GitIndex(db); |
|
|
|
GitIndex index = new GitIndex(db); |
|
|
|
|
|
|
|
|
|
|
|
if (indexEntries == null) |
|
|
|
if (indexEntries != null) { |
|
|
|
return index; |
|
|
|
for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) { |
|
|
|
for (java.util.Map.Entry<String,String> e : indexEntries.entrySet()) { |
|
|
|
index.add(trash, writeTrashFile(e.getKey(), e.getValue())).forceRecheck(); |
|
|
|
index.add(trash, writeTrashFile(e.getKey(), e.getValue())).forceRecheck(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return index; |
|
|
|
index.write(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Tree buildTree(HashMap<String, String> headEntries) throws IOException { |
|
|
|
private Tree buildTree(HashMap<String, String> headEntries) throws IOException { |
|
|
|
Tree tree = new Tree(db); |
|
|
|
Tree tree = new Tree(db); |
|
|
|
|
|
|
|
ObjectWriter ow = new ObjectWriter(db); |
|
|
|
if (headEntries == null) |
|
|
|
if (headEntries == null) |
|
|
|
return tree; |
|
|
|
return tree; |
|
|
|
for (java.util.Map.Entry<String,String> e : headEntries.entrySet()) { |
|
|
|
FileTreeEntry fileEntry; |
|
|
|
tree.addFile(e.getKey()).setId(genSha1(e.getValue())); |
|
|
|
Tree parent; |
|
|
|
|
|
|
|
for (java.util.Map.Entry<String, String> e : headEntries.entrySet()) { |
|
|
|
|
|
|
|
fileEntry = tree.addFile(e.getKey()); |
|
|
|
|
|
|
|
fileEntry.setId(genSha1(e.getValue())); |
|
|
|
|
|
|
|
parent = fileEntry.getParent(); |
|
|
|
|
|
|
|
while (parent != null) { |
|
|
|
|
|
|
|
parent.setId(ow.writeTree(parent)); |
|
|
|
|
|
|
|
parent = parent.getParent(); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return tree; |
|
|
|
return tree; |
|
|
@ -136,13 +142,11 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
return null; |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Checkout go() throws IOException { |
|
|
|
protected void go() throws IllegalStateException, IOException { |
|
|
|
theReadTree = getCheckoutImpl(theHead, theIndex, theMerge); |
|
|
|
prescanTwoTrees(theHead, theMerge); |
|
|
|
theReadTree.prescanTwoTrees(); |
|
|
|
|
|
|
|
return theReadTree; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// for these rules, they all have clean yes/no options
|
|
|
|
// for these rules, they all have clean yes/no options
|
|
|
|
// but it doesn't matter if the entry is clean or not
|
|
|
|
// but it doesn't matter if the entry is clean or not
|
|
|
|
// so we can just ignore the state in the filesystem entirely
|
|
|
|
// so we can just ignore the state in the filesystem entirely
|
|
|
|
public void testRules4thru13_IndexEntryNotInHead() throws IOException { |
|
|
|
public void testRules4thru13_IndexEntryNotInHead() throws IOException { |
|
|
@ -152,17 +156,17 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
idxMap = new HashMap<String, String>(); |
|
|
|
idxMap = new HashMap<String, String>(); |
|
|
|
idxMap.put("foo", "foo"); |
|
|
|
idxMap.put("foo", "foo"); |
|
|
|
setupCase(null, null, idxMap); |
|
|
|
setupCase(null, null, idxMap); |
|
|
|
theReadTree = go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.removed().isEmpty()); |
|
|
|
assertTrue(getRemoved().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().isEmpty()); |
|
|
|
assertTrue(getConflicts().isEmpty()); |
|
|
|
|
|
|
|
|
|
|
|
// rules 6 and 7
|
|
|
|
// rules 6 and 7
|
|
|
|
idxMap = new HashMap<String, String>(); |
|
|
|
idxMap = new HashMap<String, String>(); |
|
|
|
idxMap.put("foo", "foo"); |
|
|
|
idxMap.put("foo", "foo"); |
|
|
|
setupCase(null, idxMap, idxMap); |
|
|
|
setupCase(null, idxMap, idxMap); |
|
|
|
theReadTree = go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertAllEmpty(); |
|
|
|
assertAllEmpty(); |
|
|
|
|
|
|
|
|
|
|
@ -174,9 +178,9 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
setupCase(null, mergeMap, idxMap); |
|
|
|
setupCase(null, mergeMap, idxMap); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.removed().isEmpty()); |
|
|
|
assertTrue(getRemoved().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().contains("foo")); |
|
|
|
assertTrue(getConflicts().contains("foo")); |
|
|
|
|
|
|
|
|
|
|
|
// rule 10
|
|
|
|
// rule 10
|
|
|
|
|
|
|
|
|
|
|
@ -185,29 +189,29 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.removed().contains("foo")); |
|
|
|
assertTrue(getRemoved().contains("foo")); |
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().isEmpty()); |
|
|
|
assertTrue(getConflicts().isEmpty()); |
|
|
|
|
|
|
|
|
|
|
|
// rule 11
|
|
|
|
// rule 11
|
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
new File(trash, "foo").delete(); |
|
|
|
new File(trash, "foo").delete(); |
|
|
|
writeTrashFile("foo", "bar"); |
|
|
|
writeTrashFile("foo", "bar"); |
|
|
|
theIndex.getMembers()[0].forceRecheck(); |
|
|
|
db.getIndex().getMembers()[0].forceRecheck(); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.removed().isEmpty()); |
|
|
|
assertTrue(getRemoved().isEmpty()); |
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().contains("foo")); |
|
|
|
assertTrue(getConflicts().contains("foo")); |
|
|
|
|
|
|
|
|
|
|
|
// rule 12 & 13
|
|
|
|
// rule 12 & 13
|
|
|
|
headMap.put("foo", "head"); |
|
|
|
headMap.put("foo", "head"); |
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
setupCase(headMap, null, idxMap); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.removed().isEmpty()); |
|
|
|
assertTrue(getRemoved().isEmpty()); |
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().contains("foo")); |
|
|
|
assertTrue(getConflicts().contains("foo")); |
|
|
|
|
|
|
|
|
|
|
|
// rules 14 & 15
|
|
|
|
// rules 14 & 15
|
|
|
|
setupCase(headMap, headMap, idxMap); |
|
|
|
setupCase(headMap, headMap, idxMap); |
|
|
@ -217,7 +221,7 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
|
|
|
|
|
|
|
|
// rules 16 & 17
|
|
|
|
// rules 16 & 17
|
|
|
|
setupCase(headMap, mergeMap, idxMap); go(); |
|
|
|
setupCase(headMap, mergeMap, idxMap); go(); |
|
|
|
assertTrue(theReadTree.conflicts().contains("foo")); |
|
|
|
assertTrue(getConflicts().contains("foo")); |
|
|
|
|
|
|
|
|
|
|
|
// rules 18 & 19
|
|
|
|
// rules 18 & 19
|
|
|
|
setupCase(headMap, idxMap, idxMap); go(); |
|
|
|
setupCase(headMap, idxMap, idxMap); go(); |
|
|
@ -225,25 +229,25 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
|
|
|
|
|
|
|
|
// rule 20
|
|
|
|
// rule 20
|
|
|
|
setupCase(idxMap, mergeMap, idxMap); go(); |
|
|
|
setupCase(idxMap, mergeMap, idxMap); go(); |
|
|
|
assertTrue(theReadTree.updated().containsKey("foo")); |
|
|
|
assertTrue(getUpdated().containsKey("foo")); |
|
|
|
|
|
|
|
|
|
|
|
// rules 21
|
|
|
|
// rules 21
|
|
|
|
setupCase(idxMap, mergeMap, idxMap); |
|
|
|
setupCase(idxMap, mergeMap, idxMap); |
|
|
|
new File(trash, "foo").delete(); |
|
|
|
new File(trash, "foo").delete(); |
|
|
|
writeTrashFile("foo", "bar"); |
|
|
|
writeTrashFile("foo", "bar"); |
|
|
|
theIndex.getMembers()[0].forceRecheck(); |
|
|
|
db.getIndex().getMembers()[0].forceRecheck(); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
assertTrue(theReadTree.conflicts().contains("foo")); |
|
|
|
assertTrue(getConflicts().contains("foo")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void assertAllEmpty() { |
|
|
|
private void assertAllEmpty() { |
|
|
|
assertTrue(theReadTree.removed().isEmpty()); |
|
|
|
assertTrue(getRemoved().isEmpty()); |
|
|
|
assertTrue(theReadTree.updated().isEmpty()); |
|
|
|
assertTrue(getUpdated().isEmpty()); |
|
|
|
assertTrue(theReadTree.conflicts().isEmpty()); |
|
|
|
assertTrue(getConflicts().isEmpty()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void testDirectoryFileSimple() throws IOException { |
|
|
|
public void testDirectoryFileSimple() throws IOException { |
|
|
|
theIndex = new GitIndex(db); |
|
|
|
GitIndex theIndex = new GitIndex(db); |
|
|
|
theIndex.add(trash, writeTrashFile("DF", "DF")); |
|
|
|
theIndex.add(trash, writeTrashFile("DF", "DF")); |
|
|
|
Tree treeDF = db.mapTree(theIndex.writeTree()); |
|
|
|
Tree treeDF = db.mapTree(theIndex.writeTree()); |
|
|
|
|
|
|
|
|
|
|
@ -256,20 +260,21 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
recursiveDelete(new File(trash, "DF")); |
|
|
|
recursiveDelete(new File(trash, "DF")); |
|
|
|
|
|
|
|
|
|
|
|
theIndex.add(trash, writeTrashFile("DF", "DF")); |
|
|
|
theIndex.add(trash, writeTrashFile("DF", "DF")); |
|
|
|
theReadTree = getCheckoutImpl(treeDF, theIndex, treeDFDF); |
|
|
|
theIndex.write(); |
|
|
|
theReadTree.prescanTwoTrees(); |
|
|
|
|
|
|
|
|
|
|
|
prescanTwoTrees(treeDF, treeDFDF); |
|
|
|
|
|
|
|
|
|
|
|
assertTrue(theReadTree.removed().contains("DF")); |
|
|
|
assertTrue(getRemoved().contains("DF")); |
|
|
|
assertTrue(theReadTree.updated().containsKey("DF/DF")); |
|
|
|
assertTrue(getUpdated().containsKey("DF/DF")); |
|
|
|
|
|
|
|
|
|
|
|
recursiveDelete(new File(trash, "DF")); |
|
|
|
recursiveDelete(new File(trash, "DF")); |
|
|
|
theIndex = new GitIndex(db); |
|
|
|
theIndex = new GitIndex(db); |
|
|
|
theIndex.add(trash, writeTrashFile("DF/DF", "DF/DF")); |
|
|
|
theIndex.add(trash, writeTrashFile("DF/DF", "DF/DF")); |
|
|
|
|
|
|
|
theIndex.write(); |
|
|
|
|
|
|
|
|
|
|
|
theReadTree = getCheckoutImpl(treeDFDF, theIndex, treeDF); |
|
|
|
prescanTwoTrees(treeDFDF, treeDF); |
|
|
|
theReadTree.prescanTwoTrees(); |
|
|
|
assertTrue(getRemoved().contains("DF/DF")); |
|
|
|
assertTrue(theReadTree.removed().contains("DF/DF")); |
|
|
|
assertTrue(getUpdated().containsKey("DF")); |
|
|
|
assertTrue(theReadTree.updated().containsKey("DF")); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* |
|
|
|
/* |
|
|
@ -475,32 +480,32 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void assertConflict(String s) { |
|
|
|
private void assertConflict(String s) { |
|
|
|
assertTrue(theReadTree.conflicts().contains(s)); |
|
|
|
assertTrue(getConflicts().contains(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void assertUpdated(String s) { |
|
|
|
private void assertUpdated(String s) { |
|
|
|
assertTrue(theReadTree.updated().containsKey(s)); |
|
|
|
assertTrue(getUpdated().containsKey(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void assertRemoved(String s) { |
|
|
|
private void assertRemoved(String s) { |
|
|
|
assertTrue(theReadTree.removed().contains(s)); |
|
|
|
assertTrue(getRemoved().contains(s)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void assertNoConflicts() { |
|
|
|
private void assertNoConflicts() { |
|
|
|
assertTrue(theReadTree.conflicts().isEmpty()); |
|
|
|
assertTrue(getConflicts().isEmpty()); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void doit(HashMap<String, String> h, HashMap<String, String>m, |
|
|
|
private void doit(HashMap<String, String> h, HashMap<String, String> m, |
|
|
|
HashMap<String, String> i) throws IOException { |
|
|
|
HashMap<String, String> i) throws IOException { |
|
|
|
setupCase(h, m, i); |
|
|
|
setupCase(h, m, i); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static HashMap<String, String> mk(String a) { |
|
|
|
protected static HashMap<String, String> mk(String a) { |
|
|
|
return mkmap(a, a); |
|
|
|
return mkmap(a, a); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private static HashMap<String, String> mkmap(String... args) { |
|
|
|
protected static HashMap<String, String> mkmap(String... args) { |
|
|
|
if ((args.length % 2) > 0) |
|
|
|
if ((args.length % 2) > 0) |
|
|
|
throw new IllegalArgumentException("needs to be pairs"); |
|
|
|
throw new IllegalArgumentException("needs to be pairs"); |
|
|
|
|
|
|
|
|
|
|
@ -541,46 +546,69 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
public void testCloseNameConflictsX0() throws IOException { |
|
|
|
public void testCloseNameConflictsX0() throws IOException { |
|
|
|
setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "b.b/b.b","b.b/b.bs"), mkmap("a/a", "a/a-c") ); |
|
|
|
setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "b.b/b.b","b.b/b.bs"), mkmap("a/a", "a/a-c") ); |
|
|
|
checkout(); |
|
|
|
checkout(); |
|
|
|
|
|
|
|
assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs")); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
assertIndex(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("a/a", "a/a", "b.b/b.b", "b.b/b.bs")); |
|
|
|
assertNoConflicts(); |
|
|
|
assertNoConflicts(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void testCloseNameConflicts1() throws IOException { |
|
|
|
public void testCloseNameConflicts1() throws IOException { |
|
|
|
setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "a.a/a.a","a.a/a.a"), mkmap("a/a", "a/a-c") ); |
|
|
|
setupCase(mkmap("a/a", "a/a-c"), mkmap("a/a","a/a", "a.a/a.a","a.a/a.a"), mkmap("a/a", "a/a-c") ); |
|
|
|
checkout(); |
|
|
|
checkout(); |
|
|
|
|
|
|
|
assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a")); |
|
|
|
go(); |
|
|
|
go(); |
|
|
|
|
|
|
|
assertIndex(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("a/a", "a/a", "a.a/a.a", "a.a/a.a")); |
|
|
|
assertNoConflicts(); |
|
|
|
assertNoConflicts(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private void checkout() throws IOException { |
|
|
|
|
|
|
|
theReadTree = getCheckoutImpl(theHead, theIndex, theMerge); |
|
|
|
|
|
|
|
theReadTree.checkout(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void testCheckoutOutChanges() throws IOException { |
|
|
|
public void testCheckoutOutChanges() throws IOException { |
|
|
|
setupCase(mk("foo"), mk("foo/bar"), mk("foo")); |
|
|
|
setupCase(mk("foo"), mk("foo/bar"), mk("foo")); |
|
|
|
checkout(); |
|
|
|
checkout(); |
|
|
|
|
|
|
|
assertIndex(mk("foo/bar")); |
|
|
|
|
|
|
|
assertWorkDir(mk("foo/bar")); |
|
|
|
|
|
|
|
|
|
|
|
assertFalse(new File(trash, "foo").isFile()); |
|
|
|
assertFalse(new File(trash, "foo").isFile()); |
|
|
|
assertTrue(new File(trash, "foo/bar").isFile()); |
|
|
|
assertTrue(new File(trash, "foo/bar").isFile()); |
|
|
|
recursiveDelete(new File(trash, "foo")); |
|
|
|
recursiveDelete(new File(trash, "foo")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertWorkDir(mkmap()); |
|
|
|
|
|
|
|
|
|
|
|
setupCase(mk("foo/bar"), mk("foo"), mk("foo/bar")); |
|
|
|
setupCase(mk("foo/bar"), mk("foo"), mk("foo/bar")); |
|
|
|
checkout(); |
|
|
|
checkout(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertIndex(mk("foo")); |
|
|
|
|
|
|
|
assertWorkDir(mk("foo")); |
|
|
|
|
|
|
|
|
|
|
|
assertFalse(new File(trash, "foo/bar").isFile()); |
|
|
|
assertFalse(new File(trash, "foo/bar").isFile()); |
|
|
|
assertTrue(new File(trash, "foo").isFile()); |
|
|
|
assertTrue(new File(trash, "foo").isFile()); |
|
|
|
|
|
|
|
|
|
|
|
setupCase(mk("foo"), mkmap("foo", "qux"), mkmap("foo", "bar")); |
|
|
|
setupCase(mk("foo"), mkmap("foo", "qux"), mkmap("foo", "bar")); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
assertIndex(mkmap("foo", "bar")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("foo", "bar")); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
try { |
|
|
|
checkout(); |
|
|
|
checkout(); |
|
|
|
fail("did not throw exception"); |
|
|
|
fail("did not throw exception"); |
|
|
|
} catch (CheckoutConflictException e) { |
|
|
|
} catch (CheckoutConflictException e) { |
|
|
|
// should have thrown
|
|
|
|
assertIndex(mkmap("foo", "bar")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("foo", "bar")); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void testCheckoutUncachedChanges() throws IOException { |
|
|
|
|
|
|
|
setupCase(mk("foo"), mk("foo"), mk("foo")); |
|
|
|
|
|
|
|
writeTrashFile("foo", "otherData"); |
|
|
|
|
|
|
|
checkout(); |
|
|
|
|
|
|
|
assertIndex(mk("foo")); |
|
|
|
|
|
|
|
assertWorkDir(mkmap("foo", "otherData")); |
|
|
|
|
|
|
|
assertTrue(new File(trash, "foo").isFile()); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* The interface these tests need from a class implementing a checkout |
|
|
|
* The interface these tests need from a class implementing a checkout |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -592,45 +620,68 @@ public class ReadTreeTest extends RepositoryTestCase { |
|
|
|
void checkout() throws IOException; |
|
|
|
void checkout() throws IOException; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
public void assertWorkDir(HashMap<String, String> i) |
|
|
|
* Return the current implementation of the {@link Checkout} interface. |
|
|
|
throws CorruptObjectException, IOException { |
|
|
|
* <p> |
|
|
|
TreeWalk walk = new TreeWalk(db); |
|
|
|
* May be overridden by subclasses which would inherit all tests but can |
|
|
|
walk.reset(); |
|
|
|
* specify their own implementation of a Checkout |
|
|
|
walk.setRecursive(true); |
|
|
|
* |
|
|
|
walk.addTree(new FileTreeIterator(db.getWorkDir(), FS.DETECTED)); |
|
|
|
* @param head |
|
|
|
String expectedValue; |
|
|
|
* @param index |
|
|
|
String path; |
|
|
|
* @param merge |
|
|
|
int nrFiles = 0; |
|
|
|
* @return the current implementation of {@link Checkout} |
|
|
|
FileTreeIterator ft; |
|
|
|
*/ |
|
|
|
while (walk.next()) { |
|
|
|
protected Checkout getCheckoutImpl(Tree head, GitIndex index, |
|
|
|
ft = walk.getTree(0, FileTreeIterator.class); |
|
|
|
Tree merge) { |
|
|
|
path = ft.getEntryPathString(); |
|
|
|
return new WorkdirCheckoutImpl(head, index, merge); |
|
|
|
expectedValue = i.get(path); |
|
|
|
} |
|
|
|
assertNotNull("found unexpected file for path " |
|
|
|
|
|
|
|
+ path + " in workdir", expectedValue); |
|
|
|
/** |
|
|
|
File file = new File(db.getWorkDir(), path); |
|
|
|
* An implementation of the {@link Checkout} interface which uses WorkDirCheckout |
|
|
|
assertTrue(file.exists()); |
|
|
|
*/ |
|
|
|
if (file.isFile()) { |
|
|
|
class WorkdirCheckoutImpl extends WorkDirCheckout implements Checkout { |
|
|
|
FileInputStream is = new FileInputStream(file); |
|
|
|
public WorkdirCheckoutImpl(Tree head, GitIndex index, |
|
|
|
byte[] buffer = new byte[(int) file.length()]; |
|
|
|
Tree merge) { |
|
|
|
int offset = 0; |
|
|
|
super(db, trash, head, index, merge); |
|
|
|
int numRead = 0; |
|
|
|
} |
|
|
|
while (offset < buffer.length |
|
|
|
|
|
|
|
&& (numRead = is.read(buffer, offset, buffer.length |
|
|
|
public HashMap<String, ObjectId> updated() { |
|
|
|
- offset)) >= 0) { |
|
|
|
return updated; |
|
|
|
offset += numRead; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
is.close(); |
|
|
|
public ArrayList<String> conflicts() { |
|
|
|
assertTrue("unexpected content for path " + path |
|
|
|
return conflicts; |
|
|
|
+ " in workDir. Expected: <" + expectedValue + ">", |
|
|
|
|
|
|
|
Arrays.equals(buffer, i.get(path).getBytes())); |
|
|
|
|
|
|
|
nrFiles++; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
assertEquals("WorkDir has not the right size.", i.size(), nrFiles); |
|
|
|
public ArrayList<String> removed() { |
|
|
|
} |
|
|
|
return removed; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public void assertIndex(HashMap<String, String> i) |
|
|
|
public void prescanTwoTrees() throws IOException { |
|
|
|
throws CorruptObjectException, IOException { |
|
|
|
super.prescanTwoTrees(); |
|
|
|
String expectedValue; |
|
|
|
|
|
|
|
String path; |
|
|
|
|
|
|
|
GitIndex theIndex=db.getIndex(); |
|
|
|
|
|
|
|
assertEquals("Index has not the right size.", i.size(), |
|
|
|
|
|
|
|
theIndex.getMembers().length); |
|
|
|
|
|
|
|
for (int j = 0; j < theIndex.getMembers().length; j++) { |
|
|
|
|
|
|
|
path = theIndex.getMembers()[j].getName(); |
|
|
|
|
|
|
|
expectedValue = i.get(path); |
|
|
|
|
|
|
|
assertNotNull("found unexpected entry for path " + path |
|
|
|
|
|
|
|
+ " in index", expectedValue); |
|
|
|
|
|
|
|
assertTrue("unexpected content for path " + path |
|
|
|
|
|
|
|
+ " in index. Expected: <" + expectedValue + ">", |
|
|
|
|
|
|
|
Arrays.equals( |
|
|
|
|
|
|
|
db.openBlob(theIndex.getMembers()[j].getObjectId()) |
|
|
|
|
|
|
|
.getBytes(), i.get(path).getBytes())); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public abstract void prescanTwoTrees(Tree head, Tree merge) throws IllegalStateException, IOException; |
|
|
|
|
|
|
|
public abstract void checkout() throws IOException; |
|
|
|
|
|
|
|
public abstract ArrayList<String> getRemoved(); |
|
|
|
|
|
|
|
public abstract HashMap<String, ObjectId> getUpdated(); |
|
|
|
|
|
|
|
public abstract ArrayList<String> getConflicts(); |
|
|
|
} |
|
|
|
} |
|
|
|