Merge "add more control to indexState() return-value"

This commit is contained in:
Chris Aniszczyk 2010-08-05 14:56:43 -04:00 committed by Code Review
commit c293f8fbaf
2 changed files with 84 additions and 52 deletions

View File

@ -48,7 +48,6 @@
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;
@ -118,7 +117,6 @@ public void testIterator() throws IllegalStateException, IOException,
public void testRacyGitDetection() throws IOException,
IllegalStateException, InterruptedException {
DirCache dc;
TreeSet<Long> modTimes = new TreeSet<Long>();
File lastFile;
@ -137,7 +135,10 @@ public void testRacyGitDetection() throws IOException,
// 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
@ -151,15 +152,12 @@ public void testRacyGitDetection() throws IOException,
// 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));
}
/**

View File

@ -52,19 +52,13 @@
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;
/**
@ -126,45 +120,85 @@ protected void setUp() throws Exception {
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();
}
/**
@ -186,7 +220,7 @@ else if (smudgedBefore)
* @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) {