Search in sources :

Example 21 with ObjectInserter

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

the class ExternalIdIT method addExtId.

private void addExtId(TestRepository<?> testRepo, ExternalId... extIds) throws IOException, OrmDuplicateKeyException, ConfigInvalidException {
    ObjectId rev = ExternalIdReader.readRevision(testRepo.getRepository());
    try (ObjectInserter ins = testRepo.getRepository().newObjectInserter()) {
        NoteMap noteMap = ExternalIdReader.readNoteMap(testRepo.getRevWalk(), rev);
        for (ExternalId extId : extIds) {
            ExternalIdsUpdate.insert(testRepo.getRevWalk(), ins, noteMap, extId);
        }
        ExternalIdsUpdate.commit(testRepo.getRepository(), testRepo.getRevWalk(), ins, rev, noteMap, "Add external ID", admin.getIdent(), admin.getIdent());
    }
}
Also used : ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectId(org.eclipse.jgit.lib.ObjectId) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) NoteMap(org.eclipse.jgit.notes.NoteMap)

Example 22 with ObjectInserter

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

the class CherryPickChange method cherryPick.

public Change.Id cherryPick(BatchUpdate.Factory batchUpdateFactory, @Nullable Change.Id sourceChangeId, @Nullable PatchSet.Id sourcePatchId, @Nullable Branch.NameKey sourceBranch, @Nullable String sourceChangeTopic, Project.NameKey project, ObjectId sourceCommit, CherryPickInput input, String targetRef, RefControl targetRefControl) throws OrmException, IOException, InvalidChangeOperationException, IntegrationException, UpdateException, RestApiException {
    if (Strings.isNullOrEmpty(targetRef)) {
        throw new InvalidChangeOperationException("Cherry Pick: Destination branch cannot be null or empty");
    }
    String destinationBranch = RefNames.shortName(targetRef);
    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(targetRef);
        if (destRef == null) {
            throw new InvalidChangeOperationException(String.format("Branch %s does not exist.", destinationBranch));
        }
        CodeReviewCommit mergeTip = revWalk.parseCommit(destRef.getObjectId());
        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()));
        }
        Timestamp now = TimeUtil.nowTs();
        PersonIdent committerIdent = identifiedUser.newCommitterIdent(now, serverTimeZone);
        final ObjectId computedChangeId = ChangeIdUtil.computeChangeId(commitToCherryPick.getTree(), mergeTip, commitToCherryPick.getAuthorIdent(), committerIdent, input.message);
        String commitMessage = ChangeIdUtil.insertId(input.message, computedChangeId).trim() + '\n';
        CodeReviewCommit cherryPickCommit;
        try {
            ProjectState projectState = targetRefControl.getProjectControl().getProjectState();
            cherryPickCommit = mergeUtilFactory.create(projectState).createCherryPickFromCommit(oi, git.getConfig(), mergeTip, commitToCherryPick, committerIdent, commitMessage, revWalk, input.parent - 1, false);
            Change.Key changeKey;
            final List<String> idList = cherryPickCommit.getFooterLines(FooterConstants.CHANGE_ID);
            if (!idList.isEmpty()) {
                final String idStr = idList.get(idList.size() - 1).trim();
                changeKey = new Change.Key(idStr);
            } else {
                changeKey = new Change.Key("I" + computedChangeId.name());
            }
            Branch.NameKey newDest = new Branch.NameKey(project, destRef.getName());
            List<ChangeData> destChanges = queryProvider.get().setLimit(2).byBranchKey(newDest, changeKey);
            if (destChanges.size() > 1) {
                throw new InvalidChangeOperationException("Several changes with key " + changeKey + " reside on the same branch. " + "Cannot create a new patch set.");
            }
            try (BatchUpdate bu = batchUpdateFactory.create(db.get(), project, identifiedUser, now)) {
                bu.setRepository(git, revWalk, oi);
                Change.Id result;
                if (destChanges.size() == 1) {
                    // The change key exists on the destination branch. The cherry pick
                    // will be added as a new patch set.
                    ChangeControl destCtl = targetRefControl.getProjectControl().controlFor(destChanges.get(0).notes());
                    result = insertPatchSet(bu, git, destCtl, cherryPickCommit, input);
                } else {
                    // Change key not found on destination branch. We can create a new
                    // change.
                    String newTopic = null;
                    if (!Strings.isNullOrEmpty(sourceChangeTopic)) {
                        newTopic = sourceChangeTopic + "-" + newDest.getShortName();
                    }
                    result = createNewChange(bu, cherryPickCommit, targetRefControl.getRefName(), newTopic, sourceBranch, sourceCommit, input);
                    if (sourceChangeId != null && sourcePatchId != null) {
                        bu.addOp(sourceChangeId, new AddMessageToSourceChangeOp(changeMessagesUtil, sourcePatchId, destinationBranch, cherryPickCommit));
                    }
                }
                bu.execute();
                return result;
            }
        } catch (MergeIdenticalTreeException | MergeConflictException e) {
            throw new IntegrationException("Cherry pick failed: " + e.getMessage());
        }
    }
}
Also used : InvalidChangeOperationException(com.google.gerrit.server.project.InvalidChangeOperationException) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) MergeConflictException(com.google.gerrit.extensions.restapi.MergeConflictException) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) Branch(com.google.gerrit.reviewdb.client.Branch) ChangeControl(com.google.gerrit.server.project.ChangeControl) ObjectReader(org.eclipse.jgit.lib.ObjectReader) IntegrationException(com.google.gerrit.server.git.IntegrationException) ObjectId(org.eclipse.jgit.lib.ObjectId) CodeReviewRevWalk(com.google.gerrit.server.git.CodeReviewCommit.CodeReviewRevWalk) Change(com.google.gerrit.reviewdb.client.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.git.MergeIdenticalTreeException) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ProjectState(com.google.gerrit.server.project.ProjectState)

