use of org.eclipse.jgit.lib.ObjectInserter in project gerrit by GerritCodeReview.
the class RevertSubmission method getBase.
/**
* This function finds the base that the first revert in a project + branch should be based on.
*
* <p>If there is only one change, we will base the revert on that change. If all changes are
* related, we will base on the first commit of this submission in the topological order.
*
* <p>If none of those special cases applies, the only case left is the case where we have at
* least 2 independent changes in the same project + branch (and possibly other dependent
* changes). In this case, it searches using BFS for the first commit that is either: 1. Has 2 or
* more parents, and has as parents at least one commit that is part of the submission. 2. A
* commit that is part of the submission. If neither of those are true, it just continues the
* search by going to the parents.
*
* <p>If 1 is true, it means that this merge commit was created when this submission was
* submitted. It also means that this merge commit is a descendant of all of the changes in this
* submission and project + branch. Therefore, we return this merge commit.
*
* <p>If 2 is true, it will return the commit that WalkSorter has decided that it should be the
* first commit reverted (e.g changeNotes, which is also the commit that is the first in the
* topological sorting).
*
* <p>It doesn't run through the entire graph since it will stop once it finds at least one commit
* that is part of the submission.
*
* @param changeNotes changeNotes for the change that is found by WalkSorter to be the first one
* that should be reverted, the first in the topological sorting.
* @param commitIds The commitIds of this project and branch.
* @return the base of the first revert.
*/
private ObjectId getBase(ChangeNotes changeNotes, Set<ObjectId> commitIds) throws StorageException, IOException, PermissionBackendException {
// change.
if (commitIds.size() == 1) {
return Iterables.getOnlyElement(commitIds);
}
// topological sorting.
if (getRelated.getRelated(getRevisionResource(changeNotes)).stream().map(changes -> ObjectId.fromString(changes.commit.commit)).collect(Collectors.toSet()).containsAll(commitIds)) {
return changeNotes.getCurrentPatchSet().commitId();
}
// There are independent changes in this submission and repository + branch.
try (Repository git = repoManager.openRepository(changeNotes.getProjectName());
ObjectInserter oi = git.newObjectInserter();
ObjectReader reader = oi.newReader();
RevWalk revWalk = new RevWalk(reader)) {
ObjectId startCommit = git.getRefDatabase().findRef(changeNotes.getChange().getDest().branch()).getObjectId();
revWalk.markStart(revWalk.parseCommit(startCommit));
markChangesParentsUninteresting(commitIds, revWalk);
Iterator<RevCommit> revWalkIterator = revWalk.iterator();
while (revWalkIterator.hasNext()) {
RevCommit revCommit = revWalkIterator.next();
if (commitIds.contains(revCommit.getId())) {
return changeNotes.getCurrentPatchSet().commitId();
}
if (Arrays.stream(revCommit.getParents()).anyMatch(parent -> commitIds.contains(parent.getId()))) {
// the first common descendant of all those changes.
return revCommit.getId();
}
}
// without finding a single commit that matches any commit from the submission.
throw new StorageException(String.format("Couldn't find change %s in the repository %s", changeNotes.getChangeId(), changeNotes.getProjectName().get()));
}
}
use of org.eclipse.jgit.lib.ObjectInserter in project gerrit by GerritCodeReview.
the class PutMessage method apply.
@Override
public Response<String> apply(ChangeResource resource, CommitMessageInput input) throws IOException, RestApiException, UpdateException, PermissionBackendException, ConfigInvalidException {
PatchSet ps = psUtil.current(resource.getNotes());
if (ps == null) {
throw new ResourceConflictException("current revision is missing");
}
if (input == null) {
throw new BadRequestException("input cannot be null");
}
String sanitizedCommitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(input.message);
ensureCanEditCommitMessage(resource.getNotes());
ChangeUtil.ensureChangeIdIsCorrect(projectCache.get(resource.getProject()).orElseThrow(illegalState(resource.getProject())).is(BooleanProjectConfig.REQUIRE_CHANGE_ID), resource.getChange().getKey().get(), sanitizedCommitMessage);
try (Repository repository = repositoryManager.openRepository(resource.getProject());
RevWalk revWalk = new RevWalk(repository);
ObjectInserter objectInserter = repository.newObjectInserter()) {
RevCommit patchSetCommit = revWalk.parseCommit(ps.commitId());
String currentCommitMessage = patchSetCommit.getFullMessage();
if (input.message.equals(currentCommitMessage)) {
throw new ResourceConflictException("new and existing commit message are the same");
}
Instant ts = TimeUtil.now();
try (BatchUpdate bu = updateFactory.create(resource.getChange().getProject(), userProvider.get(), ts)) {
// Ensure that BatchUpdate will update the same repo
bu.setRepository(repository, new RevWalk(objectInserter.newReader()), objectInserter);
PatchSet.Id psId = ChangeUtil.nextPatchSetId(repository, ps.id());
ObjectId newCommit = createCommit(objectInserter, patchSetCommit, sanitizedCommitMessage, ts);
PatchSetInserter inserter = psInserterFactory.create(resource.getNotes(), psId, newCommit);
inserter.setMessage(String.format("Patch Set %s: Commit message was updated.", psId.getId()));
inserter.setDescription("Edit commit message");
bu.setNotify(resolveNotify(input, resource));
bu.addOp(resource.getChange().getId(), inserter);
bu.execute();
}
}
return Response.ok("ok");
}
use of org.eclipse.jgit.lib.ObjectInserter in project gerrit by GerritCodeReview.
the class GroupsIT method createCommit.
// TODO(issue-15517): Fix the JdkObsolete issue with Date once JGit's PersonIdent class supports
// Instants
@SuppressWarnings("JdkObsolete")
private ObjectId createCommit(Repository repo, String commitMessage, @Nullable ObjectId treeId) throws IOException {
try (ObjectInserter oi = repo.newObjectInserter()) {
if (treeId == null) {
treeId = oi.insert(Constants.OBJ_TREE, new byte[] {});
}
PersonIdent ident = new PersonIdent(serverIdent.get(), Date.from(TimeUtil.now()));
CommitBuilder cb = new CommitBuilder();
cb.setTreeId(treeId);
cb.setCommitter(ident);
cb.setAuthor(ident);
cb.setMessage(commitMessage);
ObjectId commit = oi.insert(cb);
oi.flush();
return commit;
}
}
use of org.eclipse.jgit.lib.ObjectInserter in project gerrit by GerritCodeReview.
the class GroupsIT method createBranch.
private void createBranch(Project.NameKey project, String ref) throws IOException {
try (Repository r = repoManager.openRepository(project);
ObjectInserter oi = r.newObjectInserter();
RevWalk rw = new RevWalk(r)) {
ObjectId emptyCommit = createCommit(r, "Test change");
RefUpdate updateRef = r.updateRef(ref);
updateRef.setExpectedOldObjectId(ObjectId.zeroId());
updateRef.setNewObjectId(emptyCommit);
assertThat(updateRef.update(rw)).isEqualTo(RefUpdate.Result.NEW);
}
}
use of org.eclipse.jgit.lib.ObjectInserter in project gerrit by GerritCodeReview.
the class AbstractSubmoduleSubscription method directUpdateSubmodule.
protected void directUpdateSubmodule(Project.NameKey project, String refName, Project.NameKey path, AnyObjectId id) throws Exception {
try (Repository serverRepo = repoManager.openRepository(project);
ObjectInserter ins = serverRepo.newObjectInserter();
RevWalk rw = new RevWalk(serverRepo)) {
Ref ref = serverRepo.exactRef(refName);
assertWithMessage(refName).that(ref).isNotNull();
ObjectId oldCommitId = ref.getObjectId();
DirCache dc = DirCache.newInCore();
DirCacheBuilder b = dc.builder();
b.addTree(new byte[0], DirCacheEntry.STAGE_0, rw.getObjectReader(), rw.parseTree(oldCommitId));
b.finish();
DirCacheEditor e = dc.editor();
e.add(new PathEdit(path.get()) {
@Override
public void apply(DirCacheEntry ent) {
ent.setFileMode(FileMode.GITLINK);
ent.setObjectId(id);
}
});
e.finish();
CommitBuilder cb = new CommitBuilder();
cb.addParentId(oldCommitId);
cb.setTreeId(dc.writeTree(ins));
PersonIdent ident = serverIdent.get();
cb.setAuthor(ident);
cb.setCommitter(ident);
cb.setMessage("Direct update submodule " + path);
ObjectId newCommitId = ins.insert(cb);
ins.flush();
RefUpdate ru = serverRepo.updateRef(refName);
ru.setExpectedOldObjectId(oldCommitId);
ru.setNewObjectId(newCommitId);
assertThat(ru.update()).isEqualTo(RefUpdate.Result.FAST_FORWARD);
}
}
Aggregations