Program: 91276
Project: 91276
Buggy source:
/** 
 * Test packfile scanning while a gc is done from the outside (different process or different Repository instance). This situation occurs e.g. if a gerrit server is serving fetch requests while native git is doing a garbage collection. The test shows that when core.trustfolderstat==true jgit may miss to detect that a new packfile was created. This situation is persistent until a new full rescan of the pack directory is triggered. The test works with two Repository instances working on the same disk location. One (db) for all write operations (creating commits, doing gc) and another one (receivingDB) which just reads and which in the end shows the bug
 * @throws Exception
 */
@Test public void testScanningForPackfiles() throws Exception {
  ObjectId unknownID=ObjectId.fromString("String_Node_Str");
  GC gc=new GC(db);
  gc.setExpireAgeMillis(0);
  gc.setPackExpireAgeMillis(0);
  try (FileRepository receivingDB=new FileRepository(db.getDirectory())){
    FileBasedConfig cfg=receivingDB.getConfig();
    cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION,null,ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT,true);
    cfg.save();
    ObjectId id=commitFile("String_Node_Str","String_Node_Str","String_Node_Str").getId();
    gc.gc();
    assertFalse(receivingDB.hasObject(unknownID));
    assertTrue(receivingDB.getObjectDatabase().hasPackedObject(id));
    File packsFolder=new File(receivingDB.getObjectsDirectory(),"String_Node_Str");
    File tmpFile=new File(packsFolder,"String_Node_Str");
    RevCommit id2=commitFile("String_Node_Str","String_Node_Str","String_Node_Str");
    fsTick(null);
    assertTrue(tmpFile.createNewFile());
    assertFalse(receivingDB.hasObject(unknownID));
    gc.gc();
    Thread.sleep(2600);
    File[] ret=packsFolder.listFiles(new FilenameFilter(){
      @Override public boolean accept(      File dir,      String name){
        return name.endsWith("String_Node_Str");
      }
    }
);
    assertTrue(ret.length == 1);
    Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified());
    assertFalse(receivingDB.hasObject(unknownID));
    assertTrue(receivingDB.hasObject(id2));
  }
 }

Fixed version (ground truth):
/** 
 * Test packfile scanning while a gc is done from the outside (different process or different Repository instance). This situation occurs e.g. if a gerrit server is serving fetch requests while native git is doing a garbage collection. The test shows that when core.trustfolderstat==true jgit may miss to detect that a new packfile was created. This situation is persistent until a new full rescan of the pack directory is triggered. The test works with two Repository instances working on the same disk location. One (db) for all write operations (creating commits, doing gc) and another one (receivingDB) which just reads and which in the end shows the bug
 * @throws Exception
 */
@Test public void testScanningForPackfiles() throws Exception {
  ObjectId unknownID=ObjectId.fromString("String_Node_Str");
  GC gc=new GC(db);
  gc.setExpireAgeMillis(0);
  gc.setPackExpireAgeMillis(0);
  try (FileRepository receivingDB=new FileRepository(db.getDirectory())){
    FileBasedConfig cfg=receivingDB.getConfig();
    cfg.setBoolean(ConfigConstants.CONFIG_CORE_SECTION,null,ConfigConstants.CONFIG_KEY_TRUSTFOLDERSTAT,true);
    cfg.save();
    ObjectId id=commitFile("String_Node_Str","String_Node_Str","String_Node_Str").getId();
    gc.gc();
    assertFalse(receivingDB.hasObject(unknownID));
    assertTrue(receivingDB.getObjectDatabase().hasPackedObject(id));
    File packsFolder=new File(receivingDB.getObjectsDirectory(),"String_Node_Str");
    File tmpFile=new File(packsFolder,"String_Node_Str");
    RevCommit id2=commitFile("String_Node_Str","String_Node_Str","String_Node_Str");
    fsTick(null);
    assertTrue(tmpFile.createNewFile());
    assertFalse(receivingDB.hasObject(unknownID));
    gc.gc();
    Thread.sleep(2600);
    File[] ret=packsFolder.listFiles(new FilenameFilter(){
      @Override public boolean accept(      File dir,      String name){
        return name.endsWith("String_Node_Str");
      }
    }
);
    assertTrue(ret != null && ret.length == 1);
    Assume.assumeTrue(tmpFile.lastModified() == ret[0].lastModified());
    assertFalse(receivingDB.hasObject(unknownID));
    assertTrue(receivingDB.hasObject(id2));
  }
 }