Search in sources :

Example 46 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class MagicFileTest method commitMessageFileContainsFullCommitMessageAsModifiablePart.

@Test
public void commitMessageFileContainsFullCommitMessageAsModifiablePart() throws Exception {
    try (Repository repository = repositoryManager.createRepository(Project.nameKey("myRepo"));
        TestRepository<Repository> testRepo = new TestRepository<>(repository);
        ObjectReader objectReader = repository.newObjectReader()) {
        RevCommit commit = testRepo.commit().message("Subject line\n\nFurther explanations.\n").create();
        MagicFile commitMessageFile = MagicFile.forCommitMessage(objectReader, commit);
        assertThat(commitMessageFile.modifiableContent()).isEqualTo("Subject line\n\nFurther explanations.\n");
    }
}
Also used : TestRepository(org.eclipse.jgit.junit.TestRepository) Repository(org.eclipse.jgit.lib.Repository) TestRepository(org.eclipse.jgit.junit.TestRepository) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) Test(org.junit.Test)

Example 47 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class ChangeEditUtil method publish.

/**
 * Promote change edit to patch set, by squashing the edit into its parent.
 *
 * @param updateFactory factory for creating updates.
 * @param notes the {@code ChangeNotes} of the change to which the change edit belongs
 * @param user the current user
 * @param edit change edit to publish
 * @param notify Notify handling that defines to whom email notifications should be sent after the
 *     change edit is published.
 */
public void publish(BatchUpdate.Factory updateFactory, ChangeNotes notes, CurrentUser user, ChangeEdit edit, NotifyResolver.Result notify) throws IOException, RestApiException, UpdateException {
    Change change = edit.getChange();
    try (Repository repo = gitManager.openRepository(change.getProject());
        ObjectInserter oi = repo.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        PatchSet basePatchSet = edit.getBasePatchSet();
        if (!basePatchSet.id().equals(change.currentPatchSetId())) {
            throw new ResourceConflictException("only edit for current patch set can be published");
        }
        RevCommit squashed = squashEdit(rw, oi, edit.getEditCommit(), basePatchSet);
        PatchSet.Id psId = ChangeUtil.nextPatchSetId(repo, change.currentPatchSetId());
        PatchSetInserter inserter = patchSetInserterFactory.create(notes, psId, squashed).setSendEmail(!change.isWorkInProgress());
        StringBuilder message = new StringBuilder("Patch Set ").append(inserter.getPatchSetId().get()).append(": ");
        // Previously checked that the base patch set is the current patch set.
        ObjectId prior = basePatchSet.commitId();
        ChangeKind kind = changeKindCache.getChangeKind(change.getProject(), rw, repo.getConfig(), prior, squashed);
        if (kind == ChangeKind.NO_CODE_CHANGE) {
            message.append("Commit message was updated.");
            inserter.setDescription("Edit commit message");
        } else {
            message.append("Published edit on patch set ").append(basePatchSet.number()).append(".");
        }
        try (BatchUpdate bu = updateFactory.create(change.getProject(), user, TimeUtil.now())) {
            bu.setRepository(repo, rw, oi);
            bu.setNotify(notify);
            bu.addOp(change.getId(), inserter.setMessage(message.toString()));
            bu.addOp(change.getId(), new BatchUpdateOp() {

                @Override
                public void updateRepo(RepoContext ctx) throws Exception {
                    ctx.addRefUpdate(edit.getEditCommit().copy(), ObjectId.zeroId(), edit.getRefName());
                }
            });
            bu.execute();
        }
    }
}
Also used : RepoContext(com.google.gerrit.server.update.RepoContext) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.entities.PatchSet) Change(com.google.gerrit.entities.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) UpdateException(com.google.gerrit.server.update.UpdateException) AuthException(com.google.gerrit.extensions.restapi.AuthException) RestApiException(com.google.gerrit.extensions.restapi.RestApiException) LockFailureException(com.google.gerrit.git.LockFailureException) StorageException(com.google.gerrit.exceptions.StorageException) IOException(java.io.IOException) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PatchSetInserter(com.google.gerrit.server.change.PatchSetInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) ChangeKind(com.google.gerrit.extensions.client.ChangeKind) BatchUpdateOp(com.google.gerrit.server.update.BatchUpdateOp)

