Search in sources :

Example 11 with RevObject

use of org.eclipse.jgit.revwalk.RevObject in project gerrit by GerritCodeReview.

the class ReceiveCommits method isCommit.

private boolean isCommit(ReceiveCommand cmd) {
    RevObject obj;
    try {
        obj = rp.getRevWalk().parseAny(cmd.getNewId());
    } catch (IOException err) {
        logError("Invalid object " + cmd.getNewId().name() + " for " + cmd.getRefName(), err);
        reject(cmd, "invalid object");
        return false;
    }
    if (obj instanceof RevCommit) {
        return true;
    }
    reject(cmd, "not a commit");
    return false;
}
Also used : RevObject(org.eclipse.jgit.revwalk.RevObject) IOException(java.io.IOException) RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 12 with RevObject

use of org.eclipse.jgit.revwalk.RevObject in project gerrit by GerritCodeReview.

the class CreateTag method apply.

@Override
public TagInfo apply(ProjectResource resource, TagInput input) throws RestApiException, IOException, PermissionBackendException {
    if (input == null) {
        input = new TagInput();
    }
    if (input.ref != null && !ref.equals(input.ref)) {
        throw new BadRequestException("ref must match URL");
    }
    if (input.revision == null) {
        input.revision = Constants.HEAD;
    }
    ref = RefUtil.normalizeTagRef(ref);
    RefControl refControl = resource.getControl().controlForRef(ref);
    PermissionBackend.ForRef perm = permissionBackend.user(identifiedUser).project(resource.getNameKey()).ref(ref);
    try (Repository repo = repoManager.openRepository(resource.getNameKey())) {
        ObjectId revid = RefUtil.parseBaseRevision(repo, resource.getNameKey(), input.revision);
        RevWalk rw = RefUtil.verifyConnected(repo, revid);
        RevObject object = rw.parseAny(revid);
        rw.reset();
        boolean isAnnotated = Strings.emptyToNull(input.message) != null;
        boolean isSigned = isAnnotated && input.message.contains("-----BEGIN PGP SIGNATURE-----\n");
        if (isSigned) {
            throw new MethodNotAllowedException("Cannot create signed tag \"" + ref + "\"");
        } else if (isAnnotated && !refControl.canPerform(Permission.CREATE_TAG)) {
            throw new AuthException("Cannot create annotated tag \"" + ref + "\"");
        } else {
            perm.check(RefPermission.CREATE);
        }
        if (repo.getRefDatabase().exactRef(ref) != null) {
            throw new ResourceConflictException("tag \"" + ref + "\" already exists");
        }
        try (Git git = new Git(repo)) {
            TagCommand tag = git.tag().setObjectId(object).setName(ref.substring(R_TAGS.length())).setAnnotated(isAnnotated).setSigned(isSigned);
            if (isAnnotated) {
                tag.setMessage(input.message).setTagger(identifiedUser.get().newCommitterIdent(TimeUtil.nowTs(), TimeZone.getDefault()));
            }
            Ref result = tag.call();
            tagCache.updateFastForward(resource.getNameKey(), ref, ObjectId.zeroId(), result.getObjectId());
            referenceUpdated.fire(resource.getNameKey(), ref, ObjectId.zeroId(), result.getObjectId(), identifiedUser.get().getAccount());
            try (RevWalk w = new RevWalk(repo)) {
                return ListTags.createTagInfo(perm, result, w);
            }
        }
    } catch (InvalidRevisionException e) {
        throw new BadRequestException("Invalid base revision");
    } catch (GitAPIException e) {
        log.error("Cannot create tag \"" + ref + "\"", e);
        throw new IOException(e);
    }
}
Also used : MethodNotAllowedException(com.google.gerrit.extensions.restapi.MethodNotAllowedException) PermissionBackend(com.google.gerrit.server.permissions.PermissionBackend) ObjectId(org.eclipse.jgit.lib.ObjectId) RevObject(org.eclipse.jgit.revwalk.RevObject) AuthException(com.google.gerrit.extensions.restapi.AuthException) TagInput(com.google.gerrit.extensions.api.projects.TagInput) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) TagCommand(org.eclipse.jgit.api.TagCommand) GitAPIException(org.eclipse.jgit.api.errors.GitAPIException) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) Ref(org.eclipse.jgit.lib.Ref) Git(org.eclipse.jgit.api.Git) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) InvalidRevisionException(com.google.gerrit.server.project.RefUtil.InvalidRevisionException)

Example 13 with RevObject

use of org.eclipse.jgit.revwalk.RevObject in project gerrit by GerritCodeReview.

