Merge "Add additional FastForwardMode enums for different config contexts"
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsGarbageCollector.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsGarbageCollector.java
index dd01fa3..4397813 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsGarbageCollector.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsGarbageCollector.java
@@ -45,8 +45,8 @@
 
 import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.GC;
 import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.UNREACHABLE_GARBAGE;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -320,25 +320,25 @@ private DfsPackDescription writePack(PackSource source, PackWriter pw,
 		DfsPackDescription pack = repo.getObjectDatabase().newPack(source);
 		newPackDesc.add(pack);
 
-		out = objdb.writeFile(pack, PACK_EXT);
+		out = objdb.writeFile(pack, PACK);
 		try {
 			pw.writePack(pm, pm, out);
 		} finally {
 			out.close();
 		}
 
-		out = objdb.writeFile(pack, PACK_INDEX_EXT);
+		out = objdb.writeFile(pack, INDEX);
 		try {
 			CountingOutputStream cnt = new CountingOutputStream(out);
 			pw.writeIndex(cnt);
-			pack.setFileSize(PACK_INDEX_EXT, cnt.getCount());
+			pack.setFileSize(INDEX, cnt.getCount());
 		} finally {
 			out.close();
 		}
 
 		PackWriter.Statistics stats = pw.getStatistics();
 		pack.setPackStats(stats);
-		pack.setFileSize(PACK_EXT, stats.getTotalBytes());
+		pack.setFileSize(PACK, stats.getTotalBytes());
 		pack.setObjectCount(stats.getTotalObjects());
 		pack.setDeltaCount(stats.getTotalDeltas());
 		objectsPacked += stats.getTotalObjects();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
index 5187266..90bd444 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsInserter.java
@@ -43,8 +43,8 @@
 
 package org.eclipse.jgit.storage.dfs;
 
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
 
 import java.io.EOFException;
 import java.io.IOException;
@@ -153,7 +153,7 @@ public void flush() throws IOException {
 			throw new IOException();
 
 		byte[] packHash = packOut.writePackFooter();
-		packDsc.setFileSize(PACK_EXT, packOut.getCount());
+		packDsc.setFileSize(PACK, packOut.getCount());
 		packOut.close();
 		packOut = null;
 
@@ -223,7 +223,7 @@ private void beginPack() throws IOException {
 
 		rollback = true;
 		packDsc = db.newPack(DfsObjDatabase.PackSource.INSERT);
-		packOut = new PackStream(db.writeFile(packDsc, PACK_EXT));
+		packOut = new PackStream(db.writeFile(packDsc, PACK));
 		packKey = new DfsPackKey();
 
 		// Write the header as though it were a single object pack.
@@ -253,14 +253,14 @@ PackIndex writePackIndex(DfsPackDescription pack, byte[] packHash,
 			packIndex = PackIndex.read(buf.openInputStream());
 		}
 
-		DfsOutputStream os = db.writeFile(pack, PACK_INDEX_EXT);
+		DfsOutputStream os = db.writeFile(pack, INDEX);
 		try {
 			CountingOutputStream cnt = new CountingOutputStream(os);
 			if (buf != null)
 				buf.writeTo(cnt, null);
 			else
 				index(cnt, packHash, list);
-			pack.setFileSize(PACK_INDEX_EXT, cnt.getCount());
+			pack.setFileSize(INDEX, cnt.getCount());
 		} finally {
 			os.close();
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjDatabase.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjDatabase.java
index f241894..3163955 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjDatabase.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsObjDatabase.java
@@ -56,6 +56,7 @@
 import org.eclipse.jgit.lib.ObjectDatabase;
 import org.eclipse.jgit.lib.ObjectInserter;
 import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.storage.pack.PackExt;
 
 /** Manages objects stored in {@link DfsPackFile} on a storage system. */
 public abstract class DfsObjDatabase extends ObjectDatabase {
@@ -280,7 +281,7 @@ protected abstract void commitPackImpl(Collection<DfsPackDescription> desc,
 	 *             the file cannot be opened.
 	 */
 	protected abstract ReadableChannel openFile(
-			DfsPackDescription desc, String ext)
+			DfsPackDescription desc, PackExt ext)
 			throws FileNotFoundException, IOException;
 
 	/**
@@ -297,7 +298,7 @@ protected abstract ReadableChannel openFile(
 	 *             the file cannot be opened.
 	 */
 	protected abstract DfsOutputStream writeFile(
-			DfsPackDescription desc, String ext) throws IOException;
+			DfsPackDescription desc, PackExt ext) throws IOException;
 
 	void addPack(DfsPackFile newPack) throws IOException {
 		PackList o, n;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackCompactor.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackCompactor.java
index ff4c320..c17c863 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackCompactor.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackCompactor.java
@@ -44,8 +44,8 @@
 package org.eclipse.jgit.storage.dfs;
 
 import static org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource.COMPACT;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
 
 import java.io.IOException;
 import java.util.ArrayList;
@@ -139,7 +139,7 @@ public DfsPackCompactor autoAdd() throws IOException {
 		DfsObjDatabase objdb = repo.getObjectDatabase();
 		for (DfsPackFile pack : objdb.getPacks()) {
 			DfsPackDescription d = pack.getPackDescription();
-			if (d.getFileSize(PACK_EXT) < autoAddSize)
+			if (d.getFileSize(PACK) < autoAddSize)
 				add(pack);
 		}
 		return this;
@@ -285,12 +285,12 @@ public int compare(ObjectIdWithOffset a, ObjectIdWithOffset b) {
 
 	private void writePack(DfsObjDatabase objdb, DfsPackDescription pack,
 			PackWriter pw, ProgressMonitor pm) throws IOException {
-		DfsOutputStream out = objdb.writeFile(pack, PACK_EXT);
+		DfsOutputStream out = objdb.writeFile(pack, PACK);
 		try {
 			CountingOutputStream cnt = new CountingOutputStream(out);
 			pw.writePack(pm, pm, cnt);
 			pack.setObjectCount(pw.getObjectCount());
-			pack.setFileSize(PACK_EXT, cnt.getCount());
+			pack.setFileSize(PACK, cnt.getCount());
 		} finally {
 			out.close();
 		}
@@ -298,11 +298,11 @@ private void writePack(DfsObjDatabase objdb, DfsPackDescription pack,
 
 	private void writeIndex(DfsObjDatabase objdb, DfsPackDescription pack,
 			PackWriter pw) throws IOException {
-		DfsOutputStream out = objdb.writeFile(pack, PACK_INDEX_EXT);
+		DfsOutputStream out = objdb.writeFile(pack, INDEX);
 		try {
 			CountingOutputStream cnt = new CountingOutputStream(out);
 			pw.writeIndex(cnt);
-			pack.setFileSize(PACK_INDEX_EXT, cnt.getCount());
+			pack.setFileSize(INDEX, cnt.getCount());
 		} finally {
 			out.close();
 		}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java
index 9cb29af..3d3d80d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackDescription.java
@@ -49,7 +49,7 @@
 
 import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.storage.dfs.DfsObjDatabase.PackSource;
-import org.eclipse.jgit.storage.pack.PackConstants;
+import org.eclipse.jgit.storage.pack.PackExt;
 import org.eclipse.jgit.storage.pack.PackWriter;
 
 /**
@@ -69,7 +69,7 @@ public class DfsPackDescription implements Comparable<DfsPackDescription> {
 
 	private long lastModified;
 
-	private Map<String, Long> sizeMap;
+	private Map<PackExt, Long> sizeMap;
 
 	private long objectCount;
 
@@ -98,7 +98,7 @@ public DfsPackDescription(DfsRepositoryDescription repoDesc, String name) {
 		this.repoDesc = repoDesc;
 		int dot = name.lastIndexOf('.');
 		this.packName = (dot < 0) ? name : name.substring(0, dot);
-		this.sizeMap = new HashMap<String, Long>(5);
+		this.sizeMap = new HashMap<PackExt, Long>(5);
 	}
 
 	/** @return description of the repository. */
@@ -111,8 +111,8 @@ public DfsRepositoryDescription getRepositoryDescription() {
 	 *            the file extension
 	 * @return name of the file.
 	 * */
-	public String getFileName(String ext) {
-		return packName + '.' + ext;
+	public String getFileName(PackExt ext) {
+		return packName + '.' + ext.getExtension();
 	}
 
 	/** @return the source of the pack. */
@@ -153,7 +153,7 @@ public DfsPackDescription setLastModified(long timeMillis) {
 	 *            be determined on first read.
 	 * @return {@code this}
 	 */
-	public DfsPackDescription setFileSize(String ext, long bytes) {
+	public DfsPackDescription setFileSize(PackExt ext, long bytes) {
 		sizeMap.put(ext, Long.valueOf(Math.max(0, bytes)));
 		return this;
 	}
@@ -163,7 +163,7 @@ public DfsPackDescription setFileSize(String ext, long bytes) {
 	 *            the file extension.
 	 * @return size of the file, in bytes. If 0 the file size is not yet known.
 	 */
-	public long getFileSize(String ext) {
+	public long getFileSize(PackExt ext) {
 		Long size = sizeMap.get(ext);
 		return size == null ? 0 : size.longValue();
 	}
@@ -278,6 +278,6 @@ public int compareTo(DfsPackDescription b) {
 
 	@Override
 	public String toString() {
-		return getFileName(PackConstants.PACK_EXT);
+		return getFileName(PackExt.PACK);
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java
index 4c41557..ca58f8d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackFile.java
@@ -45,8 +45,8 @@
 
 package org.eclipse.jgit.storage.dfs;
 
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
 
 import java.io.BufferedInputStream;
 import java.io.EOFException;
@@ -165,7 +165,7 @@ public final class DfsPackFile {
 		this.packDesc = desc;
 		this.key = key;
 
-		length = desc.getFileSize(PACK_EXT);
+		length = desc.getFileSize(PACK);
 		if (length <= 0)
 			length = -1;
 	}
@@ -190,7 +190,7 @@ public long getCachedSize() {
 	}
 
 	private String getPackName() {
-		return packDesc.getFileName(PACK_EXT);
+		return packDesc.getFileName(PACK);
 	}
 
 	void setBlockSize(int newSize) {
@@ -232,7 +232,7 @@ private PackIndex idx(DfsReader ctx) throws IOException {
 
 			PackIndex idx;
 			try {
-				ReadableChannel rc = ctx.db.openFile(packDesc, PACK_INDEX_EXT);
+				ReadableChannel rc = ctx.db.openFile(packDesc, INDEX);
 				try {
 					InputStream in = Channels.newInputStream(rc);
 					int wantSize = 8192;
@@ -250,14 +250,14 @@ else if (bs <= 0)
 				invalid = true;
 				IOException e2 = new IOException(MessageFormat.format(
 						DfsText.get().shortReadOfIndex,
-						packDesc.getFileName(PACK_INDEX_EXT)));
+						packDesc.getFileName(INDEX)));
 				e2.initCause(e);
 				throw e2;
 			} catch (IOException e) {
 				invalid = true;
 				IOException e2 = new IOException(MessageFormat.format(
 						DfsText.get().cannotReadIndex,
-						packDesc.getFileName(PACK_INDEX_EXT)));
+						packDesc.getFileName(INDEX)));
 				e2.initCause(e);
 				throw e2;
 			}
@@ -623,7 +623,7 @@ DfsBlock readOneBlock(long pos, DfsReader ctx)
 			throw new PackInvalidException(getPackName());
 
 		boolean close = true;
-		ReadableChannel rc = ctx.db.openFile(packDesc, PACK_EXT);
+		ReadableChannel rc = ctx.db.openFile(packDesc, PACK);
 		try {
 			// If the block alignment is not yet known, discover it. Prefer the
 			// larger size from either the cache or the file itself.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackParser.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackParser.java
index 5956f64..e31de53 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackParser.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsPackParser.java
@@ -43,7 +43,7 @@
 
 package org.eclipse.jgit.storage.dfs;
 
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
 
 import java.io.EOFException;
 import java.io.IOException;
@@ -148,7 +148,7 @@ public PackLock parse(ProgressMonitor receiving, ProgressMonitor resolving)
 			out = null;
 			currBuf = null;
 			readBlock = null;
-			packDsc.setFileSize(PACK_EXT, packEnd);
+			packDsc.setFileSize(PACK, packEnd);
 
 			writePackIndex();
 			objdb.commitPack(Collections.singletonList(packDsc), null);
@@ -207,7 +207,7 @@ protected void onPackHeader(long objectCount) throws IOException {
 		packDsc = objdb.newPack(DfsObjDatabase.PackSource.RECEIVE);
 		packKey = new DfsPackKey();
 
-		out = objdb.writeFile(packDsc, PACK_EXT);
+		out = objdb.writeFile(packDsc, PACK);
 		int size = out.blockSize();
 		if (size <= 0)
 			size = blockCache.getBlockSize();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
index d83137d..393fa3f 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/DfsReader.java
@@ -47,7 +47,7 @@
 import static org.eclipse.jgit.lib.Constants.OBJECT_ID_LENGTH;
 import static org.eclipse.jgit.lib.Constants.OBJ_BLOB;
 import static org.eclipse.jgit.lib.Constants.OBJ_TREE;
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.PACK;
 
 import java.io.IOException;
 import java.io.InterruptedIOException;
@@ -662,7 +662,7 @@ void copyPackAsIs(DfsPackFile pack, long length, boolean validate,
 				pack.setInvalid();
 				throw new IOException(MessageFormat.format(
 						JGitText.get().packfileCorruptionDetected,
-						pack.getPackDescription().getFileName(PACK_EXT)));
+						pack.getPackDescription().getFileName(PACK)));
 			}
 		}
 	}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java
index 4086539..780669d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/dfs/InMemoryRepository.java
@@ -15,6 +15,7 @@
 
 import org.eclipse.jgit.lib.Ref;
 import org.eclipse.jgit.lib.Ref.Storage;
+import org.eclipse.jgit.storage.pack.PackExt;
 import org.eclipse.jgit.util.RefList;
 
 /**
@@ -103,7 +104,7 @@ protected void rollbackPack(Collection<DfsPackDescription> desc) {
 		}
 
 		@Override
-		protected ReadableChannel openFile(DfsPackDescription desc, String ext)
+		protected ReadableChannel openFile(DfsPackDescription desc, PackExt ext)
 				throws FileNotFoundException, IOException {
 			MemPack memPack = (MemPack) desc;
 			byte[] file = memPack.fileMap.get(ext);
@@ -114,7 +115,7 @@ protected ReadableChannel openFile(DfsPackDescription desc, String ext)
 
 		@Override
 		protected DfsOutputStream writeFile(
-				DfsPackDescription desc, final String ext) throws IOException {
+				DfsPackDescription desc, final PackExt ext) throws IOException {
 			final MemPack memPack = (MemPack) desc;
 			return new Out() {
 				@Override
@@ -126,8 +127,8 @@ public void flush() {
 	}
 
 	private static class MemPack extends DfsPackDescription {
-		private final Map<String, byte[]>
-				fileMap = new HashMap<String, byte[]>();
+		private final Map<PackExt, byte[]>
+				fileMap = new HashMap<PackExt, byte[]>();
 
 		MemPack(String name, DfsRepositoryDescription repoDesc) {
 			super(repoDesc, name);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
index 8ad01e1..666df58 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/file/PackFile.java
@@ -45,7 +45,7 @@
 
 package org.eclipse.jgit.storage.file;
 
-import static org.eclipse.jgit.storage.pack.PackConstants.PACK_INDEX_EXT;
+import static org.eclipse.jgit.storage.pack.PackExt.INDEX;
 
 import java.io.EOFException;
 import java.io.File;
@@ -76,6 +76,7 @@
 import org.eclipse.jgit.lib.ObjectLoader;
 import org.eclipse.jgit.storage.pack.BinaryDelta;
 import org.eclipse.jgit.storage.pack.ObjectToPack;
+import org.eclipse.jgit.storage.pack.PackExt;
 import org.eclipse.jgit.storage.pack.PackOutputStream;
 import org.eclipse.jgit.util.LongList;
 import org.eclipse.jgit.util.NB;
@@ -155,7 +156,7 @@ private synchronized PackIndex idx() throws IOException {
 				throw new PackInvalidException(packFile);
 
 			try {
-				final PackIndex idx = PackIndex.open(extFile(PACK_INDEX_EXT));
+				final PackIndex idx = PackIndex.open(extFile(INDEX));
 
 				if (packChecksum == null)
 					packChecksum = idx.packChecksum;
@@ -1078,10 +1079,10 @@ private void setCorrupt(long offset) {
 		}
 	}
 
-	private File extFile(String ext) {
+	private File extFile(PackExt ext) {
 		String p = packFile.getName();
 		int dot = p.lastIndexOf('.');
 		String b = (dot < 0) ? p : p.substring(0, dot);
-		return new File(packFile.getParentFile(), b + '.' + ext);
+		return new File(packFile.getParentFile(), b + '.' + ext.getExtension());
 	}
 }
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConstants.java b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java
similarity index 72%
rename from org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConstants.java
rename to org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java
index 84acf72..cb33308 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackConstants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/storage/pack/PackExt.java
@@ -43,15 +43,45 @@
 
 package org.eclipse.jgit.storage.pack;
 
-/** Misc. constants used with pack files. */
-public class PackConstants {
+/** A pack file extension. */
+public class PackExt {
 
 	/** A pack file extension. */
-	public static final String PACK_EXT = "pack"; //$NON-NLS-1$
+	public static final PackExt PACK = new PackExt("pack"); //$NON-NLS-1$
 
 	/** A pack index file extension. */
-	public static final String PACK_INDEX_EXT = "idx"; //$NON-NLS-1$
+	public static final PackExt INDEX = new PackExt("idx"); //$NON-NLS-1$
 
-	private PackConstants() {
+	private final String ext;
+
+	/**
+	 * @param ext
+	 *            the file extension.
+	 */
+	public PackExt(String ext) {
+		this.ext = ext;
+	}
+
+	/** @return the file extension. */
+	public String getExtension() {
+		return ext;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (obj instanceof PackExt) {
+			return ((PackExt) obj).getExtension().equals(getExtension());
+		}
+		return false;
+	}
+
+	@Override
+	public int hashCode() {
+		return getExtension().hashCode();
+	}
+
+	@Override
+	public String toString() {
+		return String.format("PackExt[%s]", getExtension()); //$NON-NLS-1$
 	}
 }