package org.eclipse.jgit.storage.file;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
final ObjectLoader or;
id = ObjectId.fromString("902d5476fa249b7abc9d84c611577a81381f0327");
- pr = new PackFile(TEST_PACK);
+ pr = new PackFile(TEST_PACK, PACK.getBit() | INDEX.getBit());
or = pr.get(new WindowCursor(null), id);
assertNotNull(or);
assertEquals(Constants.OBJ_TREE, or.getType());
package org.eclipse.jgit.storage.file;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.storage.pack.CachedPack;
import org.eclipse.jgit.storage.pack.ObjectToPack;
+import org.eclipse.jgit.storage.pack.PackExt;
import org.eclipse.jgit.storage.pack.PackWriter;
import org.eclipse.jgit.util.FS;
import org.eclipse.jgit.util.FileUtils;
public PackFile openPack(final File pack)
throws IOException {
final String p = pack.getName();
- if (p.length() != 50 || !p.startsWith("pack-") || !p.endsWith(".pack")) //$NON-NLS-1$
+ if (p.length() != 50 || !p.startsWith("pack-") || !p.endsWith(".pack")) //$NON-NLS-1$ //$NON-NLS-2$
throw new IOException(MessageFormat.format(JGitText.get().notAValidPack, pack));
- PackFile res = new PackFile(pack);
+ // The pack and index are assumed to exist. The existence of other
+ // extensions needs to be explicitly checked.
+ //
+ int extensions = PACK.getBit() | INDEX.getBit();
+ final String base = p.substring(0, p.length() - 4);
+ for (PackExt ext : PackExt.values()) {
+ if ((extensions & ext.getBit()) == 0) {
+ final String name = base + ext.getExtension();
+ if (new File(pack.getParentFile(), name).exists())
+ extensions |= ext.getBit();
+ }
+ }
+
+ PackFile res = new PackFile(pack, extensions);
insertPack(res);
return res;
}
if (indexName.length() != 49 || !indexName.endsWith(".idx")) //$NON-NLS-1$
continue;
- final String base = indexName.substring(0, indexName.length() - 4);
- final String packName = base + ".pack"; //$NON-NLS-1$
- if (!names.contains(packName)) {
+ final String base = indexName.substring(0, indexName.length() - 3);
+ int extensions = 0;
+ for (PackExt ext : PackExt.values()) {
+ if (names.contains(base + ext.getExtension()))
+ extensions |= ext.getBit();
+ }
+
+ if ((extensions & PACK.getBit()) == 0) {
// Sometimes C Git's HTTP fetch transport leaves a
// .idx file behind and does not download the .pack.
// We have to skip over such useless indexes.
continue;
}
+ final String packName = base + PACK.getExtension();
final PackFile oldPack = forReuse.remove(packName);
if (oldPack != null) {
list.add(oldPack);
}
final File packFile = new File(packDirectory, packName);
- list.add(new PackFile(packFile));
+ list.add(new PackFile(packFile, extensions));
foundNew = true;
}
private final File packFile;
+ private final int extensions;
+
private File keepFile;
private volatile String packName;
*
* @param packFile
* path of the <code>.pack</code> file holding the data.
+ * @param extensions
+ * additional pack file extensions with the same base as the pack
*/
- public PackFile(final File packFile) {
+ public PackFile(final File packFile, int extensions) {
this.packFile = packFile;
this.packLastModified = (int) (packFile.lastModified() >> 10);
+ this.extensions = extensions;
// Multiply by 31 here so we can more directly combine with another
// value in WindowCache.hash(), without doing the multiply there.
String b = (dot < 0) ? p : p.substring(0, dot);
return new File(packFile.getParentFile(), b + '.' + ext.getExtension());
}
+
+ private boolean hasExt(PackExt ext) {
+ return (extensions & ext.getBit()) != 0;
+ }
}
/** A pack file extension. */
public class PackExt {
+ private static volatile PackExt[] VALUES = new PackExt[] {};
/** A pack file extension. */
- public static final PackExt PACK = new PackExt("pack"); //$NON-NLS-1$
+ public static final PackExt PACK = newPackExt("pack"); //$NON-NLS-1$
/** A pack index file extension. */
- public static final PackExt INDEX = new PackExt("idx"); //$NON-NLS-1$
+ public static final PackExt INDEX = newPackExt("idx"); //$NON-NLS-1$
- private final String ext;
+ /** @return all of the PackExt values. */
+ public static PackExt[] values() {
+ return VALUES;
+ }
/**
+ * Returns a PackExt for the file extension and registers it in the values
+ * array.
+ *
* @param ext
* the file extension.
+ * @return the PackExt for the ext
*/
- public PackExt(String ext) {
+ public synchronized static PackExt newPackExt(String ext) {
+ PackExt[] dst = new PackExt[VALUES.length + 1];
+ for (int i = 0; i < VALUES.length; i++) {
+ PackExt packExt = VALUES[i];
+ if (packExt.getExtension().equals(ext))
+ return packExt;
+ dst[i] = packExt;
+ }
+ if (VALUES.length >= 32)
+ throw new IllegalStateException(
+ "maximum number of pack extensions exceeded"); //$NON-NLS-1$
+
+ PackExt value = new PackExt(ext, VALUES.length);
+ dst[VALUES.length] = value;
+ VALUES = dst;
+ return value;
+ }
+
+ private final String ext;
+
+ private final int pos;
+
+ private PackExt(String ext, int pos) {
this.ext = ext;
+ this.pos = pos;
}
/** @return the file extension. */
return ext;
}
- @Override
- public boolean equals(Object obj) {
- if (obj instanceof PackExt) {
- return ((PackExt) obj).getExtension().equals(getExtension());
- }
- return false;
+ /** @return the position of the extension in the values array. */
+ public int getPosition() {
+ return pos;
}
- @Override
- public int hashCode() {
- return getExtension().hashCode();
+ /** @return the bit mask of the extension e.g {@code 1 << getPosition()}. */
+ public int getBit() {
+ return 1 << getPosition();
}
@Override
public String toString() {
- return String.format("PackExt[%s]", getExtension()); //$NON-NLS-1$
+ return String.format("PackExt[%s, bit=0x%s]", getExtension(), //$NON-NLS-1$
+ Integer.toHexString(getBit()));
}
}