the class CreateBranch method apply.

@Override
public BranchInfo apply(ProjectResource rsrc, BranchInput input) throws BadRequestException, AuthException, ResourceConflictException, IOException {
    if (input == null) {
        input = new BranchInput();
    }
    if (input.ref != null && !ref.equals(input.ref)) {
        throw new BadRequestException("ref must match URL");
    }
    if (input.revision == null) {
        input.revision = Constants.HEAD;
    }
    while (ref.startsWith("/")) {
        ref = ref.substring(1);
    }
    ref = RefNames.fullName(ref);
    if (!Repository.isValidRefName(ref)) {
        throw new BadRequestException("invalid branch name \"" + ref + "\"");
    }
    if (MagicBranch.isMagicBranch(ref)) {
        throw new BadRequestException("not allowed to create branches under \"" + MagicBranch.getMagicRefNamePrefix(ref) + "\"");
    }
    final Branch.NameKey name = new Branch.NameKey(rsrc.getNameKey(), ref);
    final RefControl refControl = rsrc.getControl().controlForRef(name);
    try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) {
        ObjectId revid = RefUtil.parseBaseRevision(repo, rsrc.getNameKey(), input.revision);
        RevWalk rw = RefUtil.verifyConnected(repo, revid);
        RevObject object = rw.parseAny(revid);
        if (ref.startsWith(Constants.R_HEADS)) {
            //
            try {
                object = rw.parseCommit(object);
            } catch (IncorrectObjectTypeException notCommit) {
                throw new BadRequestException("\"" + input.revision + "\" not a commit");
            }
        }
        if (!refControl.canCreate(db.get(), repo, object)) {
            throw new AuthException("Cannot create \"" + ref + "\"");
        }
        try {
            final RefUpdate u = repo.updateRef(ref);
            u.setExpectedOldObjectId(ObjectId.zeroId());
            u.setNewObjectId(object.copy());
            u.setRefLogIdent(identifiedUser.get().newRefLogIdent());
            u.setRefLogMessage("created via REST from " + input.revision, false);
            refCreationValidator.validateRefOperation(rsrc.getName(), identifiedUser.get(), u);
            final RefUpdate.Result result = u.update(rw);
            switch(result) {
                case FAST_FORWARD:
                case NEW:
                case NO_CHANGE:
                    referenceUpdated.fire(name.getParentKey(), u, ReceiveCommand.Type.CREATE, identifiedUser.get().getAccount());
                    break;
                case LOCK_FAILURE:
                    if (repo.getRefDatabase().exactRef(ref) != null) {
                        throw new ResourceConflictException("branch \"" + ref + "\" already exists");
                    }
                    String refPrefix = RefUtil.getRefPrefix(ref);
                    while (!Constants.R_HEADS.equals(refPrefix)) {
                        if (repo.getRefDatabase().exactRef(refPrefix) != null) {
                            throw new ResourceConflictException("Cannot create branch \"" + ref + "\" since it conflicts with branch \"" + refPrefix + "\".");
                        }
                        refPrefix = RefUtil.getRefPrefix(refPrefix);
                    }
                //$FALL-THROUGH$
                case FORCED:
                case IO_FAILURE:
                case NOT_ATTEMPTED:
                case REJECTED:
                case REJECTED_CURRENT_BRANCH:
                case RENAMED:
                default:
                    {
                        throw new IOException(result.name());
                    }
            }
            BranchInfo info = new BranchInfo();
            info.ref = ref;
            info.revision = revid.getName();
            info.canDelete = permissionBackend.user(identifiedUser).ref(name).testOrFalse(RefPermission.DELETE) ? true : null;
            return info;
        } catch (IOException err) {
            log.error("Cannot create branch \"" + name + "\"", err);
            throw err;
        }
    } catch (RefUtil.InvalidRevisionException e) {
        throw new BadRequestException("invalid revision \"" + input.revision + "\"");
    }
}
Also used : BranchInfo(com.google.gerrit.extensions.api.projects.BranchInfo) ObjectId(org.eclipse.jgit.lib.ObjectId) RevObject(org.eclipse.jgit.revwalk.RevObject) AuthException(com.google.gerrit.extensions.restapi.AuthException) IncorrectObjectTypeException(org.eclipse.jgit.errors.IncorrectObjectTypeException) IOException(java.io.IOException) RevWalk(org.eclipse.jgit.revwalk.RevWalk) Repository(org.eclipse.jgit.lib.Repository) ResourceConflictException(com.google.gerrit.extensions.restapi.ResourceConflictException) MagicBranch(com.google.gerrit.server.util.MagicBranch) Branch(com.google.gerrit.reviewdb.client.Branch) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) BranchInput(com.google.gerrit.extensions.api.projects.BranchInput) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 14 with RevObject

