in org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java [203:336]
private MergeResult mergeModified(String mergedFilePath, boolean showPrompt)
throws Exception {
outw.println(MessageFormat.format(CLIText.get().mergeToolNormalConflict,
mergedFilePath));
outw.flush();
boolean isMergeSuccessful = true;
ContentSource baseSource = ContentSource.create(db.newObjectReader());
ContentSource localSource = ContentSource.create(db.newObjectReader());
ContentSource remoteSource = ContentSource.create(db.newObjectReader());
// temporary directory if mergetool.writeToTemp == true
File tempDir = mergeTools.createTempDirectory();
// the parent directory for temp files (can be same as tempDir or just
// the worktree dir)
File tempFilesParent = tempDir != null ? tempDir : db.getWorkTree();
try {
FileElement base = null;
FileElement local = null;
FileElement remote = null;
FileElement merged = new FileElement(mergedFilePath, Type.MERGED,
db.getWorkTree());
DirCache cache = db.readDirCache();
try (RevWalk revWalk = new RevWalk(db);
TreeWalk treeWalk = new TreeWalk(db,
revWalk.getObjectReader())) {
treeWalk.setFilter(
PathFilterGroup.createFromStrings(mergedFilePath));
DirCacheIterator cacheIter = new DirCacheIterator(cache);
treeWalk.addTree(cacheIter);
while (treeWalk.next()) {
if (treeWalk.isSubtree()) {
treeWalk.enterSubtree();
continue;
}
final EolStreamType eolStreamType = treeWalk
.getEolStreamType(CHECKOUT_OP);
final String filterCommand = treeWalk.getFilterCommand(
Constants.ATTR_FILTER_TYPE_SMUDGE);
WorkingTreeOptions opt = db.getConfig()
.get(WorkingTreeOptions.KEY);
CheckoutMetadata checkoutMetadata = new CheckoutMetadata(
eolStreamType, filterCommand);
DirCacheEntry entry = treeWalk
.getTree(DirCacheIterator.class).getDirCacheEntry();
if (entry == null) {
continue;
}
ObjectId id = entry.getObjectId();
switch (entry.getStage()) {
case DirCacheEntry.STAGE_1:
base = new FileElement(mergedFilePath, Type.BASE);
DirCacheCheckout.getContent(db, mergedFilePath,
checkoutMetadata,
baseSource.open(mergedFilePath, id), opt,
new FileOutputStream(
base.createTempFile(tempFilesParent)));
break;
case DirCacheEntry.STAGE_2:
local = new FileElement(mergedFilePath, Type.LOCAL);
DirCacheCheckout.getContent(db, mergedFilePath,
checkoutMetadata,
localSource.open(mergedFilePath, id), opt,
new FileOutputStream(
local.createTempFile(tempFilesParent)));
break;
case DirCacheEntry.STAGE_3:
remote = new FileElement(mergedFilePath, Type.REMOTE);
DirCacheCheckout.getContent(db, mergedFilePath,
checkoutMetadata,
remoteSource.open(mergedFilePath, id), opt,
new FileOutputStream(remote
.createTempFile(tempFilesParent)));
break;
}
}
}
if ((local == null) || (remote == null)) {
throw die(MessageFormat.format(CLIText.get().mergeToolDied,
mergedFilePath));
}
long modifiedBefore = merged.getFile().lastModified();
try {
// TODO: check how to return the exit-code of the
// tool to jgit / java runtime ?
// int rc =...
Optional<ExecutionResult> optionalResult = mergeTools.merge(
local, remote, merged, base, tempDir, toolName, prompt,
gui, this::promptForLaunch, this::informUserNoTool);
if (optionalResult.isPresent()) {
ExecutionResult result = optionalResult.get();
Charset defaultCharset = SystemReader.getInstance()
.getDefaultCharset();
outw.println(new String(result.getStdout().toByteArray(),
defaultCharset));
outw.flush();
errw.println(new String(result.getStderr().toByteArray(),
defaultCharset));
errw.flush();
} else {
return MergeResult.ABORTED;
}
} catch (ToolException e) {
isMergeSuccessful = false;
outw.println(e.getResultStdout());
outw.flush();
errw.println(e.getMessage());
errw.println(MessageFormat.format(
CLIText.get().mergeToolMergeFailed, mergedFilePath));
errw.flush();
if (e.isCommandExecutionError()) {
throw die(CLIText.get().mergeToolExecutionError, e);
}
}
// if merge was successful check file modified
if (isMergeSuccessful) {
long modifiedAfter = merged.getFile().lastModified();
if (modifiedBefore == modifiedAfter) {
outw.println(MessageFormat.format(
CLIText.get().mergeToolFileUnchanged,
mergedFilePath));
isMergeSuccessful = !showPrompt || isMergeSuccessful();
}
}
// if automatically or manually successful
// -> add the file to the index
if (isMergeSuccessful) {
addFile(mergedFilePath);
}
} finally {
baseSource.close();
localSource.close();
remoteSource.close();
}
return isMergeSuccessful ? MergeResult.SUCCESSFUL : MergeResult.FAILED;
}