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;
}
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"));
}
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);
}
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());
}
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());
}
Aggregations