Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [jgit-dev] GarbageCollectCommand does not prune unreferenced commit

in order to avoid race conditions when a pack arrives while a gc is running jgit doesn't immediately prune
garbage objects but puts them in a garbage pack which is only pruned with the next gc after a grace period
defined by gc.prunePackExpire [1] which is 1 hour by default. Before [1] this reused gc.pruneExpire
which is 2 weeks by default which led to pack file explosion, this was fixed by [1] recently.
[1] will be contained in 4.3 which I am going to release today.

[1] https://git.eclipse.org/r/#/c/69628/

-Matthias

On Thu, Apr 7, 2016 at 10:23 AM, R�diger Herrmann <ruediger.herrmann@xxxxxx> wrote:
Thanks for the hint. I wasn't aware that commits are reflogged. However, if I delete the logs directory before collecting garbage, the orphan commit is still not pruned.

Here the updated test that deletes the reflog:

@Test
public void testPruneOldOrphanCommit() throws Exception {
ObjectId initial = git.getRepository().resolve("HEAD");
RevCommit orphan = git.commit().setMessage("orphan").call();
changeLastModified(orphan, subtractDays(new Date(), 365));
RefUpdate refUpdate = git.getRepository()
.updateRef("refs/heads/master");
refUpdate.setNewObjectId(initial);
refUpdate.forceUpdate();
FileUtils.delete(new File(git.getRepository().getDirectory(), "logs"),
FileUtils.RECURSIVE | FileUtils.RETRY);

git.gc().setExpire(new Date()).call();

assertNull(git.getRepository().resolve(orphan.name()));
}




From: Matthias Sohn <matthias.sohn@xxxxxxxxx>
To: Shawn Pearce <spearce@xxxxxxxxxxx>
Cc: R�diger Herrmann <ruediger.herrmann@xxxxxx>; "jgit-dev@xxxxxxxxxxx" <jgit-dev@xxxxxxxxxxx>
Sent: Thursday, April 7, 2016 12:51 AM
Subject: Re: [jgit-dev] GarbageCollectCommand does not prune unreferenced commit

On Wed, Apr 6, 2016 at 11:19 PM, Shawn Pearce <spearce@xxxxxxxxxxx> wrote:
On Wed, Apr 6, 2016 at 2:14 PM, R�diger Herrmann
<ruediger.herrmann@xxxxxx> wrote:
> You are right of course, the shown code isn't quite what I tired. Sorry for
> the confusion. If I change it to 'unreference' the orphan commit the result
> is still the same.
>
> The correct version would reset HEAD to the previous commit so that 'orphan'
> is actually unreferenced like this:
>
> @Test
> public void testPruneOldOrphanCommit() throws Exception {
> ObjectId initial = git.getRepository().resolve("HEAD");
> RevCommit orphan = git.commit().setMessage("orphan").call();
> changeLastModified(orphan, subtractDays(new Date(), 365));
> RefUpdate refUpdate = git.getRepository()
> .updateRef("refs/heads/master");
> refUpdate.setNewObjectId(initial);
> refUpdate.forceUpdate();

Is orphan still in the reflog for master? or HEAD?

I tried your test and the orphaned commit is still referenced from both the
master's and HEAD's reflogs.

-Matthias 




Back to the top