diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java index cc37c2bf8b1f94d77a08a74c0e8ea9aa04b1f7f1..b35fc761755168c6d485a23a99da10cf9345dd9d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBasicTest.java @@ -46,6 +46,7 @@ import java.io.File; import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheBasicTest extends RepositoryTestCase { @@ -176,8 +177,10 @@ public void testBuildThenClear() throws Exception { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java index fe02a1b23ea1c464a194f562b5cf11dbd4816b90..e919e41f4d947338d74bbb091404367a5d91cb83 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheBuilderTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -65,6 +65,20 @@ public void testBuildEmpty() throws Exception { } } + public void testBuildRejectsUnsetFileMode() throws Exception { + final DirCache dc = DirCache.newInCore(); + final DirCacheBuilder b = dc.builder(); + assertNotNull(b); + + final DirCacheEntry e = new DirCacheEntry("a"); + assertEquals(0, e.getRawMode()); + try { + b.add(e); + } catch (IllegalArgumentException err) { + assertEquals("FileMode not set for path a", err.getMessage()); + } + } + public void testBuildOneFile_FinishWriteCommit() throws Exception { final String path = "a-file-path"; final FileMode mode = FileMode.REGULAR_FILE; @@ -168,6 +182,7 @@ public void testFindSingleFile() throws Exception { assertNotNull(b); final DirCacheEntry entOrig = new DirCacheEntry(path); + entOrig.setFileMode(FileMode.REGULAR_FILE); assertNotSame(path, entOrig.getPathString()); assertEquals(path, entOrig.getPathString()); b.add(entOrig); @@ -191,8 +206,10 @@ public void testAdd_InGitSortOrder() throws Exception { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) @@ -213,8 +230,10 @@ public void testAdd_ReverseGitSortOrder() throws Exception { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = ents.length - 1; i >= 0; i--) @@ -235,8 +254,10 @@ public void testBuilderClear() throws Exception { final String[] paths = { "a.", "a.b", "a/b", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } { final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.spearce.jgit.test/tst/org/spearce/jgit/dircache/DirCacheEntryTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java similarity index 75% rename from org.spearce.jgit.test/tst/org/spearce/jgit/dircache/DirCacheEntryTest.java rename to org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java index fa035d3327a43c30ef9e80b8f1fb96d1fa17e8dd..446fd706015ad35793d5e8a4b406d80377164d1d 100644 --- a/org.spearce.jgit.test/tst/org/spearce/jgit/dircache/DirCacheEntryTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheEntryTest.java @@ -41,11 +41,12 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -package org.spearce.jgit.dircache; +package org.eclipse.jgit.dircache; import junit.framework.TestCase; -import org.spearce.jgit.lib.Constants; +import org.eclipse.jgit.lib.Constants; +import org.eclipse.jgit.lib.FileMode; public class DirCacheEntryTest extends TestCase { public void testIsValidPath() { @@ -118,4 +119,40 @@ public void testCreate_ByStringPathAndStage() { assertEquals("Invalid stage 4 for path a", err.getMessage()); } } + + public void testSetFileMode() { + final DirCacheEntry e = new DirCacheEntry("a"); + + assertEquals(0, e.getRawMode()); + + e.setFileMode(FileMode.REGULAR_FILE); + assertSame(FileMode.REGULAR_FILE, e.getFileMode()); + assertEquals(FileMode.REGULAR_FILE.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.EXECUTABLE_FILE); + assertSame(FileMode.EXECUTABLE_FILE, e.getFileMode()); + assertEquals(FileMode.EXECUTABLE_FILE.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.SYMLINK); + assertSame(FileMode.SYMLINK, e.getFileMode()); + assertEquals(FileMode.SYMLINK.getBits(), e.getRawMode()); + + e.setFileMode(FileMode.GITLINK); + assertSame(FileMode.GITLINK, e.getFileMode()); + assertEquals(FileMode.GITLINK.getBits(), e.getRawMode()); + + try { + e.setFileMode(FileMode.MISSING); + fail("incorrectly accepted FileMode.MISSING"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid mode 0 for path a", err.getMessage()); + } + + try { + e.setFileMode(FileMode.TREE); + fail("incorrectly accepted FileMode.TREE"); + } catch (IllegalArgumentException err) { + assertEquals("Invalid mode 40000 for path a", err.getMessage()); + } + } } diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java index cdc659a21c923423d673ee630c942ce3a5967081..d5a632c48cbc36498e594d9885581620a8a72097 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheFindTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -43,6 +43,7 @@ package org.eclipse.jgit.dircache; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheFindTest extends RepositoryTestCase { @@ -51,8 +52,10 @@ public void testEntriesWithin() throws Exception { final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 3; diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java index db9f684fed4a970ef36137b89040dde5d2fbb4b0..efea117388f714d395ccf759e8976966265a247d 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -74,8 +74,10 @@ public void testNoSubtree_NoTreeWalk() throws Exception { final String[] paths = { "a.", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java index ceaadf97b63c2cc3cbdf95ed388853ecb7f81775..0926ab9899c2618204ebc31cbd709808cc209456 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheLargePathTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -46,6 +46,7 @@ import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheLargePathTest extends RepositoryTestCase { @@ -76,6 +77,10 @@ private void testLongPath(final int len) throws CorruptObjectException, final DirCacheEntry longEnt = new DirCacheEntry(longPath); final DirCacheEntry shortEnt = new DirCacheEntry(shortPath); + + longEnt.setFileMode(FileMode.REGULAR_FILE); + shortEnt.setFileMode(FileMode.REGULAR_FILE); + assertEquals(longPath, longEnt.getPathString()); assertEquals(shortPath, shortEnt.getPathString()); diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java index f74a35cd35bdb462d743b739fdc7bd70132f8afd..8345c5d83dada2c2c0621540ea22016468b3f12b 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheTreeTest.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * and other copyright owners as documented in the project's IP log. * * This program and the accompanying materials are made available @@ -46,6 +46,7 @@ import java.io.IOException; import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.RepositoryTestCase; public class DirCacheTreeTest extends RepositoryTestCase { @@ -81,8 +82,10 @@ public void testSingleSubtree() throws Exception { final String[] paths = { "a.", "a/b", "a/c", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 3; @@ -116,8 +119,10 @@ public void testTwoLevelSubtree() throws Exception { final String[] paths = { "a.", "a/b", "a/c/e", "a/c/f", "a/d", "a0b" }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final int aFirst = 1; final int aLast = 4; final int acFirst = 2; @@ -173,8 +178,10 @@ public void testWriteReadTree() throws CorruptObjectException, IOException { final String B = String.format("b%2000s", "b"); final String[] paths = { A + ".", A + "." + B, A + "/" + B, A + "0" + B }; final DirCacheEntry[] ents = new DirCacheEntry[paths.length]; - for (int i = 0; i < paths.length; i++) + for (int i = 0; i < paths.length; i++) { ents[i] = new DirCacheEntry(paths[i]); + ents[i].setFileMode(FileMode.REGULAR_FILE); + } final DirCacheBuilder b = dc.builder(); for (int i = 0; i < ents.length; i++) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java index f294f5cf515def98e0325c1cd6cb86d7fd0203ae..69f5444c643b09451d0b976f13ae74faee3183a3 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheBuilder.java @@ -48,7 +48,6 @@ import java.util.Arrays; import org.eclipse.jgit.lib.AnyObjectId; -import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.WindowCursor; import org.eclipse.jgit.treewalk.AbstractTreeIterator; @@ -97,8 +96,13 @@ protected DirCacheBuilder(final DirCache dc, final int ecnt) { * * @param newEntry * the new entry to add. + * @throws IllegalArgumentException + * If the FileMode of the entry was not set by the caller. */ public void add(final DirCacheEntry newEntry) { + if (newEntry.getRawMode() == 0) + throw new IllegalArgumentException("FileMode not set for path " + + newEntry.getPathString()); beforeAdd(newEntry); fastAdd(newEntry); } @@ -194,8 +198,6 @@ public void finish() { } private void beforeAdd(final DirCacheEntry newEntry) { - if (FileMode.TREE.equals(newEntry.getRawMode())) - throw bad(newEntry, "Adding subtree not allowed"); if (sorted && entryCnt > 0) { final DirCacheEntry lastEntry = entries[entryCnt - 1]; final int cr = DirCache.cmp(lastEntry, newEntry); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java index 1ad8e355d5ae399c40e2ee04d95b38b2e75739db..85ad8b4d790119a6a888fdc1bc482dd8041af319 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008, Google Inc. + * Copyright (C) 2008-2009, Google Inc. * Copyright (C) 2008, Shawn O. Pearce <spearce@spearce.org> * and other copyright owners as documented in the project's IP log. * @@ -145,11 +145,16 @@ private void applyEdits() { } final DirCacheEntry ent; - if (missing) + if (missing) { ent = new DirCacheEntry(e.path); - else + e.apply(ent); + if (ent.getRawMode() == 0) + throw new IllegalArgumentException("FileMode not set" + + " for path " + ent.getPathString()); + } else { ent = cache.getEntry(eIdx); - e.apply(ent); + e.apply(ent); + } fastAdd(ent); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java index eed33401d510780de69118cc047f4e5d4b77fdab..415de095b2a1fda56dc8f81e706bf1ed49a04b19 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheEntry.java @@ -388,8 +388,18 @@ public FileMode getFileMode() { * * @param mode * the new mode constant. + * @throws IllegalArgumentException + * If {@code mode} is {@link FileMode#MISSING}, + * {@link FileMode#TREE}, or any other type code not permitted + * in a tree object. */ public void setFileMode(final FileMode mode) { + switch (mode.getBits() & FileMode.TYPE_MASK) { + case FileMode.TYPE_MISSING: + case FileMode.TYPE_TREE: + throw new IllegalArgumentException("Invalid mode " + mode + + " for path " + getPathString()); + } NB.encodeInt32(info, infoOffset + P_MODE, mode.getBits()); } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java index fc29aa71b85b054352c93e176b5c420965aaa883..144b1a6cfc4b18766550c5f619a933e0b0889340 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/dircache/DirCacheTree.java @@ -382,10 +382,6 @@ private int computeSize(final DirCacheEntry[] cache, int cIdx, } final FileMode mode = e.getFileMode(); - if (mode.getObjectType() == Constants.OBJ_BAD) - throw new IllegalStateException("Entry \"" + e.getPathString() - + "\" has incorrect mode set up."); - size += mode.copyToLength(); size += ep.length - pathOffset; size += OBJECT_ID_LENGTH + 2;