use of org.eclipse.jgit.revwalk.RevObject in project gerrit by GerritCodeReview.

the class ListTags method createTagInfo.

public static TagInfo createTagInfo(PermissionBackend.ForRef perm, Ref ref, RevWalk rw) throws MissingObjectException, IOException {
    RevObject object = rw.parseAny(ref.getObjectId());
    boolean canDelete = perm.testOrFalse(RefPermission.DELETE);
    if (object instanceof RevTag) {
        // Annotated or signed tag
        RevTag tag = (RevTag) object;
        PersonIdent tagger = tag.getTaggerIdent();
        return new TagInfo(ref.getName(), tag.getName(), tag.getObject().getName(), tag.getFullMessage().trim(), tagger != null ? CommonConverters.toGitPerson(tag.getTaggerIdent()) : null, canDelete);
    }
    // Lightweight tag
    return new TagInfo(ref.getName(), ref.getObjectId().getName(), canDelete);
}
Also used : RevTag(org.eclipse.jgit.revwalk.RevTag) RevObject(org.eclipse.jgit.revwalk.RevObject) PersonIdent(org.eclipse.jgit.lib.PersonIdent) TagInfo(com.google.gerrit.extensions.api.projects.TagInfo)

Example 15 with RevObject

use of org.eclipse.jgit.revwalk.RevObject in project gerrit by GerritCodeReview.

the class AutoMerger method merge.

/**
   * Perform an auto-merge of the parents of the given merge commit.
   *
   * @return auto-merge commit or {@code null} if an auto-merge commit couldn't be created. Headers
   *     of the returned RevCommit are parsed.
   */
