Search in sources :

Example 1 with DirCacheBuilder

use of org.eclipse.jgit.dircache.DirCacheBuilder in project gerrit by GerritCodeReview.

the class SubmoduleOp method readTree.

private static DirCache readTree(RevWalk rw, ObjectId base) throws IOException {
    final DirCache dc = DirCache.newInCore();
    final DirCacheBuilder b = dc.builder();
    b.addTree(// no prefix path
    new byte[0], // standard stage
    DirCacheEntry.STAGE_0, rw.getObjectReader(), rw.parseTree(base));
    b.finish();
    return dc;
}
Also used : DirCache(org.eclipse.jgit.dircache.DirCache) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder)

Example 2 with DirCacheBuilder

use of org.eclipse.jgit.dircache.DirCacheBuilder in project gerrit by GerritCodeReview.

the class CommitMsgHookTest method dirCacheAltersId.

@Test
public void dirCacheAltersId() throws Exception {
    assertEquals("a\n" + //
    "\n" + //
    "Change-Id: I7fc3876fee63c766a2063df97fbe04a2dddd8d7c\n", //
    call("a\n"));
    final DirCacheBuilder builder = repository.lockDirCache().builder();
    builder.add(file("A"));
    assertTrue(builder.commit());
    assertEquals("a\n" + //
    "\n" + //
    "Change-Id: If56597ea9759f23b070677ea6f064c60c38da631\n", //
    call("a\n"));
}
Also used : DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) Test(org.junit.Test)

Example 3 with DirCacheBuilder

use of org.eclipse.jgit.dircache.DirCacheBuilder 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 4 with DirCacheBuilder

use of org.eclipse.jgit.dircache.DirCacheBuilder in project egit by eclipse.

the class GitMoveDeleteHookTest method testMoveFolderWithFileWithConflictsShouldBeCanceled.

@Theory
public void testMoveFolderWithFileWithConflictsShouldBeCanceled(boolean autoStageMoves) throws Exception {
    configureAutoStageMoves(autoStageMoves);
    TestProject project = initRepoInsideProjectInsideWorkspace();
    String filePath = "folder/file.txt";
    IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
    Repository repo = testRepository.getRepository();
    DirCache index = repo.lockDirCache();
    DirCacheBuilder builder = index.builder();
    addUnmergedEntry(filePath, builder);
    builder.commit();
    try {
        project.getProject().getFolder("folder").move(project.getProject().getFolder("newfolder").getFullPath(), false, null);
        fail("Expected move of folder with file with conflicts to fail.");
    } catch (CoreException e) {
        IStatus status = e.getStatus();
        assertNotNull(status);
        assertEquals(IStatus.WARNING, status.getSeverity());
    }
    assertTrue("File should still exist at old location", file.exists());
    DirCache indexAfter = repo.readDirCache();
    DirCacheEntry entry = indexAfter.getEntry(filePath);
    assertEquals("Expected entry to still be in non-zero (conflict) stage", DirCacheEntry.STAGE_1, entry.getStage());
}
Also used : DirCache(org.eclipse.jgit.dircache.DirCache) TestRepository(org.eclipse.egit.core.test.TestRepository) Repository(org.eclipse.jgit.lib.Repository) IStatus(org.eclipse.core.runtime.IStatus) IFile(org.eclipse.core.resources.IFile) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) TestProject(org.eclipse.egit.core.test.TestProject) CoreException(org.eclipse.core.runtime.CoreException) Theory(org.junit.experimental.theories.Theory)

Example 5 with DirCacheBuilder

use of org.eclipse.jgit.dircache.DirCacheBuilder in project egit by eclipse.

the class GitMoveDeleteHookTest method testMoveFileWithConflictsShouldBeCanceled.

@Theory
public void testMoveFileWithConflictsShouldBeCanceled(boolean autoStageMoves) throws Exception {
    configureAutoStageMoves(autoStageMoves);
    TestProject project = initRepoInsideProjectInsideWorkspace();
    String filePath = "file.txt";
    IFile file = testUtils.addFileToProject(project.getProject(), filePath, "some text");
    Repository repo = testRepository.getRepository();
    DirCache index = repo.lockDirCache();
    DirCacheBuilder builder = index.builder();
    addUnmergedEntry(filePath, builder);
    builder.commit();
    try {
        file.move(new Path("destination.txt"), false, null);
        fail("Expected move of file with conflicts to fail.");
    } catch (CoreException e) {
        IStatus status = e.getStatus();
        assertNotNull(status);
        assertEquals(IStatus.WARNING, status.getSeverity());
    }
    assertTrue("File should still exist at old location", file.exists());
    DirCache indexAfter = repo.readDirCache();
    DirCacheEntry entry = indexAfter.getEntry(filePath);
    assertEquals("Expected entry to still be in non-zero (conflict) stage", DirCacheEntry.STAGE_1, entry.getStage());
}
Also used : IPath(org.eclipse.core.runtime.IPath) Path(org.eclipse.core.runtime.Path) DirCache(org.eclipse.jgit.dircache.DirCache) TestRepository(org.eclipse.egit.core.test.TestRepository) Repository(org.eclipse.jgit.lib.Repository) IStatus(org.eclipse.core.runtime.IStatus) IFile(org.eclipse.core.resources.IFile) DirCacheBuilder(org.eclipse.jgit.dircache.DirCacheBuilder) DirCacheEntry(org.eclipse.jgit.dircache.DirCacheEntry) TestProject(org.eclipse.egit.core.test.TestProject) CoreException(org.eclipse.core.runtime.CoreException) Theory(org.junit.experimental.theories.Theory)

Aggregations

DirCacheBuilder (org.eclipse.jgit.dircache.DirCacheBuilder)22 DirCache (org.eclipse.jgit.dircache.DirCache)20 DirCacheEntry (org.eclipse.jgit.dircache.DirCacheEntry)15 ObjectInserter (org.eclipse.jgit.lib.ObjectInserter)8 ObjectId (org.eclipse.jgit.lib.ObjectId)7 IOException (java.io.IOException)6 Repository (org.eclipse.jgit.lib.Repository)6 InputStream (java.io.InputStream)4 RevWalk (org.eclipse.jgit.revwalk.RevWalk)4 IStatus (org.eclipse.core.runtime.IStatus)3 HashMap (java.util.HashMap)2 Map (java.util.Map)2 TreeSet (java.util.TreeSet)2 IFile (org.eclipse.core.resources.IFile)2 CoreException (org.eclipse.core.runtime.CoreException)2 TestProject (org.eclipse.egit.core.test.TestProject)2 TestRepository (org.eclipse.egit.core.test.TestRepository)2 ConcurrentRefUpdateException (org.eclipse.jgit.api.errors.ConcurrentRefUpdateException)2 JGitInternalException (org.eclipse.jgit.api.errors.JGitInternalException)2 Sequence (org.eclipse.jgit.diff.Sequence)2