import java.io.IOException;
import java.util.TreeSet;
-import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheBuilder;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.treewalk.FileTreeIterator;
public void testRacyGitDetection() throws IOException,
IllegalStateException, InterruptedException {
- DirCache dc;
TreeSet<Long> modTimes = new TreeSet<Long>();
File lastFile;
// now add both files to the index. No racy git expected
addToIndex(modTimes);
- assertEquals("[[a, modTime(index/file): t0/t0], [b, modTime(index/file): t0/t0]]", indexState(modTimes));
+ assertEquals(
+ "[a, mode:100644, time:t0, length:1, sha1:2e65efe2a145dda7ee51d1741299f848e5bf752e]" +
+ "[b, mode:100644, time:t0, length:1, sha1:63d8dbd40c23542e740659a7168a0ce3138ea748]",
+ indexState(SMUDGE | MOD_TIME | LENGTH | CONTENT_ID));
// Remember the last modTime of index file. All modifications times of
// further modification are translated to this value so it looks that
// mod time.
addToIndex(modTimes);
- dc = db.readDirCache();
- assertTrue(dc.getEntryCount() == 2);
- assertTrue(dc.getEntry("a").isSmudged());
- assertFalse(dc.getEntry("b").isSmudged());
-
- // although racily clean a should not be reported as beeing dirty
- assertEquals("[[a, modTime(index/file): t0/t0, unsmudged], [b, modTime(index/file): t1/t1]]", indexState(modTimes));
- assertEquals("[[a, modTime(index/file): t0/t0, unsmudged], [b, modTime(index/file): t1/t1]]", indexState(modTimes));
-
+ db.readDirCache();
+ // although racily clean a should not be reported as being dirty
+ assertEquals(
+ "[a, mode:100644, time:t1, smudged, length:0]" +
+ "[b, mode:100644, time:t0, length:1]",
+ indexState(SMUDGE|MOD_TIME|LENGTH));
}
/**
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
import java.util.Map;
import java.util.TreeSet;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.errors.IncorrectObjectTypeException;
-import org.eclipse.jgit.errors.MissingObjectException;
import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
import org.eclipse.jgit.storage.file.FileRepository;
-import org.eclipse.jgit.treewalk.FileTreeIteratorWithTimeControl;
import org.eclipse.jgit.treewalk.NameConflictTreeWalk;
/**
trash = db.getWorkTree();
}
- public String indexState(TreeSet<Long> modTimes)
- throws IllegalStateException, MissingObjectException,
- IncorrectObjectTypeException, IOException {
+ public static final int MOD_TIME = 1;
+
+ public static final int SMUDGE = 2;
+
+ public static final int LENGTH = 4;
+
+ public static final int CONTENT_ID = 8;
+
+ /**
+ * Represent the state of the index in one String. This representation is
+ * useful when writing tests which do assertions on the state of the index.
+ * By default information about path, mode, stage (if different from 0) is
+ * included. A bitmask controls which additional info about
+ * modificationTimes, smudge state and length is included.
+ * <p>
+ * The format of the returned string is described with this BNF:
+ *
+ * <pre>
+ * result = ( "[" path mode stage? time? smudge? length? sha1? "]" )* .
+ * mode = ", mode:" number .
+ * stage = ", stage:" number .
+ * time = ", time:t" timestamp-index .
+ * smudge = "" | ", smudged" .
+ * length = ", length:" number .
+ * sha1 = ", sha1:" hex-sha1 .
+ *
+ * 'stage' is only presented when the stage is different from 0. All
+ * reported time stamps are mapped to strings like "t0", "t1", ... "tn". The
+ * smallest reported time-stamp will be called "t0". This allows to write
+ * assertions against the string although the concrete value of the
+ * time stamps is unknown.
+ *
+ * @param includedOptions
+ * a bitmask constructed out of the constants {@link #MOD_TIME},
+ * {@link #SMUDGE}, {@link #LENGTH} and {@link #CONTENT_ID}
+ * controlling which info is present in the resulting string.
+ * @return a string encoding the index state
+ * @throws IllegalStateException
+ * @throws IOException
+ */
+ public String indexState(int includedOptions)
+ throws IllegalStateException, IOException {
DirCache dc = db.readDirCache();
- Map lookup = new HashMap();
- List ret = new ArrayList(dc.getEntryCount());
+ StringBuilder sb = new StringBuilder();
+ TreeSet<Long> timeStamps = null;
+
+ // iterate once over the dircache just to collect all time stamps
+ if (0 != (includedOptions & MOD_TIME)) {
+ timeStamps = new TreeSet<Long>();
+ for (int i=0; i<dc.getEntryCount(); ++i)
+ timeStamps.add(Long.valueOf(dc.getEntry(i).getLastModified()));
+ }
+
+ // iterate again, now produce the result string
NameConflictTreeWalk tw = new NameConflictTreeWalk(db);
tw.reset();
- tw.addTree(new FileTreeIteratorWithTimeControl(db, modTimes));
tw.addTree(new DirCacheIterator(dc));
- boolean smudgedBefore;
while (tw.next()) {
- List entry = new ArrayList(4);
- FileTreeIteratorWithTimeControl fIt = tw.getTree(0,
- FileTreeIteratorWithTimeControl.class);
- DirCacheIterator dcIt = tw.getTree(1, DirCacheIterator.class);
- entry.add(tw.getPathString());
- entry.add("modTime(index/file): "
- + ((dcIt == null) ? "null" : lookup(Long.valueOf(dcIt
- .getDirCacheEntry().getLastModified()), "t%n",
- lookup))
- + "/"
- + ((fIt == null) ? "null" : lookup(
- Long.valueOf(fIt.getEntryLastModified()), "t%n",
- lookup)));
- smudgedBefore = (dcIt == null) ? false : dcIt.getDirCacheEntry()
- .isSmudged();
- if (fIt != null
- && dcIt != null
- && fIt.isModified(dcIt.getDirCacheEntry(), true, true,
- db.getFS()))
- entry.add("dirty");
- if (dcIt != null && dcIt.getDirCacheEntry().isSmudged())
- entry.add("smudged");
- else if (smudgedBefore)
- entry.add("unsmudged");
- ret.add(entry);
+ DirCacheIterator dcIt = tw.getTree(0, DirCacheIterator.class);
+ sb.append("["+tw.getPathString()+", mode:" + dcIt.getEntryFileMode());
+ int stage = dcIt.getDirCacheEntry().getStage();
+ if (stage != 0)
+ sb.append(", stage:" + stage);
+ if (0 != (includedOptions & MOD_TIME)) {
+ sb.append(", time:t"+
+ timeStamps.headSet(Long.valueOf(dcIt.getDirCacheEntry().getLastModified())).size());
+ }
+ if (0 != (includedOptions & SMUDGE))
+ if (dcIt.getDirCacheEntry().isSmudged())
+ sb.append(", smudged");
+ if (0 != (includedOptions & LENGTH))
+ sb.append(", length:"
+ + Integer.toString(dcIt.getDirCacheEntry().getLength()));
+ if (0 != (includedOptions & CONTENT_ID))
+ sb.append(", sha1:" + ObjectId.toString(dcIt
+ .getEntryObjectId()));
+ sb.append("]");
}
- return ret.toString();
+ return sb.toString();
}
/**
* @param lookupTable
* a table storing object-name mappings.
* @return a name of that object. Is not guaranteed to be unique. Use
- * nameTemplates containing "%n" to always have uniqe names
+ * nameTemplates containing "%n" to always have unique names
*/
public static String lookup(Object l, String nameTemplate,
Map<Object, String> lookupTable) {