Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jgit-dev] isOutdated() and lastModified()

Hello all,
I've found a situation in which this patch doesn't work for me (Linux, Java 
6):

Here's the test code. "initialRepository" is mostly used for repository 
building, so it could be replaced by git command. The assertation  
"Assert.assertEquals(anotherCommitId1, anotherCommitId2);" is failed for me.
I don't know the reason but I guess this is  because of sth related to
FileSnapshot#isModified checks. If I remove some "resolve" calls (that I've 
marked) or "sleep" call, the test is passed.

Object "repository2" is independent from "repository1", so instead 
"repository1" there could be some external tool like native git runner. So 
this situation is from the real life.

The test code


final File gitDir = ...;
final Repository initialRepository = new FileRepository(girDir);
initialRepository.create(false);

final DirCache dirCache = DirCache.newInCore();
ObjectInserter objectInserter = initialRepository.newObjectInserter();
final ObjectId treeId;
try {
	treeId = dirCache.writeTree(objectInserter);
}
finally {
	objectInserter.release();
}

CommitBuilder commitBuilder;

commitBuilder = new CommitBuilder();
commitBuilder.setAuthor(new PersonIdent(initialRepository));
commitBuilder.setCommitter(new PersonIdent(initialRepository));
commitBuilder.setMessage("Initial commit");
commitBuilder.setTreeId(treeId);

objectInserter = initialRepository.newObjectInserter();
final ObjectId commitId;
try {
	commitId = objectInserter.insert(commitBuilder);
}
finally {
	objectInserter.release();
}

RefUpdate refUpdate;

refUpdate = initialRepository.updateRef("refs/heads/master");
refUpdate.setNewObjectId(commitId);
refUpdate.forceUpdate();

refUpdate = initialRepository.updateRef("HEAD");
refUpdate.link("refs/heads/master");

Repository repository1 = new FileRepository(gitDir);
final ObjectId headId1 = repository1.resolve("HEAD"); //without this "resolve" 
the test is passed

Repository repository2 = new FileRepository(gitDir);
final ObjectId headId2 = repository2.resolve("HEAD"); //without this "resolve" 
the test is passed

Assert.assertEquals(headId1, headId2);
Assert.assertEquals(commitId, headId1);

commitBuilder = new CommitBuilder();
commitBuilder.setAuthor(new PersonIdent(initialRepository));
commitBuilder.setCommitter(new PersonIdent(initialRepository));
commitBuilder.setMessage("Another commit");
commitBuilder.setParentId(commitId);
commitBuilder.setTreeId(treeId);

objectInserter = initialRepository.newObjectInserter();
final ObjectId anotherCommitId;
try {
	anotherCommitId = objectInserter.insert(commitBuilder);
}
finally {
	objectInserter.release();
}

refUpdate = repository1.updateRef("HEAD");
refUpdate.setNewObjectId(anotherCommitId);
refUpdate.forceUpdate();

//we prepared two repository objects for the same repository directory
//now let's resolve HEAD in both of them

Thread.sleep(4000); //without this "sleep" the test is passed

final ObjectId anotherCommitId2 = repository2.resolve("HEAD");
final ObjectId anotherCommitId1 = repository1.resolve("HEAD");

Assert.assertEquals(anotherCommitId1, anotherCommitId2);
Assert.assertEquals(anotherCommitId1, anotherCommitId);


On Tuesday 14 December 2010 17:42:43 Dmitry Pavlenko wrote:
> Thank you, this helps.
> 
> On Tuesday 14 December 2010 03:51:43 you wrote:
> > On Sat, Dec 11, 2010 at 8:02 AM, Dmitry Pavlenko <dmit10@xxxxxxx> wrote:
> > > I seems that FileBasedConfig (and loose-refs-related classes) relies on
> > > java.io.File.lastModified() call (at least in isOutdated() method).
> > 
> > The following Gerrit changes try to fix this problem:
> >    http://egit.eclipse.org/r/2114
> >    http://egit.eclipse.org/r/2115
> >    http://egit.eclipse.org/r/2116
> >    http://egit.eclipse.org/r/2117
> >    http://egit.eclipse.org/r/2118
> >    http://egit.eclipse.org/r/2119
> > 
> > Unfortunately its a bit too accurate.  2117 ("FileBasedConfig: Use
> > FileSnapshot for isOutdated") shows an application programming bug
> > with regards to Repository getConfig().  Once this change goes into
> > 
> > JGit, applications cannot do:
> >   Repository db = ...;
> >   db.getConfig().setString(....);
> >   db.getConfig().save();
> > 
> > Because db.getConfig() might re-read the file and discard the set that
> > the application just performed.  Yikes, that's one heck of a breakage.


Back to the top