Example 23 with ObjectInserter

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

the class CreateChange method applyImpl.

@Override
protected Response<ChangeInfo> applyImpl(BatchUpdate.Factory updateFactory, TopLevelResource parent, ChangeInput input) throws OrmException, IOException, InvalidChangeOperationException, RestApiException, UpdateException, PermissionBackendException {
    if (Strings.isNullOrEmpty(input.project)) {
        throw new BadRequestException("project must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.branch)) {
        throw new BadRequestException("branch must be non-empty");
    }
    if (Strings.isNullOrEmpty(input.subject)) {
        throw new BadRequestException("commit message must be non-empty");
    }
    if (input.status != null) {
        if (input.status != ChangeStatus.NEW && input.status != ChangeStatus.DRAFT) {
            throw new BadRequestException("unsupported change status");
        }
        if (!allowDrafts && input.status == ChangeStatus.DRAFT) {
            throw new MethodNotAllowedException("draft workflow is disabled");
        }
    }
    String refName = RefNames.fullName(input.branch);
    ProjectResource rsrc = projectsCollection.parse(input.project);
    Capable r = rsrc.getControl().canPushToAtLeastOneRef();
    if (r != Capable.OK) {
        throw new AuthException(r.getMessage());
    }
    RefControl refControl = rsrc.getControl().controlForRef(refName);
    if (!refControl.canUpload() || !refControl.isVisible()) {
        throw new AuthException("cannot upload review");
    }
    Project.NameKey project = rsrc.getNameKey();
    try (Repository git = gitManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk rw = new RevWalk(reader)) {
        ObjectId parentCommit;
        List<String> groups;
        if (input.baseChange != null) {
            List<ChangeControl> ctls = changeFinder.find(input.baseChange, rsrc.getControl().getUser());
            if (ctls.size() != 1) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            ChangeControl ctl = Iterables.getOnlyElement(ctls);
            if (!ctl.isVisible(db.get())) {
                throw new UnprocessableEntityException("Base change not found: " + input.baseChange);
            }
            PatchSet ps = psUtil.current(db.get(), ctl.getNotes());
            parentCommit = ObjectId.fromString(ps.getRevision().get());
            groups = ps.getGroups();
        } else {
            Ref destRef = git.getRefDatabase().exactRef(refName);
            if (destRef != null) {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    throw new ResourceConflictException(String.format("Branch %s already exists.", refName));
                }
                parentCommit = destRef.getObjectId();
            } else {
                if (Boolean.TRUE.equals(input.newBranch)) {
                    parentCommit = null;
                } else {
                    throw new UnprocessableEntityException(String.format("Branch %s does not exist.", refName));
                }
            }
            groups = Collections.emptyList();
        }
        RevCommit mergeTip = parentCommit == null ? null : rw.parseCommit(parentCommit);
        Timestamp now = TimeUtil.nowTs();
        IdentifiedUser me = user.get().asIdentifiedUser();
        PersonIdent author = me.newCommitterIdent(now, serverTimeZone);
        AccountState account = accountCache.get(me.getAccountId());
        GeneralPreferencesInfo info = account.getAccount().getGeneralPreferencesInfo();
        ObjectId treeId = mergeTip == null ? emptyTreeId(oi) : mergeTip.getTree();
        ObjectId id = ChangeIdUtil.computeChangeId(treeId, mergeTip, author, author, input.subject);
        String commitMessage = ChangeIdUtil.insertId(input.subject, id);
        if (Boolean.TRUE.equals(info.signedOffBy)) {
            commitMessage += String.format("%s%s", SIGNED_OFF_BY_TAG, account.getAccount().getNameEmail(anonymousCowardName));
        }
        RevCommit c;
        if (input.merge != null) {
            // create a merge commit
            if (!(submitType.equals(SubmitType.MERGE_ALWAYS) || submitType.equals(SubmitType.MERGE_IF_NECESSARY))) {
                throw new BadRequestException("Submit type: " + submitType + " is not supported");
            }
            c = newMergeCommit(git, oi, rw, rsrc.getControl(), mergeTip, input.merge, author, commitMessage);
        } else {
            // create an empty commit
            c = newCommit(oi, rw, author, mergeTip, commitMessage);
        }
        Change.Id changeId = new Change.Id(seq.nextChangeId());
        ChangeInserter ins = changeInserterFactory.create(changeId, c, refName);
        ins.setMessage(String.format("Uploaded patch set %s.", ins.getPatchSetId().get()));
        String topic = input.topic;
        if (topic != null) {
            topic = Strings.emptyToNull(topic.trim());
        }
        ins.setTopic(topic);
        ins.setDraft(input.status == ChangeStatus.DRAFT);
        ins.setPrivate(input.isPrivate != null && input.isPrivate);
        ins.setWorkInProgress(input.workInProgress != null && input.workInProgress);
        ins.setGroups(groups);
        ins.setNotify(input.notify);
        ins.setAccountsToNotify(notifyUtil.resolveAccounts(input.notifyDetails));
        try (BatchUpdate bu = updateFactory.create(db.get(), project, me, now)) {
            bu.setRepository(git, rw, oi);
            bu.insertChange(ins);
            bu.execute();
        }
        ChangeJson json = jsonFactory.noOptions();
        return Response.created(json.format(ins.getChange()));
    } catch (IllegalArgumentException e) {
        throw new BadRequestException(e.getMessage());
    }
}
Also used : RefControl(com.google.gerrit.server.project.RefControl) AuthException(com.google.gerrit.extensions.restapi.AuthException) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) Capable(com.google.gerrit.common.data.Capable) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ChangeControl(com.google.gerrit.server.project.ChangeControl) ObjectReader(org.eclipse.jgit.lib.ObjectReader) RevCommit(org.eclipse.jgit.revwalk.RevCommit) UnprocessableEntityException(com.google.gerrit.extensions.restapi.UnprocessableEntityException) MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) AccountState(com.google.gerrit.server.account.AccountState) Change(com.google.gerrit.reviewdb.client.Change) RevWalk(org.eclipse.jgit.revwalk.RevWalk) IdentifiedUser(com.google.gerrit.server.IdentifiedUser) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) Ref(org.eclipse.jgit.lib.Ref) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) GeneralPreferencesInfo(com.google.gerrit.extensions.client.GeneralPreferencesInfo) ProjectResource(com.google.gerrit.server.project.ProjectResource) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 24 with ObjectInserter

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