Example 48 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class TreeCreator method readBaseTree.

private DirCache readBaseTree(Repository repository) throws IOException {
    try (ObjectReader objectReader = repository.newObjectReader()) {
        DirCache dirCache = DirCache.newInCore();
        DirCacheBuilder dirCacheBuilder = dirCache.builder();
        if (!ObjectId.zeroId().equals(baseTreeId)) {
            dirCacheBuilder.addTree(new byte[0], DirCacheEntry.STAGE_0, objectReader, baseTreeId);
        }
        dirCacheBuilder.finish();
        return dirCache;
    }
}
Also used : DirCache(org.eclipse.jgit.dircache.DirCache) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) ObjectReader(org.eclipse.jgit.lib.ObjectReader)

Example 49 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class CherryPickChange method cherryPick.

/**
 * This function can be called directly to cherry-pick a change (or commit if sourceChange is
 * null) with a few other parameters that are especially useful for cherry-picking a commit that
 * is the revert-of another change.
 *
 * @param sourceChange Change to cherry pick. Can be null, and then the function will only cherry
 *     pick a commit.
 * @param project Project name
 * @param sourceCommit Id of the commit to be cherry picked.
 * @param input Input object for different configurations of cherry pick.
 * @param dest Destination branch for the cherry pick.
 * @param timestamp the current timestamp.
 * @param revertedChange The id of the change that is reverted. This is used for the "revertOf"
 *     field to mark the created cherry pick change as "revertOf" the original change that was
 *     reverted.
 * @param changeIdForNewChange The Change-Id that the new change of the cherry pick will have.
 * @param idForNewChange The ID that the new change of the cherry pick will have. If provided and
 *     the cherry-pick doesn't result in creating a new change, then
 *     InvalidChangeOperationException is thrown.
 * @return Result object that describes the cherry pick.
 * @throws IOException Unable to open repository or read from the database.
 * @throws InvalidChangeOperationException Parent or branch don't exist, or two changes with same
 *     key exist in the branch. Also thrown when idForNewChange is not null but cherry-pick only
 *     creates a new patchset rather than a new change.
 * @throws UpdateException Problem updating the database using batchUpdateFactory.
 * @throws RestApiException Error such as invalid SHA1
 * @throws ConfigInvalidException Can't find account to notify.
 * @throws NoSuchProjectException Can't find project state.
 */