public RevCommit merge(Repository repo, RevWalk rw, final ObjectInserter ins, RevCommit merge, ThreeWayMergeStrategy mergeStrategy) throws IOException {
    checkArgument(rw.getObjectReader().getCreatedFromInserter() == ins);
    InMemoryInserter tmpIns = null;
    if (ins instanceof InMemoryInserter) {
        // Caller gave us an in-memory inserter, so ensure anything we write from
        // this method is visible to them.
        tmpIns = (InMemoryInserter) ins;
    } else if (!save) {
        // If we don't plan on saving results, use a fully in-memory inserter.
        // Using just a non-flushing wrapper is not sufficient, since in
        // particular DfsInserter might try to write to storage after exceeding an
        // internal buffer size.
        tmpIns = new InMemoryInserter(rw.getObjectReader());
    }
    rw.parseHeaders(merge);
    String refName = RefNames.refsCacheAutomerge(merge.name());
    Ref ref = repo.getRefDatabase().exactRef(refName);
    if (ref != null && ref.getObjectId() != null) {
        RevObject obj = rw.parseAny(ref.getObjectId());
        if (obj instanceof RevCommit) {
            return (RevCommit) obj;
        }
        return commit(repo, rw, tmpIns, ins, refName, obj, merge);
    }
    ResolveMerger m = (ResolveMerger) mergeStrategy.newMerger(repo, true);
    DirCache dc = DirCache.newInCore();
    m.setDirCache(dc);
    m.setObjectInserter(tmpIns == null ? new NonFlushingWrapper(ins) : tmpIns);
    boolean couldMerge;
    try {
        couldMerge = m.merge(merge.getParents());
    } catch (IOException e) {
        // It is not safe to continue further down in this method as throwing
        // an exception most likely means that the merge tree was not created
        // and m.getMergeResults() is empty. This would mean that all paths are
        // unmerged and Gerrit UI would show all paths in the patch list.
        log.warn("Error attempting automerge " + refName, e);
        return null;
    }
    ObjectId treeId;
    if (couldMerge) {
        treeId = m.getResultTreeId();
    } else {
        RevCommit ours = merge.getParent(0);
        RevCommit theirs = merge.getParent(1);
        rw.parseBody(ours);
        rw.parseBody(theirs);
        String oursMsg = ours.getShortMessage();
        String theirsMsg = theirs.getShortMessage();
        String oursName = String.format("HEAD   (%s %s)", ours.abbreviate(6).name(), oursMsg.substring(0, Math.min(oursMsg.length(), 60)));
        String theirsName = String.format("BRANCH (%s %s)", theirs.abbreviate(6).name(), theirsMsg.substring(0, Math.min(theirsMsg.length(), 60)));
        MergeFormatter fmt = new MergeFormatter();
        Map<String, MergeResult<? extends Sequence>> r = m.getMergeResults();
        Map<String, ObjectId> resolved = new HashMap<>();
        for (Map.Entry<String, MergeResult<? extends Sequence>> entry : r.entrySet()) {
            MergeResult<? extends Sequence> p = entry.getValue();
            try (TemporaryBuffer buf = new TemporaryBuffer.LocalFile(null, 10 * 1024 * 1024)) {
                fmt.formatMerge(buf, p, "BASE", oursName, theirsName, UTF_8.name());
                buf.close();
                try (InputStream in = buf.openInputStream()) {
                    resolved.put(entry.getKey(), ins.insert(Constants.OBJ_BLOB, buf.length(), in));
                }
            }
        }
        DirCacheBuilder builder = dc.builder();
        int cnt = dc.getEntryCount();
        for (int i = 0; i < cnt; ) {
            DirCacheEntry entry = dc.getEntry(i);
            if (entry.getStage() == 0) {
                builder.add(entry);
                i++;
                continue;
            }
            int next = dc.nextEntry(i);
            String path = entry.getPathString();
            DirCacheEntry res = new DirCacheEntry(path);
            if (resolved.containsKey(path)) {
                // For a file with content merge conflict that we produced a result
                // above on, collapse the file down to a single stage 0 with just
                // the blob content, and a randomly selected mode (the lowest stage,
                // which should be the merge base, or ours).
                res.setFileMode(entry.getFileMode());
                res.setObjectId(resolved.get(path));
            } else if (next == i + 1) {
                // If there is exactly one stage present, shouldn't be a conflict...
                res.setFileMode(entry.getFileMode());
                res.setObjectId(entry.getObjectId());
            } else if (next == i + 2) {
                // Two stages suggests a delete/modify conflict. Pick the higher
                // stage as the automatic result.
                entry = dc.getEntry(i + 1);
                res.setFileMode(entry.getFileMode());
                res.setObjectId(entry.getObjectId());
            } else {
                // 3 stage conflict, no resolve above
                // Punt on the 3-stage conflict and show the base, for now.
                res.setFileMode(entry.getFileMode());
                res.setObjectId(entry.getObjectId());
            }
            builder.add(res);
            i = next;
        }
        builder.finish();
        treeId = dc.writeTree(ins);
    }
    return commit(repo, rw, tmpIns, ins, refName, treeId, merge);
}
Also used : DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) HashMap(java.util.HashMap) MergeResult(org.eclipse.jgit.merge.MergeResult) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RevObject(org.eclipse.jgit.revwalk.RevObject) ObjectId(org.eclipse.jgit.lib.ObjectId) InputStream(java.io.InputStream) InMemoryInserter(com.google.gerrit.server.git.InMemoryInserter) IOException(java.io.IOException) Sequence(org.eclipse.jgit.diff.Sequence) ResolveMerger(org.eclipse.jgit.merge.ResolveMerger) DirCache(org.eclipse.jgit.dircache.DirCache) Ref(org.eclipse.jgit.lib.Ref) TemporaryBuffer(org.eclipse.jgit.util.TemporaryBuffer) HashMap(java.util.HashMap) Map(java.util.Map) MergeFormatter(org.eclipse.jgit.merge.MergeFormatter)

Aggregations

RevObject (org.eclipse.jgit.revwalk.RevObject)25 RevWalk (org.eclipse.jgit.revwalk.RevWalk)14 IOException (java.io.IOException)10 ObjectId (org.eclipse.jgit.lib.ObjectId)10 RevCommit (org.eclipse.jgit.revwalk.RevCommit)10 Repository (org.eclipse.jgit.lib.Repository)8 Ref (org.eclipse.jgit.lib.Ref)7 RevTag (org.eclipse.jgit.revwalk.RevTag)6 RevTree (org.eclipse.jgit.revwalk.RevTree)6 Map (java.util.Map)4 IncorrectObjectTypeException (org.eclipse.jgit.errors.IncorrectObjectTypeException)4 TagCommand (org.eclipse.jgit.api.TagCommand)3 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)3 PersonIdent (org.eclipse.jgit.lib.PersonIdent)3 ImmutableMap (com.google.common.collect.ImmutableMap)2 AuthException (com.google.gerrit.extensions.restapi.AuthException)2 BadRequestException (com.google.gerrit.extensions.restapi.BadRequestException)2 ResourceConflictException (com.google.gerrit.extensions.restapi.ResourceConflictException)2 OutputStream (java.io.OutputStream)2 Writer (java.io.Writer)2