AutoMerger: Support disabling writes to refs/cache-automerge/*

It turns out that when the persistent diff cache (and eventually the
blame cache) is present, we never have to actually read the
refs/cache-automerge/* refs. When we need the commit/tree data for the
purposes of populating the cache, we can always just read that back
from the ObjectInserter that created it. This also means we can do
batch work like an online RebuildNoteDb without ever having to write
refs/cache-automerge/* refs.

Leave the default behavior of writing out the refs as people currently
expect that behavior, but we could potentially revisit that in the
future.

Change-Id: I8bad4de10c8ef6ac6fd5a8b2cf79fc3e3ef6f830
This commit is contained in:
Dave Borowitz
2016-04-25 13:03:42 -04:00
parent 937854a833
commit f5e6e04435
5 changed files with 163 additions and 142 deletions

View File

@@ -267,7 +267,6 @@ public class AllChangesIndexer
private final ProgressMonitor failed;
private final PrintWriter verboseWriter;
private final Repository repo;
private RevWalk walk;
private ProjectIndexer(ChangeIndexer indexer,
ThreeWayMergeStrategy mergeStrategy,
@@ -289,8 +288,8 @@ public class AllChangesIndexer
@Override
public Void call() throws Exception {
walk = new RevWalk(repo);
try {
try (ObjectInserter ins = repo.newObjectInserter();
RevWalk walk = new RevWalk(ins.newReader())) {
// Walk only refs first to cover as many changes as we can without having
// to mark every single change.
for (Ref ref : repo.getRefDatabase().getRefs(Constants.R_HEADS).values()) {
@@ -303,26 +302,25 @@ public class AllChangesIndexer
RevCommit bCommit;
while ((bCommit = walk.next()) != null && !byId.isEmpty()) {
if (byId.containsKey(bCommit)) {
getPathsAndIndex(bCommit);
getPathsAndIndex(walk, ins, bCommit);
byId.removeAll(bCommit);
}
}
for (ObjectId id : byId.keySet()) {
getPathsAndIndex(id);
getPathsAndIndex(walk, ins, id);
}
} finally {
walk.close();
}
return null;
}
private void getPathsAndIndex(ObjectId b) throws Exception {
private void getPathsAndIndex(RevWalk walk, ObjectInserter ins, ObjectId b)
throws Exception {
List<ChangeData> cds = Lists.newArrayList(byId.get(b));
try (DiffFormatter df = new DiffFormatter(DisabledOutputStream.INSTANCE)) {
RevCommit bCommit = walk.parseCommit(b);
RevTree bTree = bCommit.getTree();
RevTree aTree = aFor(bCommit, walk);
RevTree aTree = aFor(bCommit, walk, ins);
df.setRepository(repo);
if (!cds.isEmpty()) {
List<String> paths = (aTree != null)
@@ -364,7 +362,8 @@ public class AllChangesIndexer
return ImmutableList.copyOf(paths);
}
private RevTree aFor(RevCommit b, RevWalk walk) throws IOException {
private RevTree aFor(RevCommit b, RevWalk walk, ObjectInserter ins)
throws IOException {
switch (b.getParentCount()) {
case 0:
return walk.parseTree(emptyTree());
@@ -373,7 +372,7 @@ public class AllChangesIndexer
walk.parseBody(a);
return walk.parseTree(a.getTree());
case 2:
RevCommit am = autoMerger.merge(repo, walk, b, mergeStrategy);
RevCommit am = autoMerger.merge(repo, walk, ins, b, mergeStrategy);
return am == null ? null : am.getTree();
default:
return null;