public Result cherryPick(@Nullable Change sourceChange, Project.NameKey project, ObjectId sourceCommit, CherryPickInput input, BranchNameKey dest, Instant timestamp, @Nullable Change.Id revertedChange, @Nullable ObjectId changeIdForNewChange, @Nullable Change.Id idForNewChange, @Nullable Boolean workInProgress) throws IOException, InvalidChangeOperationException, UpdateException, RestApiException, ConfigInvalidException, NoSuchProjectException {
    IdentifiedUser identifiedUser = user.get();
    try (Repository git = gitManager.openRepository(project);
        // before patch sets are updated.
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        CodeReviewRevWalk revWalk = CodeReviewCommit.newRevWalk(reader)) {
        Ref destRef = git.getRefDatabase().exactRef(dest.branch());
        if (destRef == null) {
            throw new InvalidChangeOperationException(String.format("Branch %s does not exist.", dest.branch()));
        }
        RevCommit baseCommit = getBaseCommit(destRef, project.get(), revWalk, input.base);
        CodeReviewCommit commitToCherryPick = revWalk.parseCommit(sourceCommit);
        if (input.parent <= 0 || input.parent > commitToCherryPick.getParentCount()) {
            throw new InvalidChangeOperationException(String.format("Cherry Pick: Parent %s does not exist. Please specify a parent in" + " range [1, %s].", input.parent, commitToCherryPick.getParentCount()));
        }
        // If the commit message is not set, the commit message of the source commit will be used.
        String commitMessage = Strings.nullToEmpty(input.message);
        commitMessage = commitMessage.isEmpty() ? commitToCherryPick.getFullMessage() : commitMessage;
        String destChangeId = getDestinationChangeId(commitMessage, changeIdForNewChange);
        ChangeData destChange = null;
        if (destChangeId != null) {
            // If "idForNewChange" is not null we must fail, since we are not expecting an already
            // existing change.
            destChange = getDestChangeWithVerification(destChangeId, dest, idForNewChange != null);
        }
        if (changeIdForNewChange != null) {
            // If Change-Id was explicitly provided for the new change, override the value in commit
            // message.
            commitMessage = ChangeIdUtil.insertId(commitMessage, changeIdForNewChange, true);
        } else if (destChangeId == null) {
            // If commit message did not specify Change-Id, generate a new one and insert to the
            // message.
            commitMessage = ChangeIdUtil.insertId(commitMessage, CommitMessageUtil.generateChangeId(), true);
        }
        commitMessage = CommitMessageUtil.checkAndSanitizeCommitMessage(commitMessage);
        CodeReviewCommit cherryPickCommit;
        ProjectState projectState = projectCache.get(dest.project()).orElseThrow(noSuchProject(dest.project()));
        PersonIdent committerIdent = identifiedUser.newCommitterIdent(timestamp, serverTimeZone);
        try {
            MergeUtil mergeUtil;
            if (input.allowConflicts) {
                // allowConflicts requires to use content merge
                mergeUtil = mergeUtilFactory.create(projectState, true);
            } else {
                // use content merge only if it's configured on the project
                mergeUtil = mergeUtilFactory.create(projectState);
            }
            cherryPickCommit = mergeUtil.createCherryPickFromCommit(oi, git.getConfig(), baseCommit, commitToCherryPick, committerIdent, commitMessage, revWalk, input.parent - 1, input.allowEmpty, input.allowConflicts);
            oi.flush();
        } catch (MergeIdenticalTreeException | MergeConflictException e) {
            throw new IntegrationConflictException("Cherry pick failed: " + e.getMessage(), e);
        }
        try (BatchUpdate bu = batchUpdateFactory.create(project, identifiedUser, timestamp)) {
            bu.setRepository(git, revWalk, oi);
            bu.setNotify(resolveNotify(input));
            Change.Id changeId;
            String newTopic = null;
            if (input.topic != null) {
                newTopic = Strings.emptyToNull(input.topic.trim());
            }
            if (newTopic == null && sourceChange != null && !Strings.isNullOrEmpty(sourceChange.getTopic())) {
                newTopic = sourceChange.getTopic() + "-" + dest.shortName();
            }
            if (destChange != null) {
                // The change key exists on the destination branch. The cherry pick
                // will be added as a new patch set.
                changeId = insertPatchSet(bu, git, destChange.notes(), cherryPickCommit, sourceChange, newTopic, input, workInProgress);
            } else {
                // Change key not found on destination branch. We can create a new
                // change.
                changeId = createNewChange(bu, cherryPickCommit, dest.branch(), newTopic, project, sourceChange, sourceCommit, input, revertedChange, idForNewChange, workInProgress);
            }
            bu.execute();
            return Result.create(changeId, cherryPickCommit.getFilesWithGitConflicts());
        }
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) Change(com.google.gerrit.entities.Change) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) CodeReviewCommit(com.google.gerrit.server.git.CodeReviewCommit) ChangeData(com.google.gerrit.server.query.change.ChangeData) MergeIdenticalTreeException(com.google.gerrit.server.submit.MergeIdenticalTreeException) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) MergeUtil(com.google.gerrit.server.git.MergeUtil) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ProjectState(com.google.gerrit.server.project.ProjectState) IntegrationConflictException(com.google.gerrit.server.submit.IntegrationConflictException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 50 with ObjectReader

use of org.eclipse.jgit.lib.ObjectReader in project gerrit by GerritCodeReview.

the class PRED_commit_edits_2 method exec.

@Override
public Operation exec(Prolog engine) throws PrologException {
    engine.setB0();
    Term a1 = arg1.dereference();
    Term a2 = arg2.dereference();
    Pattern fileRegex = getRegexParameter(a1);
    Pattern editRegex = getRegexParameter(a2);
    Map<String, FileDiffOutput> modifiedFiles = StoredValues.DIFF_LIST.get(engine);
    FileDiffOutput firstDiff = Iterables.getFirst(modifiedFiles.values(), /* defaultValue= */
    null);
    if (firstDiff == null) {
        // No available diffs. We cannot identify old and new commit IDs.
        engine.fail();
    }
    Repository repo = StoredValues.REPOSITORY.get(engine);
    try (ObjectReader reader = repo.newObjectReader();
        RevWalk rw = new RevWalk(reader)) {
        final RevTree aTree = firstDiff.oldCommitId().equals(ObjectId.zeroId()) ? null : rw.parseTree(firstDiff.oldCommitId());
        final RevTree bTree = rw.parseCommit(firstDiff.newCommitId()).getTree();
        for (FileDiffOutput entry : modifiedFiles.values()) {
            String newName = FilePathAdapter.getNewPath(entry.oldPath(), entry.newPath(), entry.changeType());
            String oldName = FilePathAdapter.getOldPath(entry.oldPath(), entry.changeType());
            if (Patch.isMagic(newName)) {
                continue;
            }
            if (fileRegex.matcher(newName).find() || (oldName != null && fileRegex.matcher(oldName).find())) {
                List<Edit> edits = entry.edits().stream().map(TaggedEdit::jgitEdit).collect(Collectors.toList());
                if (edits.isEmpty()) {
                    continue;
                }
                Text tA;
                if (oldName != null) {
                    tA = load(aTree, oldName, reader);
                } else {
                    tA = load(aTree, newName, reader);
                }
                Text tB = load(bTree, newName, reader);
                for (Edit edit : edits) {
                    if (tA != Text.EMPTY) {
                        String aDiff = tA.getString(edit.getBeginA(), edit.getEndA(), true);
                        if (editRegex.matcher(aDiff).find()) {
                            return cont;
                        }
                    }
                    if (tB != Text.EMPTY) {
                        String bDiff = tB.getString(edit.getBeginB(), edit.getEndB(), true);
                        if (editRegex.matcher(bDiff).find()) {
                            return cont;
                        }
                    }
                }
            }
        }
    } catch (IOException err) {
        throw new JavaException(this, 1, err);
    }
    return engine.fail();
}
Also used : Pattern(java.util.regex.Pattern) JavaException(com.googlecode.prolog_cafe.exceptions.JavaException) Edit(org.eclipse.jgit.diff.Edit) TaggedEdit(com.google.gerrit.server.patch.filediff.TaggedEdit) Text(com.google.gerrit.server.patch.Text) Term(com.googlecode.prolog_cafe.lang.Term) SymbolTerm(com.googlecode.prolog_cafe.lang.SymbolTerm) VariableTerm(com.googlecode.prolog_cafe.lang.VariableTerm) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) FileDiffOutput(com.google.gerrit.server.patch.filediff.FileDiffOutput) Repository(org.eclipse.jgit.lib.Repository) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevTree(org.eclipse.jgit.revwalk.RevTree)

Aggregations

ObjectReader (org.eclipse.jgit.lib.ObjectReader)115 RevWalk (org.eclipse.jgit.revwalk.RevWalk)69 ObjectId (org.eclipse.jgit.lib.ObjectId)59 RevCommit (org.eclipse.jgit.revwalk.RevCommit)56 Repository (org.eclipse.jgit.lib.Repository)47 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)31 CanonicalTreeParser (org.eclipse.jgit.treewalk.CanonicalTreeParser)26 IOException (java.io.IOException)24 Test (org.junit.Test)23 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)20 RevTree (org.eclipse.jgit.revwalk.RevTree)19 DiffEntry (org.eclipse.jgit.diff.DiffEntry)18 Ref (org.eclipse.jgit.lib.Ref)17 PersonIdent (org.eclipse.jgit.lib.PersonIdent)14 TreeWalk (org.eclipse.jgit.treewalk.TreeWalk)13 TestRepository (org.eclipse.jgit.junit.TestRepository)12 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)11 Change (com.google.gerrit.reviewdb.client.Change)10 Map (java.util.Map)10 GerritPersonIdent (com.google.gerrit.server.GerritPersonIdent)9