the class Revert method revert.

private Change.Id revert(BatchUpdate.Factory updateFactory, ChangeControl ctl, String message) throws OrmException, IOException, RestApiException, UpdateException {
    Change.Id changeIdToRevert = ctl.getChange().getId();
    PatchSet.Id patchSetId = ctl.getChange().currentPatchSetId();
    PatchSet patch = psUtil.get(db.get(), ctl.getNotes(), patchSetId);
    if (patch == null) {
        throw new ResourceNotFoundException(changeIdToRevert.toString());
    }
    Project.NameKey project = ctl.getProject().getNameKey();
    CurrentUser user = ctl.getUser();
    try (Repository git = repoManager.openRepository(project);
        ObjectInserter oi = git.newObjectInserter();
        ObjectReader reader = oi.newReader();
        RevWalk revWalk = new RevWalk(reader)) {
        RevCommit commitToRevert = revWalk.parseCommit(ObjectId.fromString(patch.getRevision().get()));
        if (commitToRevert.getParentCount() == 0) {
            throw new ResourceConflictException("Cannot revert initial commit");
        }
        Timestamp now = TimeUtil.nowTs();
        PersonIdent committerIdent = new PersonIdent(serverIdent, now);
        PersonIdent authorIdent = user.asIdentifiedUser().newCommitterIdent(now, committerIdent.getTimeZone());
        RevCommit parentToCommitToRevert = commitToRevert.getParent(0);
        revWalk.parseHeaders(parentToCommitToRevert);
        CommitBuilder revertCommitBuilder = new CommitBuilder();
        revertCommitBuilder.addParentId(commitToRevert);
        revertCommitBuilder.setTreeId(parentToCommitToRevert.getTree());
        revertCommitBuilder.setAuthor(authorIdent);
        revertCommitBuilder.setCommitter(authorIdent);
        Change changeToRevert = ctl.getChange();
        if (message == null) {
            message = MessageFormat.format(ChangeMessages.get().revertChangeDefaultMessage, changeToRevert.getSubject(), patch.getRevision().get());
        }
        ObjectId computedChangeId = ChangeIdUtil.computeChangeId(parentToCommitToRevert.getTree(), commitToRevert, authorIdent, committerIdent, message);
        revertCommitBuilder.setMessage(ChangeIdUtil.insertId(message, computedChangeId, true));
        Change.Id changeId = new Change.Id(seq.nextChangeId());
        ObjectId id = oi.insert(revertCommitBuilder);
        RevCommit revertCommit = revWalk.parseCommit(id);
        ChangeInserter ins = changeInserterFactory.create(changeId, revertCommit, ctl.getChange().getDest().get()).setTopic(changeToRevert.getTopic());
        ins.setMessage("Uploaded patch set 1.");
        Set<Account.Id> reviewers = new HashSet<>();
        reviewers.add(changeToRevert.getOwner());
        reviewers.addAll(approvalsUtil.getReviewers(db.get(), ctl.getNotes()).all());
        reviewers.remove(user.getAccountId());
        ins.setReviewers(reviewers);
        try (BatchUpdate bu = updateFactory.create(db.get(), project, user, now)) {
            bu.setRepository(git, revWalk, oi);
            bu.insertChange(ins);
            bu.addOp(changeId, new NotifyOp(ctl.getChange(), ins));
            bu.addOp(changeToRevert.getId(), new PostRevertedMessageOp(computedChangeId));
            bu.execute();
        }
        return changeId;
    } catch (RepositoryNotFoundException e) {
        throw new ResourceNotFoundException(changeIdToRevert.toString(), e);
    }
}
Also used : CurrentUser(com.google.gerrit.server.CurrentUser) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) Timestamp(java.sql.Timestamp) BatchUpdate(com.google.gerrit.server.update.BatchUpdate) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) ObjectReader(org.eclipse.jgit.lib.ObjectReader) ResourceNotFoundException(com.google.gerrit.extensions.restapi.ResourceNotFoundException) RevCommit(org.eclipse.jgit.revwalk.RevCommit) HashSet(java.util.HashSet) ObjectId(org.eclipse.jgit.lib.ObjectId) PatchSet(com.google.gerrit.reviewdb.client.PatchSet) Change(com.google.gerrit.reviewdb.client.Change) RepositoryNotFoundException(org.eclipse.jgit.errors.RepositoryNotFoundException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Project(com.google.gerrit.reviewdb.client.Project) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ObjectId(org.eclipse.jgit.lib.ObjectId)

Example 25 with ObjectInserter

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

the class Schema_144 method migrateData.

@Override
protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException {
    Set<ExternalId> toAdd = new HashSet<>();
    try (Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
        ResultSet rs = stmt.executeQuery("SELECT " + "account_id, " + "email_address, " + "password, " + "external_id " + "FROM account_external_ids")) {
        while (rs.next()) {
            Account.Id accountId = new Account.Id(rs.getInt(1));
            String email = rs.getString(2);
            String password = rs.getString(3);
            String externalId = rs.getString(4);
            toAdd.add(ExternalId.create(ExternalId.Key.parse(externalId), accountId, email, password));
        }
    }
    try {
        try (Repository repo = repoManager.openRepository(allUsersName);
            RevWalk rw = new RevWalk(repo);
            ObjectInserter ins = repo.newObjectInserter()) {
            ObjectId rev = ExternalIdReader.readRevision(repo);
            NoteMap noteMap = ExternalIdReader.readNoteMap(rw, rev);
            for (ExternalId extId : toAdd) {
                ExternalIdsUpdate.upsert(rw, ins, noteMap, extId);
            }
            ExternalIdsUpdate.commit(repo, rw, ins, rev, noteMap, COMMIT_MSG, serverIdent, serverIdent);
        }
    } catch (IOException | ConfigInvalidException e) {
        throw new OrmException("Failed to migrate external IDs to NoteDb", e);
    }
}
Also used : Account(com.google.gerrit.reviewdb.client.Account) ConfigInvalidException(org.eclipse.jgit.errors.ConfigInvalidException) ObjectId(org.eclipse.jgit.lib.ObjectId) Statement(java.sql.Statement) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) NoteMap(org.eclipse.jgit.notes.NoteMap) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Repository(org.eclipse.jgit.lib.Repository) ObjectInserter(org.eclipse.jgit.lib.ObjectInserter) OrmException(com.google.gwtorm.server.OrmException) ResultSet(java.sql.ResultSet) ObjectId(org.eclipse.jgit.lib.ObjectId) ExternalId(com.google.gerrit.server.account.externalids.ExternalId) HashSet(java.util.HashSet)

Aggregations

ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)56 ObjectId (org.eclipse.jgit.lib.ObjectId)39 RevWalk (org.eclipse.jgit.revwalk.RevWalk)30 Repository (org.eclipse.jgit.lib.Repository)26 IOException (java.io.IOException)17 ObjectReader (org.eclipse.jgit.lib.ObjectReader)16 RevCommit (org.eclipse.jgit.revwalk.RevCommit)16 Change (com.google.gerrit.reviewdb.client.Change)13 PersonIdent (org.eclipse.jgit.lib.PersonIdent)12 NoteMap (org.eclipse.jgit.notes.NoteMap)12 CommitBuilder (org.eclipse.jgit.lib.CommitBuilder)11 RefUpdate (org.eclipse.jgit.lib.RefUpdate)11 BatchUpdate (com.google.gerrit.server.update.BatchUpdate)10 OrmException (com.google.gwtorm.server.OrmException)8 ExternalId (com.google.gerrit.server.account.externalids.ExternalId)7 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)6 Project (com.google.gerrit.reviewdb.client.Project)6 ChangeControl (com.google.gerrit.server.project.ChangeControl)6 DirCache (org.eclipse.jgit.dircache.DirCache)6 Ref (org.eclipse.jgit.lib.Ref)6