Files
gerrit/gerrit-server/src
Dave Borowitz fcc9992f94 BatchUpdate: Scan repo for changes before applying change updates
In the ReceiveCommits codepath, the control flow looks like:

1. Repository is opened.
2. ChangeNotes are loaded for each change mentioned in the push.
3. BatchUpdate is created and setChangeRepo is called, using the same
   repository from (1).
4. During BatchUpdate#execute, the change meta ref is updated from its
   old value to a new value.

A problem arises if any ChangeNotes need to be auto-rebuilt in (2).
The notes are rebuilt and then loaded using a fresh copy of the
repository, referring to a new meta SHA-1. Since the repo used by the
BatchUpdate was opened in (1), during (4) it can't see the new meta
SHA-1. Depending on the details of a DFS backend implementation, it
might either see the incorrect old value of the ref, which would
result in a lock failure when trying to apply, or it might see the
correct old value of the ref but not have access to the packfile
containing that SHA-1. Either way, the NoteDb update will fail.

Work around this by calling repo.scanForRepoChanges() in (4) prior to
executing change updates, to ensure the rebuilt SHA-1 created in (2)
is available to set as the old value in the NoteDb ref update.

This is a bit of a hack, since it only applies to BatchUpdate, not to
other occasions where we might open a repo before auto-rebuilding a
change. However, that is a bigger problem that at the very least
requires modifying the ChangeNotes(.Factory) interface, which I didn't
want to tackle today.

Change-Id: Ie31da44fd93a288f5442c3b978d57afeba2accba
2016-07-08 13:57:32 +00:00
..