Search in sources :

Example 96 with ObjectInserter

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()));
    }
}
Also used : Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevWalk(org.eclipse.jgit.revwalk.RevWalk) StorageException(com.google.gerrit.exceptions.StorageException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 97 with ObjectInserter

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");
}
Also used : ObjectId(org.eclipse.jgit.lib.ObjectId) Instant(java.time.Instant) PatchSet(com.google.gerrit.entities.PatchSet) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PatchSetInserter(com.google.gerrit.server.change.PatchSetInserter) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 98 with ObjectInserter

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;
    }
}
Also used : ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder)

Example 99 with ObjectInserter

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);
    }
}
Also used : TestRepository(org.eclipse.jgit.junit.TestRepository) Repository(org.eclipse.jgit.lib.Repository) InMemoryRepository(org.eclipse.jgit.internal.storage.dfs.InMemoryRepository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RefUpdate(org.eclipse.jgit.lib.RefUpdate) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate)

Example 100 with ObjectInserter

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);
    }
}
Also used : DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) AnyObjectId(org.eclipse.jgit.lib.AnyObjectId) ObjectId(org.eclipse.jgit.lib.ObjectId) PathEdit(org.eclipse.jgit.dircache.DirCacheEditor.PathEdit) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) DirCacheEditor(org.eclipse.jgit.dircache.DirCacheEditor) RevWalk(org.eclipse.jgit.revwalk.RevWalk) DirCache(org.eclipse.jgit.dircache.DirCache) TestRepository(org.eclipse.jgit.junit.TestRepository) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) RefUpdate(org.eclipse.jgit.lib.RefUpdate) RemoteRefUpdate(org.eclipse.jgit.transport.RemoteRefUpdate)

Aggregations

ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)108 ObjectId (org.eclipse.jgit.lib.ObjectId)77 RevWalk (org.eclipse.jgit.revwalk.RevWalk)55 Repository (org.eclipse.jgit.lib.Repository)49 RevCommit (org.eclipse.jgit.revwalk.RevCommit)35 IOException (java.io.IOException)31 ObjectReader (org.eclipse.jgit.lib.ObjectReader)31 PersonIdent (org.eclipse.jgit.lib.PersonIdent)30 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)28 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)24 RefUpdate (org.eclipse.jgit.lib.RefUpdate)24 DirCache (org.eclipse.jgit.dircache.DirCache)15 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)14 Change (com.google.gerrit.entities.Change)13 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)13 Change (com.google.gerrit.reviewdb.client.Change)13 DirCacheEntry (org.eclipse.jgit.dircache.DirCacheEntry)13 Ref (org.eclipse.jgit.lib.Ref)13 IdentifiedUser (com.google.gerrit.server.IdentifiedUser)12 ResourceNotFoundException (com.google.gerrit.extensions.restapi.ResourceNotFoundException)10