eclipse-jgit / jgit

JGit, the Java implementation of git
https://www.eclipse.org/jgit/
Other
127 stars 37 forks source link

Use of SnapshottingRefDirectory can use a stale loose ref upon updates #21

Closed lucamilanesio closed 1 month ago

lucamilanesio commented 7 months ago

Version

6.6.0 or later

Operating System

Linux/Unix, MacOS, Windows

Bug description

The Problem

When using the SnapshottingRefDirectory, if a thread has read packed-refs, then another actor updates packed-refs, the original thread may create an update that is based on the old cached/snapshotted packed-refs content. That update could effectively perform a forced update unintentionally because it is unaware of the new content. This seems particularly likely to happen in a scenario where a loose ref was just packed. Our thread would otherwise see the non-snapshotted loose ref value, but instead relies on its outdated packed-refs snapshot.

The problem is potentially related to the Gerrit Code Review Issue 309098227 where Gerrit multi-site plugin detected an in-memory split-brain where two threads were trying to update the same ref, with one of the thread having a stale cached data, which is compatible with the underlying JGit issue.

In the case of the Gerrit Code Review Issue 309098227, disabling the use of SnapshottingRefDirectory solved the problem.

Actual behavior

The two threads trying to update the same ref did not have the same view of the underlying ref-db at the time of the ref-update execution.

Expected behavior

When two threads are reading concurrently a changing ref-db and starting to update a ref, they should have the same view of the ref-db which corresponds to the latest update performed on disk, regardless of the previously cached value.

Relevant log output

No response

Other information

No response

lucamilanesio commented 7 months ago

@quic-nasserg provided a fix with Change 1176275

msohn commented 7 months ago

Change 1176275 was merged on stable-6.6