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 cc37c2bf8..b35fc7617 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 fe02a1b23..e919e41f4 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 fa035d332..446fd7060 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 cdc659a21..d5a632c48 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 db9f684fe..efea11738 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 ceaadf97b..0926ab989 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 f74a35cd3..8345c5d83 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 f294f5cf5..69f5444c6 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 1ad8e355d..85ad8b4d7 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 * 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 eed33401d..415de095b 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 fc29aa71b..144b1a6cf 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;