Search in sources :

Example 21 with RevCommit

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

the class AutoMerger method commit.

private RevCommit commit(Repository repo, RevWalk rw, @Nullable InMemoryInserter tmpIns, ObjectInserter ins, String refName, ObjectId tree, RevCommit merge) throws IOException {
    rw.parseHeaders(merge);
    // For maximum stability, choose a single ident using the committer time of
    // the input commit, using the server name and timezone.
    PersonIdent ident = new PersonIdent(gerritIdent, merge.getCommitterIdent().getWhen(), gerritIdent.getTimeZone());
    CommitBuilder cb = new CommitBuilder();
    cb.setAuthor(ident);
    cb.setCommitter(ident);
    cb.setTreeId(tree);
    cb.setMessage("Auto-merge of " + merge.name() + '\n');
    for (RevCommit p : merge.getParents()) {
        cb.addParentId(p);
    }
    if (!save) {
        checkArgument(tmpIns != null);
        try (ObjectReader tmpReader = tmpIns.newReader();
            RevWalk tmpRw = new RevWalk(tmpReader)) {
            return tmpRw.parseCommit(tmpIns.insert(cb));
        }
    }
    checkArgument(tmpIns == null);
    checkArgument(!(ins instanceof InMemoryInserter));
    ObjectId commitId = ins.insert(cb);
    ins.flush();
    RefUpdate ru = repo.updateRef(refName);
    ru.setNewObjectId(commitId);
    ru.disableRefLog();
    ru.forceUpdate();
    return rw.parseCommit(commitId);
}
Also used : PersonIdent(org.eclipse.jgit.lib.PersonIdent) GerritPersonIdent(com.google.gerrit.server.GerritPersonIdent) ObjectId(org.eclipse.jgit.lib.ObjectId) CommitBuilder(org.eclipse.jgit.lib.CommitBuilder) ObjectReader(org.eclipse.jgit.lib.ObjectReader) InMemoryInserter(com.google.gerrit.server.git.InMemoryInserter) RevWalk(org.eclipse.jgit.revwalk.RevWalk) RevCommit(org.eclipse.jgit.revwalk.RevCommit) RefUpdate(org.eclipse.jgit.lib.RefUpdate)

Example 22 with RevCommit

use of org.eclipse.jgit.revwalk.RevCommit 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)

Example 23 with RevCommit

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

the class PatchListLoader method aFor.

private RevObject aFor(PatchListKey key, Repository repo, RevWalk rw, ObjectInserter ins, RevCommit b) throws IOException {
    if (key.getOldId() != null) {
        return rw.parseAny(key.getOldId());
    }
    switch(b.getParentCount()) {
        case 0:
            return rw.parseAny(emptyTree(ins));
        case 1:
            {
                RevCommit r = b.getParent(0);
                rw.parseBody(r);
                return r;
            }
        case 2:
            if (key.getParentNum() != null) {
                RevCommit r = b.getParent(key.getParentNum() - 1);
                rw.parseBody(r);
                return r;
            }
            return autoMerger.merge(repo, rw, ins, b, mergeStrategy);
        default:
            // TODO(sop) handle an octopus merge.
            return null;
    }
}
Also used : RevCommit(org.eclipse.jgit.revwalk.RevCommit)

Example 24 with RevCommit

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

the class ChangeNotesTest method tagInlineCommenrts.

@Test
public void tagInlineCommenrts() throws Exception {
    String tag = "jenkins";
    Change c = newChange();
    RevCommit commit = tr.commit().message("PS2").create();
    ChangeUpdate update = newUpdate(c, changeOwner);
    update.putComment(Status.PUBLISHED, newComment(c.currentPatchSetId(), "a.txt", "uuid1", new CommentRange(1, 2, 3, 4), 1, changeOwner, null, TimeUtil.nowTs(), "Comment", (short) 1, commit.name(), false));
    update.setTag(tag);
    update.commit();
    ChangeNotes notes = newNotes(c);
    ImmutableListMultimap<RevId, Comment> comments = notes.getComments();
    assertThat(comments).hasSize(1);
    assertThat(comments.entries().asList().get(0).getValue().tag).isEqualTo(tag);
}
Also used : Comment(com.google.gerrit.reviewdb.client.Comment) CommentRange(com.google.gerrit.reviewdb.client.CommentRange) Change(com.google.gerrit.reviewdb.client.Change) RevId(com.google.gerrit.reviewdb.client.RevId) RevCommit(org.eclipse.jgit.revwalk.RevCommit) Test(org.junit.Test)

Example 25 with RevCommit

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

the class ChangeIT method deleteChangeAsUserWithDeleteOwnChangesPermission.

@Test
@TestProjectInput(cloneAs = "user")
public void deleteChangeAsUserWithDeleteOwnChangesPermission() throws Exception {
    allow(Permission.DELETE_OWN_CHANGES, REGISTERED_USERS, "refs/*");
    try {
        PushOneCommit.Result changeResult = pushFactory.create(db, user.getIdent(), testRepo).to("refs/for/master");
        String changeId = changeResult.getChangeId();
        int id = changeResult.getChange().getId().id;
        RevCommit commit = changeResult.getCommit();
        setApiUser(user);
        gApi.changes().id(changeId).delete();
        assertThat(query(changeId)).isEmpty();
        String ref = new Change.Id(id).toRefPrefix() + "1";
        eventRecorder.assertRefUpdatedEvents(project.get(), ref, null, commit, commit, null);
    } finally {
        removePermission(project, "refs/*", Permission.DELETE_OWN_CHANGES);
    }
}
Also used : LabelId(com.google.gerrit.reviewdb.client.LabelId) PushOneCommit(com.google.gerrit.acceptance.PushOneCommit) RevCommit(org.eclipse.jgit.revwalk.RevCommit) TestProjectInput(com.google.gerrit.acceptance.TestProjectInput) AbstractDaemonTest(com.google.gerrit.acceptance.AbstractDaemonTest) Test(org.junit.Test)

Aggregations

RevCommit (org.eclipse.jgit.revwalk.RevCommit)1300 Test (org.junit.Test)650 RevWalk (org.eclipse.jgit.revwalk.RevWalk)332 ObjectId (org.eclipse.jgit.lib.ObjectId)292 Repository (org.eclipse.jgit.lib.Repository)272 IOException (java.io.IOException)221 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)190 Ref (org.eclipse.jgit.lib.Ref)174 ArrayList (java.util.ArrayList)134 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)133 File (java.io.File)133 Git (org.eclipse.jgit.api.Git)133 PersonIdent (org.eclipse.jgit.lib.PersonIdent)105 Change (com.google.gerrit.entities.Change)87 TestRepository (org.eclipse.jgit.junit.TestRepository)72 GitAPIException (org.eclipse.jgit.api.errors.GitAPIException)69 ObjectReader (org.eclipse.jgit.lib.ObjectReader)64 ChangeInfo (com.google.gerrit.extensions.common.ChangeInfo)61 List (java.util.List)61 HashMap (java.util.HashMap)57