public BatchMetaDataUpdate openUpdate(final MetaDataUpdate update) throws IOException {
final Repository db = update.getRepository();
reader = db.newObjectReader();
inserter = db.newObjectInserter();
final RevWalk rw = new RevWalk(reader);
final RevTree tree = revision != null ? rw.parseTree(revision) : null;
newTree = readTree(tree);
return new BatchMetaDataUpdate() {
AnyObjectId src = revision;
AnyObjectId srcTree = tree;
@Override
public void write(CommitBuilder commit) throws IOException {
write(VersionedMetaData.this, commit);
}
private void doSave(VersionedMetaData config, CommitBuilder commit) throws IOException {
DirCache nt = config.newTree;
ObjectReader r = config.reader;
ObjectInserter i = config.inserter;
try {
config.newTree = newTree;
config.reader = reader;
config.inserter = inserter;
config.onSave(commit);
} catch (ConfigInvalidException e) {
throw new IOException("Cannot update " + getRefName() + " in "
+ db.getDirectory() + ": " + e.getMessage(), e);
} finally {
config.newTree = nt;
config.reader = r;
config.inserter = i;
}
}
@Override
public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
doSave(config, commit);
final ObjectId res = newTree.writeTree(inserter);
if (res.equals(srcTree)) {
// If there are no changes to the content, don't create the commit.
return;
}
commit.setTreeId(res);
if (src != null) {
commit.addParentId(src);
}
src = inserter.insert(commit);
srcTree = res;
}
@Override
public RevCommit createRef(String refName) throws IOException {
if (Objects.equal(src, revision)) {
return revision;
}
RefUpdate ru = db.updateRef(refName);
ru.setExpectedOldObjectId(ObjectId.zeroId());
ru.setNewObjectId(src);
RefUpdate.Result result = ru.update();
switch (result) {
case NEW:
revision = rw.parseCommit(ru.getNewObjectId());
update.replicate(ru.getName());
return revision;
default:
throw new IOException("Cannot update " + ru.getName() + " in "
+ db.getDirectory() + ": " + ru.getResult());
}
}
@Override
public RevCommit commit() throws IOException {
return commitAt(revision);
}
@Override
public RevCommit commitAt(ObjectId expected) throws IOException {
if (Objects.equal(src, expected)) {
return revision;
}
RefUpdate ru = db.updateRef(getRefName());
if (expected != null) {
ru.setExpectedOldObjectId(expected);
} else {
ru.setExpectedOldObjectId(ObjectId.zeroId());
}
ru.setNewObjectId(src);
ru.disableRefLog();
inserter.flush();
switch (ru.update(rw)) {
case NEW:
case FAST_FORWARD:
revision = rw.parseCommit(ru.getNewObjectId());
update.replicate(ru.getName());
return revision;
default:
throw new IOException("Cannot update " + ru.getName() + " in "