use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class SubmoduleOp method composeGitlinksCommit.
/** Amend an existing commit with gitlink updates */
public CodeReviewCommit composeGitlinksCommit(final Branch.NameKey subscriber, CodeReviewCommit currentCommit) throws IOException, SubmoduleException {
OpenRepo or;
try {
or = orm.getRepo(subscriber.getParentKey());
} catch (NoSuchProjectException | IOException e) {
throw new SubmoduleException("Cannot access superproject", e);
}
StringBuilder msgbuf = new StringBuilder("");
DirCache dc = readTree(or.rw, currentCommit);
DirCacheEditor ed = dc.editor();
for (SubmoduleSubscription s : targets.get(subscriber)) {
updateSubmodule(dc, ed, msgbuf, s);
}
ed.finish();
ObjectId newTreeId = dc.writeTree(or.ins);
// Gitlinks are already updated, just return the commit
if (newTreeId.equals(currentCommit.getTree())) {
return currentCommit;
}
or.rw.parseBody(currentCommit);
CommitBuilder commit = new CommitBuilder();
commit.setTreeId(newTreeId);
commit.setParentIds(currentCommit.getParents());
if (verboseSuperProject != VerboseSuperprojectUpdate.FALSE) {
// TODO(czhen): handle cherrypick footer
commit.setMessage(currentCommit.getFullMessage() + "\n\n* submodules:\n" + msgbuf.toString());
} else {
commit.setMessage(currentCommit.getFullMessage());
}
commit.setAuthor(currentCommit.getAuthorIdent());
commit.setCommitter(myIdent);
ObjectId id = or.ins.insert(commit);
CodeReviewCommit newCommit = or.rw.parseCommit(id);
newCommit.copyFrom(currentCommit);
return newCommit;
}
use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class VersionedMetaData method readTree.
protected DirCache readTree(RevTree tree) throws IOException, MissingObjectException, IncorrectObjectTypeException {
DirCache dc = DirCache.newInCore();
if (tree != null) {
DirCacheBuilder b = dc.builder();
b.addTree(new byte[0], DirCacheEntry.STAGE_0, reader, tree);
b.finish();
}
return dc;
}
use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class VersionedMetaData method openUpdate.
/**
* Open a batch of updates to the same metadata ref.
*
* <p>This allows making multiple commits to a single metadata ref, at the end of which is a
* single ref update. For batching together updates to multiple refs (each consisting of one or
* more commits against their respective refs), create the {@link MetaDataUpdate} with a {@link
* BatchRefUpdate}.
*
* <p>A ref update produced by this {@link BatchMetaDataUpdate} is only committed if there is no
* associated {@link BatchRefUpdate}. As a result, the configured ref updated event is not fired
* if there is an associated batch.
*
* @param update helper info about the update.
* @throws IOException if the update failed.
*/
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 boolean 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;
return 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 {
if (!doSave(config, commit)) {
return;
}
ObjectId res = newTree.writeTree(inserter);
if (res.equals(srcTree) && !update.allowEmpty() && (commit.getTreeId() == null)) {
// If there are no changes to the content, don't create the commit.
return;
}
// the tree for the updated DirCache.
if (commit.getTreeId() == null) {
commit.setTreeId(res);
} else {
// In this case, the caller populated the tree without using DirCache.
res = commit.getTreeId();
}
if (src != null) {
commit.addParentId(src);
}
if (update.insertChangeId()) {
ObjectId id = ChangeIdUtil.computeChangeId(res, getRevision(), commit.getAuthor(), commit.getCommitter(), commit.getMessage());
commit.setMessage(ChangeIdUtil.insertId(commit.getMessage(), id));
}
src = inserter.insert(commit);
srcTree = res;
}
@Override
public RevCommit createRef(String refName) throws IOException {
if (Objects.equals(src, revision)) {
return revision;
}
return updateRef(ObjectId.zeroId(), src, refName);
}
@Override
public void removeRef(String refName) throws IOException {
RefUpdate ru = db.updateRef(refName);
ru.setForceUpdate(true);
if (revision != null) {
ru.setExpectedOldObjectId(revision);
}
RefUpdate.Result result = ru.delete();
switch(result) {
case FORCED:
update.fireGitRefUpdatedEvent(ru);
return;
case LOCK_FAILURE:
throw new LockFailureException("Cannot delete " + ru.getName() + " in " + db.getDirectory() + ": " + ru.getResult());
case FAST_FORWARD:
case IO_FAILURE:
case NEW:
case NOT_ATTEMPTED:
case NO_CHANGE:
case REJECTED:
case REJECTED_CURRENT_BRANCH:
case RENAMED:
default:
throw new IOException("Cannot delete " + 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.equals(src, expected)) {
return revision;
}
return updateRef(MoreObjects.firstNonNull(expected, ObjectId.zeroId()), src, getRefName());
}
@Override
public void close() {
newTree = null;
rw.close();
if (inserter != null) {
inserter.close();
inserter = null;
}
if (reader != null) {
reader.close();
reader = null;
}
}
private RevCommit updateRef(AnyObjectId oldId, AnyObjectId newId, String refName) throws IOException {
BatchRefUpdate bru = update.getBatch();
if (bru != null) {
bru.addCommand(new ReceiveCommand(oldId.toObjectId(), newId.toObjectId(), refName));
inserter.flush();
revision = rw.parseCommit(newId);
return revision;
}
RefUpdate ru = db.updateRef(refName);
ru.setExpectedOldObjectId(oldId);
ru.setNewObjectId(src);
ru.setRefLogIdent(update.getCommitBuilder().getAuthor());
String message = update.getCommitBuilder().getMessage();
if (message == null) {
message = "meta data update";
}
try (BufferedReader reader = new BufferedReader(new StringReader(message))) {
// read the subject line and use it as reflog message
ru.setRefLogMessage("commit: " + reader.readLine(), true);
}
inserter.flush();
RefUpdate.Result result = ru.update();
switch(result) {
case NEW:
case FAST_FORWARD:
revision = rw.parseCommit(ru.getNewObjectId());
update.fireGitRefUpdatedEvent(ru);
return revision;
case LOCK_FAILURE:
throw new LockFailureException("Cannot update " + ru.getName() + " in " + db.getDirectory() + ": " + ru.getResult());
case FORCED:
case IO_FAILURE:
case NOT_ATTEMPTED:
case NO_CHANGE:
case REJECTED:
case REJECTED_CURRENT_BRANCH:
case RENAMED:
default:
throw new IOException("Cannot update " + ru.getName() + " in " + db.getDirectory() + ": " + ru.getResult());
}
}
};
}
use of org.eclipse.jgit.dircache.DirCache in project gerrit by GerritCodeReview.
the class TreeCreator method createNewTree.
private DirCache createNewTree(Repository repository) throws IOException {
DirCache newTree = readBaseTree(repository);
List<DirCacheEditor.PathEdit> pathEdits = getPathEdits(repository);
applyPathEdits(newTree, pathEdits);
return newTree;
}
Aggregations