diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
index 0e25c49..a1433e9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/internal/storage/file/PackFileSnapshotTest.java
@@ -43,28 +43,50 @@
 package org.eclipse.jgit.internal.storage.file;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
+import static org.junit.Assume.assumeTrue;
 
 import java.io.File;
 import java.io.IOException;
+import java.io.OutputStream;
 import java.io.Writer;
 import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
 import java.nio.file.StandardOpenOption;
+//import java.nio.file.attribute.BasicFileAttributes;
 import java.text.ParseException;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.Random;
 import java.util.zip.Deflater;
 
 import org.eclipse.jgit.api.GarbageCollectCommand;
 import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.AbortedByHookException;
+import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.api.errors.NoFilepatternException;
+import org.eclipse.jgit.api.errors.NoHeadException;
+import org.eclipse.jgit.api.errors.NoMessageException;
+import org.eclipse.jgit.api.errors.UnmergedPathsException;
+import org.eclipse.jgit.api.errors.WrongRepositoryStateException;
 import org.eclipse.jgit.junit.RepositoryTestCase;
+import org.eclipse.jgit.lib.AnyObjectId;
 import org.eclipse.jgit.lib.ConfigConstants;
+import org.eclipse.jgit.lib.ObjectId;
 import org.eclipse.jgit.storage.file.FileBasedConfig;
 import org.eclipse.jgit.storage.pack.PackConfig;
 import org.junit.Test;
 
 public class PackFileSnapshotTest extends RepositoryTestCase {
 
+	private static ObjectId unknownID = ObjectId
+			.fromString("1234567890123456789012345678901234567890");
+
 	@Test
 	public void testSamePackDifferentCompressionDetectChecksumChanged()
 			throws Exception {
@@ -100,24 +122,213 @@ public void testSamePackDifferentCompressionDetectChecksumChanged()
 		assertTrue("expected checksum changed", snapshot.isChecksumChanged(pf));
 	}
 
-	private void appendRandomLine(File f) throws IOException {
+	private void appendRandomLine(File f, int length, Random r)
+			throws IOException {
 		try (Writer w = Files.newBufferedWriter(f.toPath(),
 				StandardOpenOption.APPEND)) {
-			w.append(randomLine(20));
+			appendRandomLine(w, length, r);
 		}
 	}
 
-	private String randomLine(int len) {
-		final int a = 97; // 'a'
-		int z = 122; // 'z'
-		Random random = new Random();
-		StringBuilder buffer = new StringBuilder(len);
+	private void appendRandomLine(File f) throws IOException {
+		appendRandomLine(f, 5, new Random());
+	}
+
+	private void appendRandomLine(Writer w, int len, Random r)
+			throws IOException {
+		final int c1 = 32; // ' '
+		int c2 = 126; // '~'
 		for (int i = 0; i < len; i++) {
-			int rnd = a + (int) (random.nextFloat() * (z - a + 1));
-			buffer.append((char) rnd);
+			w.append((char) (c1 + r.nextInt(1 + c2 - c1)));
 		}
-		buffer.append('\n');
-		return buffer.toString();
+	}
+
+	private ObjectId createTestRepo(int testDataSeed, int testDataLength)
+			throws IOException, GitAPIException, NoFilepatternException,
+			NoHeadException, NoMessageException, UnmergedPathsException,
+			ConcurrentRefUpdateException, WrongRepositoryStateException,
+			AbortedByHookException {
+		// Create a repo with two commits and one file. Each commit adds
+		// testDataLength number of bytes. Data are random bytes. Since the
+		// seed for the random number generator is specified we will get
+		// the same set of bytes for every run and for every platform
+		Random r = new Random(testDataSeed);
+		Git git = Git.wrap(db);
+		File f = writeTrashFile("file", "foobar ");
+		appendRandomLine(f, testDataLength, r);
+		git.add().addFilepattern("file").call();
+		git.commit().setMessage("message1").call();
+		appendRandomLine(f, testDataLength, r);
+		git.add().addFilepattern("file").call();
+		return git.commit().setMessage("message2").call().getId();
+	}
+
+	// Try repacking so fast that you get two new packs which differ only in
+	// content/chksum but have same name, size and lastmodified.
+	// Since this is done with standard gc (which creates new tmp files and
+	// renames them) the filekeys of the new packfiles differ helping jgit
+	// to detect the fast modification
+	@Test
+	public void testDetectModificationAlthoughSameSizeAndModificationtime()
+			throws Exception {
+		int testDataSeed = 1;
+		int testDataLength = 100;
+		FileBasedConfig config = db.getConfig();
+		// don't use mtime of the parent folder to detect pack file
+		// modification.
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, false);
+		config.save();
+
+		createTestRepo(testDataSeed, testDataLength);
+
+		// repack to create initial packfile
+		PackFile pf = repackAndCheck(5, null, null, null);
+		Path packFilePath = pf.getPackFile().toPath();
+		AnyObjectId chk1 = pf.getPackChecksum();
+		String name = pf.getPackName();
+		Long length = Long.valueOf(pf.getPackFile().length());
+		long m1 = packFilePath.toFile().lastModified();
+
+		// Wait for a filesystem timer tick to enhance probability the rest of
+		// this test is done before the filesystem timer ticks again.
+		fsTick(packFilePath.toFile());
+
+		// Repack to create packfile with same name, length. Lastmodified and
+		// content and checksum are different since compression level differs
+		AnyObjectId chk2 = repackAndCheck(6, name, length, chk1)
+				.getPackChecksum();
+		long m2 = packFilePath.toFile().lastModified();
+		assumeFalse(m2 == m1);
+
+		// Repack to create packfile with same name, length. Lastmodified is
+		// equal to the previous one because we are in the same filesystem timer
+		// slot. Content and its checksum are different
+		AnyObjectId chk3 = repackAndCheck(7, name, length, chk2)
+				.getPackChecksum();
+		long m3 = packFilePath.toFile().lastModified();
+
+		// ask for an unknown git object to force jgit to rescan the list of
+		// available packs. If we would ask for a known objectid then JGit would
+		// skip searching for new/modified packfiles
+		db.getObjectDatabase().has(unknownID);
+		assertEquals(chk3, getSinglePack(db.getObjectDatabase().getPacks())
+				.getPackChecksum());
+		assumeTrue(m3 == m2);
+	}
+
+	// Try repacking so fast that we get two new packs which differ only in
+	// content and checksum but have same name, size and lastmodified.
+	// To avoid that JGit detects modification by checking the filekey create
+	// two new packfiles upfront and create copies of them. Then modify the
+	// packfiles in-place by opening them for write and then copying the
+	// content.
+	@Test
+	public void testDetectModificationAlthoughSameSizeAndModificationtimeAndFileKey()
+			throws Exception {
+		int testDataSeed = 1;
+		int testDataLength = 100;
+		FileBasedConfig config = db.getConfig();
+		config.setBoolean(ConfigConstants.CONFIG_CORE_SECTION, null,
+				ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT, false);
+		config.save();
+
+		createTestRepo(testDataSeed, testDataLength);
+
+		// Repack to create initial packfile. Make a copy of it
+		PackFile pf = repackAndCheck(5, null, null, null);
+		Path packFilePath = pf.getPackFile().toPath();
+		Path packFileBasePath = packFilePath.resolveSibling(
+				packFilePath.getFileName().toString().replaceAll(".pack", ""));
+		AnyObjectId chk1 = pf.getPackChecksum();
+		String name = pf.getPackName();
+		Long length = Long.valueOf(pf.getPackFile().length());
+		copyPack(packFileBasePath, "", ".copy1");
+
+		// Repack to create second packfile. Make a copy of it
+		AnyObjectId chk2 = repackAndCheck(6, name, length, chk1)
+				.getPackChecksum();
+		copyPack(packFileBasePath, "", ".copy2");
+
+		// Repack to create third packfile
+		AnyObjectId chk3 = repackAndCheck(7, name, length, chk2)
+				.getPackChecksum();
+		long m3 = packFilePath.toFile().lastModified();
+		db.getObjectDatabase().has(unknownID);
+		assertEquals(chk3, getSinglePack(db.getObjectDatabase().getPacks())
+				.getPackChecksum());
+
+		// Wait for a filesystem timer tick to enhance probability the rest of
+		// this test is done before the filesystem timer ticks.
+		fsTick(packFilePath.toFile());
+
+		// Copy copy2 to packfile data to force modification of packfile without
+		// changing the packfile's filekey.
+		copyPack(packFileBasePath, ".copy2", "");
+		long m2 = packFilePath.toFile().lastModified();
+		assumeFalse(m3 == m2);
+
+		db.getObjectDatabase().has(unknownID);
+		assertEquals(chk2, getSinglePack(db.getObjectDatabase().getPacks())
+				.getPackChecksum());
+
+		// Copy copy2 to packfile data to force modification of packfile without
+		// changing the packfile's filekey.
+		copyPack(packFileBasePath, ".copy1", "");
+		long m1 = packFilePath.toFile().lastModified();
+		assumeTrue(m2 == m1);
+		db.getObjectDatabase().has(unknownID);
+		assertEquals(chk1, getSinglePack(db.getObjectDatabase().getPacks())
+				.getPackChecksum());
+	}
+
+	// Copy file from src to dst but avoid creating a new File (with new
+	// FileKey) if dst already exists
+	private Path copyFile(Path src, Path dst) throws IOException {
+		if (Files.exists(dst)) {
+			dst.toFile().setWritable(true);
+			try (OutputStream dstOut = Files.newOutputStream(dst)) {
+				Files.copy(src, dstOut);
+				return dst;
+			}
+		} else {
+			return Files.copy(src, dst, StandardCopyOption.REPLACE_EXISTING);
+		}
+	}
+
+	private Path copyPack(Path base, String srcSuffix, String dstSuffix)
+			throws IOException {
+		copyFile(Paths.get(base + ".idx" + srcSuffix),
+				Paths.get(base + ".idx" + dstSuffix));
+		copyFile(Paths.get(base + ".bitmap" + srcSuffix),
+				Paths.get(base + ".bitmap" + dstSuffix));
+		return copyFile(Paths.get(base + ".pack" + srcSuffix),
+				Paths.get(base + ".pack" + dstSuffix));
+	}
+
+	private PackFile repackAndCheck(int compressionLevel, String oldName,
+			Long oldLength, AnyObjectId oldChkSum)
+			throws IOException, ParseException {
+		PackFile p = getSinglePack(gc(compressionLevel));
+		File pf = p.getPackFile();
+		// The following two assumptions should not cause the test to fail. If
+		// on a certain platform we get packfiles (containing the same git
+		// objects) where the lengths differ or the checksums don't differ we
+		// just skip this test. A reason for that could be that compression
+		// works differently or random number generator works differently. Then
+		// we have to search for more consistent test data or checkin these
+		// packfiles as test resources
+		assumeTrue(oldLength == null || pf.length() == oldLength.longValue());
+		assumeTrue(oldChkSum == null || !p.getPackChecksum().equals(oldChkSum));
+		assertTrue(oldName == null || p.getPackName().equals(oldName));
+		return p;
+	}
+
+	private PackFile getSinglePack(Collection<PackFile> packs) {
+		Iterator<PackFile> pIt = packs.iterator();
+		PackFile p = pIt.next();
+		assertFalse(pIt.hasNext());
+		return p;
 	}
 
 	private Collection<PackFile> gc(int compressionLevel)
