summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.pgm
diff options
context:
space:
mode:
authorAndrey Loskutov <loskutov@gmx.de>2022-06-03 15:49:45 +0200
committerAndrey Loskutov <loskutov@gmx.de>2022-06-03 15:51:54 +0200
commit2ef2a3562e9aa5c826ce063a2f1d3d8ffef1f0ce (patch)
treeb0f2988a40474499808220cd7d5fe677d87b6600 /org.eclipse.jgit.pgm
parent7b1ade51d24f6efacfddd91fcfed7137c27642d3 (diff)
parentc32694e5ae98e5c1373afcb535a76d37e5d82a29 (diff)
downloadjgit-2ef2a3562e9aa5c826ce063a2f1d3d8ffef1f0ce.tar.gz
jgit-2ef2a3562e9aa5c826ce063a2f1d3d8ffef1f0ce.zip
Merge branch 'master' into stable-6.2
* master: Adapt diff- and merge tool code for PGM and EGit usage Teach JGit to handle external diff/merge tools defined in .gitattributes Change-Id: I3aefc14160caaac859bd3548460dd755ebe42fc5
Diffstat (limited to 'org.eclipse.jgit.pgm')
-rw-r--r--org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties4
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java202
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java147
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java4
4 files changed, 207 insertions, 150 deletions
diff --git a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
index 674185df2b..b14531a1bd 100644
--- a/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
+++ b/org.eclipse.jgit.pgm/resources/org/eclipse/jgit/pgm/internal/CLIText.properties
@@ -61,6 +61,8 @@ deletedRemoteBranch=Deleted remote branch {0}
diffToolHelpSetToFollowing=''git difftool --tool=<tool>'' may be set to one of the following:\n{0}\n\tuser-defined:\n{1}\nThe following tools are valid, but not currently available:\n{2}\nSome of the tools listed above only work in a windowed\nenvironment. If run in a terminal-only session, they will fail.
diffToolLaunch=Viewing ({0}/{1}): ''{2}''\nLaunch ''{3}'' [Y/n]?
diffToolDied=external diff died, stopping at path ''{0}'' due to exception: {1}
+diffToolPromptToolName=This message is displayed because 'diff.tool' is not configured.\nSee 'git difftool --tool-help' or 'git help config' for more details.\n'git difftool' will now attempt to use one of the following tools:\n{0}\n
+diffToolUnknownToolName=Unknown diff tool '{0}'
doesNotExist={0} does not exist
dontOverwriteLocalChanges=error: Your local changes to the following file would be overwritten by merge:
everythingUpToDate=Everything up-to-date
@@ -107,6 +109,8 @@ mergeToolDeletedConflictByThem= {local}: modified file\n {remote}: deleted
mergeToolContinueUnresolvedPaths=\nContinue merging other unresolved paths [y/n]?
mergeToolWasMergeSuccessfull=Was the merge successful [y/n]?
mergeToolDeletedMergeDecision=Use (m)odified or (d)eleted file, or (a)bort?
+mergeToolPromptToolName=This message is displayed because 'merge.tool' is not configured.\nSee 'git mergetool --tool-help' or 'git help config' for more details.\n'git mergetool' will now attempt to use one of the following tools:\n{0}\n
+mergeToolUnknownToolName=Unknown merge tool '{0}'
mergeFailed=Automatic merge failed; fix conflicts and then commit the result
mergeCheckoutFailed=Please, commit your changes or stash them before you can merge.
mergeMadeBy=Merge made by the ''{0}'' strategy.
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java
index 74d91cd3d7..3e6042afee 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ * Copyright (C) 2019, Tim Neumann <tim.neumann@advantest.com>
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -22,30 +23,33 @@ import java.nio.charset.StandardCharsets;
import java.text.MessageFormat;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.concurrent.TimeUnit;
+
import org.eclipse.jgit.diff.ContentSource;
import org.eclipse.jgit.diff.ContentSource.Pair;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.diff.DiffEntry.Side;
-import org.eclipse.jgit.internal.diffmergetool.ToolException;
-import org.eclipse.jgit.internal.diffmergetool.DiffTools;
-import org.eclipse.jgit.internal.diffmergetool.FileElement;
-import org.eclipse.jgit.internal.diffmergetool.ExternalDiffTool;
import org.eclipse.jgit.diff.DiffFormatter;
import org.eclipse.jgit.dircache.DirCacheCheckout;
-import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
+import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.CorruptObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
+import org.eclipse.jgit.internal.diffmergetool.DiffTools;
+import org.eclipse.jgit.internal.diffmergetool.ExternalDiffTool;
+import org.eclipse.jgit.internal.diffmergetool.FileElement;
+import org.eclipse.jgit.internal.diffmergetool.PromptContinueHandler;
+import org.eclipse.jgit.internal.diffmergetool.ToolException;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.TextProgressMonitor;
-import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
import org.eclipse.jgit.lib.internal.BooleanTriState;
import org.eclipse.jgit.pgm.internal.CLIText;
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
@@ -58,7 +62,6 @@ import org.eclipse.jgit.treewalk.WorkingTreeIterator;
import org.eclipse.jgit.treewalk.WorkingTreeOptions;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
-import org.eclipse.jgit.util.StringUtils;
import org.eclipse.jgit.util.FS.ExecutionResult;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -75,9 +78,13 @@ class DiffTool extends TextBuiltin {
@Argument(index = 1, metaVar = "metaVar_treeish")
private AbstractTreeIterator newTree;
+ private Optional<String> toolName = Optional.empty();
+
@Option(name = "--tool", aliases = {
"-t" }, metaVar = "metaVar_tool", usage = "usage_ToolForDiff")
- private String toolName;
+ void setToolName(String name) {
+ toolName = Optional.of(name);
+ }
@Option(name = "--cached", aliases = { "--staged" }, usage = "usage_cached")
private boolean cached;
@@ -97,16 +104,16 @@ class DiffTool extends TextBuiltin {
@Option(name = "--tool-help", usage = "usage_toolHelp")
private boolean toolHelp;
- private BooleanTriState gui = BooleanTriState.UNSET;
+ private boolean gui = false;
@Option(name = "--gui", aliases = { "-g" }, usage = "usage_DiffGuiTool")
void setGui(@SuppressWarnings("unused") boolean on) {
- gui = BooleanTriState.TRUE;
+ gui = true;
}
@Option(name = "--no-gui", usage = "usage_noGui")
void noGui(@SuppressWarnings("unused") boolean on) {
- gui = BooleanTriState.FALSE;
+ gui = false;
}
private BooleanTriState trustExitCode = BooleanTriState.UNSET;
@@ -140,23 +147,12 @@ class DiffTool extends TextBuiltin {
if (toolHelp) {
showToolHelp();
} else {
- boolean showPrompt = diffTools.isInteractive();
- if (prompt != BooleanTriState.UNSET) {
- showPrompt = prompt == BooleanTriState.TRUE;
- }
- String toolNamePrompt = toolName;
- if (showPrompt) {
- if (StringUtils.isEmptyOrNull(toolNamePrompt)) {
- toolNamePrompt = diffTools.getDefaultToolName(gui);
- }
- }
// get the changed files
List<DiffEntry> files = getFiles();
if (files.size() > 0) {
- compare(files, showPrompt, toolNamePrompt);
+ compare(files);
}
}
- outw.flush();
} catch (RevisionSyntaxException | IOException e) {
throw die(e.getMessage(), e);
} finally {
@@ -164,51 +160,103 @@ class DiffTool extends TextBuiltin {
}
}
- private void compare(List<DiffEntry> files, boolean showPrompt,
- String toolNamePrompt) throws IOException {
+ private void informUserNoTool(List<String> tools) {
+ try {
+ StringBuilder toolNames = new StringBuilder();
+ for (String name : tools) {
+ toolNames.append(name + " "); //$NON-NLS-1$
+ }
+ outw.println(MessageFormat.format(
+ CLIText.get().diffToolPromptToolName, toolNames));
+ outw.flush();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+
+ private class CountingPromptContinueHandler
+ implements PromptContinueHandler {
+ private final int fileIndex;
+
+ private final int fileCount;
+
+ private final String fileName;
+
+ public CountingPromptContinueHandler(int fileIndex, int fileCount,
+ String fileName) {
+ this.fileIndex = fileIndex;
+ this.fileCount = fileCount;
+ this.fileName = fileName;
+ }
+
+ @SuppressWarnings("boxing")
+ @Override
+ public boolean prompt(String toolToLaunchName) {
+ try {
+ boolean launchCompare = true;
+ outw.println(MessageFormat.format(CLIText.get().diffToolLaunch,
+ fileIndex, fileCount, fileName, toolToLaunchName)
+ + " "); //$NON-NLS-1$
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ if ((line = br.readLine()) != null) {
+ if (!line.equalsIgnoreCase("Y")) { //$NON-NLS-1$
+ launchCompare = false;
+ }
+ }
+ return launchCompare;
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+ }
+
+ private void compare(List<DiffEntry> files) throws IOException {
ContentSource.Pair sourcePair = new ContentSource.Pair(source(oldTree),
source(newTree));
try {
for (int fileIndex = 0; fileIndex < files.size(); fileIndex++) {
DiffEntry ent = files.get(fileIndex);
- String mergedFilePath = ent.getNewPath();
- if (mergedFilePath.equals(DiffEntry.DEV_NULL)) {
- mergedFilePath = ent.getOldPath();
- }
- // check if user wants to launch compare
- boolean launchCompare = true;
- if (showPrompt) {
- launchCompare = isLaunchCompare(fileIndex + 1, files.size(),
- mergedFilePath, toolNamePrompt);
+
+ String filePath = ent.getNewPath();
+ if (filePath.equals(DiffEntry.DEV_NULL)) {
+ filePath = ent.getOldPath();
}
- if (launchCompare) {
- try {
- FileElement local = createFileElement(
- FileElement.Type.LOCAL, sourcePair, Side.OLD,
- ent);
- FileElement remote = createFileElement(
- FileElement.Type.REMOTE, sourcePair, Side.NEW,
- ent);
- FileElement merged = new FileElement(mergedFilePath,
- FileElement.Type.MERGED);
+
+ try {
+ FileElement local = createFileElement(
+ FileElement.Type.LOCAL, sourcePair, Side.OLD, ent);
+ FileElement remote = createFileElement(
+ FileElement.Type.REMOTE, sourcePair, Side.NEW, ent);
+
+ PromptContinueHandler promptContinueHandler = new CountingPromptContinueHandler(
+ fileIndex + 1, files.size(), filePath);
+
+ Optional<ExecutionResult> optionalResult = diffTools
+ .compare(local, remote, toolName, prompt, gui,
+ trustExitCode, promptContinueHandler,
+ this::informUserNoTool);
+
+ if (optionalResult.isPresent()) {
+ ExecutionResult result = optionalResult.get();
// TODO: check how to return the exit-code of the tool
// to jgit / java runtime ?
// int rc =...
- ExecutionResult result = diffTools.compare(local,
- remote, merged, toolName, prompt, gui,
- trustExitCode);
- outw.println(new String(result.getStdout().toByteArray()));
+ outw.println(
+ new String(result.getStdout().toByteArray()));
+ outw.flush();
errw.println(
new String(result.getStderr().toByteArray()));
- } catch (ToolException e) {
- outw.println(e.getResultStdout());
- outw.flush();
- errw.println(e.getMessage());
- throw die(MessageFormat.format(
- CLIText.get().diffToolDied, mergedFilePath), e);
+ errw.flush();
}
- } else {
- break;
+ } catch (ToolException e) {
+ outw.println(e.getResultStdout());
+ outw.flush();
+ errw.println(e.getMessage());
+ errw.flush();
+ throw die(MessageFormat.format(
+ CLIText.get().diffToolDied, filePath, e), e);
}
}
} finally {
@@ -216,32 +264,17 @@ class DiffTool extends TextBuiltin {
}
}
- @SuppressWarnings("boxing")
- private boolean isLaunchCompare(int fileIndex, int fileCount,
- String fileName, String toolNamePrompt) throws IOException {
- boolean launchCompare = true;
- outw.println(MessageFormat.format(CLIText.get().diffToolLaunch,
- fileIndex, fileCount, fileName, toolNamePrompt) + " "); //$NON-NLS-1$
- outw.flush();
- BufferedReader br = inputReader;
- String line = null;
- if ((line = br.readLine()) != null) {
- if (!line.equalsIgnoreCase("Y")) { //$NON-NLS-1$
- launchCompare = false;
- }
- }
- return launchCompare;
- }
-
private void showToolHelp() throws IOException {
+ Map<String, ExternalDiffTool> predefTools = diffTools
+ .getPredefinedTools(true);
StringBuilder availableToolNames = new StringBuilder();
- for (String name : diffTools.getAvailableTools().keySet()) {
- availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
- }
StringBuilder notAvailableToolNames = new StringBuilder();
- for (String name : diffTools.getNotAvailableTools().keySet()) {
- notAvailableToolNames
- .append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ for (String name : predefTools.keySet()) {
+ if (predefTools.get(name).isAvailable()) {
+ availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ } else {
+ notAvailableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ }
}
StringBuilder userToolNames = new StringBuilder();
Map<String, ExternalDiffTool> userTools = diffTools
@@ -289,12 +322,12 @@ class DiffTool extends TextBuiltin {
}
private FileElement createFileElement(FileElement.Type elementType,
- Pair pair, Side side, DiffEntry entry)
- throws NoWorkTreeException, CorruptObjectException, IOException,
- ToolException {
+ Pair pair, Side side, DiffEntry entry) throws NoWorkTreeException,
+ CorruptObjectException, IOException, ToolException {
String entryPath = side == Side.NEW ? entry.getNewPath()
: entry.getOldPath();
- FileElement fileElement = new FileElement(entryPath, elementType);
+ FileElement fileElement = new FileElement(entryPath, elementType,
+ db.getWorkTree());
if (!pair.isWorkingTreeSource(side) && !fileElement.isNullPath()) {
try (RevWalk revWalk = new RevWalk(db);
TreeWalk treeWalk = new TreeWalk(db,
@@ -323,7 +356,8 @@ class DiffTool extends TextBuiltin {
fileElement.createTempFile(null)));
} else {
throw new ToolException("Cannot find path '" + entryPath //$NON-NLS-1$
- + "' in staging area!", null); //$NON-NLS-1$
+ + "' in staging area!", //$NON-NLS-1$
+ null);
}
}
}
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java
index 9712770758..2a411b81fe 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java
@@ -1,5 +1,6 @@
/*
* Copyright (C) 2018-2022, Andre Bossert <andre.bossert@siemens.com>
+ * Copyright (C) 2019, Tim Neumann <tim.neumann@advantest.com>
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -22,6 +23,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.TreeMap;
import org.eclipse.jgit.api.Git;
@@ -29,29 +31,29 @@ import org.eclipse.jgit.api.Status;
import org.eclipse.jgit.api.StatusCommand;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.diff.ContentSource;
-import org.eclipse.jgit.internal.diffmergetool.FileElement.Type;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheCheckout;
+import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
-import org.eclipse.jgit.dircache.DirCacheCheckout.CheckoutMetadata;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.internal.diffmergetool.ExternalMergeTool;
import org.eclipse.jgit.internal.diffmergetool.FileElement;
+import org.eclipse.jgit.internal.diffmergetool.FileElement.Type;
import org.eclipse.jgit.internal.diffmergetool.MergeTools;
import org.eclipse.jgit.internal.diffmergetool.ToolException;
-import org.eclipse.jgit.lib.IndexDiff.StageState;
-import org.eclipse.jgit.revwalk.RevWalk;
-import org.eclipse.jgit.treewalk.TreeWalk;
-import org.eclipse.jgit.treewalk.WorkingTreeOptions;
-import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
+import org.eclipse.jgit.lib.IndexDiff.StageState;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.internal.BooleanTriState;
-import org.eclipse.jgit.lib.CoreConfig.EolStreamType;
import org.eclipse.jgit.pgm.internal.CLIText;
+import org.eclipse.jgit.revwalk.RevWalk;
+import org.eclipse.jgit.treewalk.TreeWalk;
+import org.eclipse.jgit.treewalk.WorkingTreeOptions;
+import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
import org.eclipse.jgit.util.FS.ExecutionResult;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -61,9 +63,13 @@ import org.kohsuke.args4j.spi.RestOfArgumentsHandler;
class MergeTool extends TextBuiltin {
private MergeTools mergeTools;
+ private Optional<String> toolName = Optional.empty();
+
@Option(name = "--tool", aliases = {
"-t" }, metaVar = "metaVar_tool", usage = "usage_ToolForMerge")
- private String toolName;
+ void setToolName(String name) {
+ toolName = Optional.of(name);
+ }
private BooleanTriState prompt = BooleanTriState.UNSET;
@@ -80,16 +86,16 @@ class MergeTool extends TextBuiltin {
@Option(name = "--tool-help", usage = "usage_toolHelp")
private boolean toolHelp;
- private BooleanTriState gui = BooleanTriState.UNSET;
+ private boolean gui = false;
@Option(name = "--gui", aliases = { "-g" }, usage = "usage_MergeGuiTool")
void setGui(@SuppressWarnings("unused") boolean on) {
- gui = BooleanTriState.TRUE;
+ gui = true;
}
@Option(name = "--no-gui", usage = "usage_noGui")
void noGui(@SuppressWarnings("unused") boolean on) {
- gui = BooleanTriState.FALSE;
+ gui = false;
}
@Argument(required = false, index = 0, metaVar = "metaVar_paths")
@@ -115,20 +121,10 @@ class MergeTool extends TextBuiltin {
if (toolHelp) {
showToolHelp();
} else {
- // get prompt
- boolean showPrompt = mergeTools.isInteractive();
- if (prompt != BooleanTriState.UNSET) {
- showPrompt = prompt == BooleanTriState.TRUE;
- }
- // get passed or default tool name
- String toolNameSelected = toolName;
- if ((toolNameSelected == null) || toolNameSelected.isEmpty()) {
- toolNameSelected = mergeTools.getDefaultToolName(gui);
- }
// get the changed files
Map<String, StageState> files = getFiles();
if (files.size() > 0) {
- merge(files, showPrompt, toolNameSelected);
+ merge(files);
} else {
outw.println(CLIText.get().mergeToolNoFiles);
}
@@ -139,8 +135,21 @@ class MergeTool extends TextBuiltin {
}
}
- private void merge(Map<String, StageState> files, boolean showPrompt,
- String toolNamePrompt) throws Exception {
+ private void informUserNoTool(List<String> tools) {
+ try {
+ StringBuilder toolNames = new StringBuilder();
+ for (String name : tools) {
+ toolNames.append(name + " "); //$NON-NLS-1$
+ }
+ outw.println(MessageFormat
+ .format(CLIText.get().mergeToolPromptToolName, toolNames));
+ outw.flush();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
+ }
+ }
+
+ private void merge(Map<String, StageState> files) throws Exception {
// sort file names
List<String> mergedFilePaths = new ArrayList<>(files.keySet());
Collections.sort(mergedFilePaths);
@@ -152,6 +161,10 @@ class MergeTool extends TextBuiltin {
outw.println(MessageFormat.format(CLIText.get().mergeToolMerging,
mergedFiles));
outw.flush();
+ boolean showPrompt = mergeTools.isInteractive();
+ if (prompt != BooleanTriState.UNSET) {
+ showPrompt = prompt == BooleanTriState.TRUE;
+ }
// merge the files
MergeResult mergeResult = MergeResult.SUCCESSFUL;
for (String mergedFilePath : mergedFilePaths) {
@@ -169,8 +182,7 @@ class MergeTool extends TextBuiltin {
// get file stage state and merge
StageState fileState = files.get(mergedFilePath);
if (fileState == StageState.BOTH_MODIFIED) {
- mergeResult = mergeModified(mergedFilePath, showPrompt,
- toolNamePrompt);
+ mergeResult = mergeModified(mergedFilePath, showPrompt);
} else if ((fileState == StageState.DELETED_BY_US)
|| (fileState == StageState.DELETED_BY_THEM)) {
mergeResult = mergeDeleted(mergedFilePath,
@@ -184,19 +196,11 @@ class MergeTool extends TextBuiltin {
}
}
- private MergeResult mergeModified(String mergedFilePath, boolean showPrompt,
- String toolNamePrompt) throws Exception {
+ private MergeResult mergeModified(String mergedFilePath, boolean showPrompt)
+ throws Exception {
outw.println(MessageFormat.format(CLIText.get().mergeToolNormalConflict,
mergedFilePath));
outw.flush();
- // check if user wants to launch merge resolution tool
- boolean launch = true;
- if (showPrompt) {
- launch = isLaunch(toolNamePrompt);
- }
- if (!launch) {
- return MergeResult.ABORTED; // abort
- }
boolean isMergeSuccessful = true;
ContentSource baseSource = ContentSource.create(db.newObjectReader());
ContentSource localSource = ContentSource.create(db.newObjectReader());
@@ -210,8 +214,8 @@ class MergeTool extends TextBuiltin {
FileElement base = null;
FileElement local = null;
FileElement remote = null;
- FileElement merged = new FileElement(mergedFilePath,
- Type.MERGED);
+ FileElement merged = new FileElement(mergedFilePath, Type.MERGED,
+ db.getWorkTree());
DirCache cache = db.readDirCache();
try (RevWalk revWalk = new RevWalk(db);
TreeWalk treeWalk = new TreeWalk(db,
@@ -233,7 +237,8 @@ class MergeTool extends TextBuiltin {
.get(WorkingTreeOptions.KEY);
CheckoutMetadata checkoutMetadata = new CheckoutMetadata(
eolStreamType, filterCommand);
- DirCacheEntry entry = treeWalk.getTree(DirCacheIterator.class).getDirCacheEntry();
+ DirCacheEntry entry = treeWalk
+ .getTree(DirCacheIterator.class).getDirCacheEntry();
if (entry == null) {
continue;
}
@@ -275,23 +280,27 @@ class MergeTool extends TextBuiltin {
// TODO: check how to return the exit-code of the
// tool to jgit / java runtime ?
// int rc =...
- ExecutionResult executionResult = mergeTools.merge(local,
- remote, merged, base, tempDir, toolName, prompt, gui);
- outw.println(
- new String(executionResult.getStdout().toByteArray()));
- outw.flush();
- errw.println(
- new String(executionResult.getStderr().toByteArray()));
- errw.flush();
+ Optional<ExecutionResult> optionalResult = mergeTools.merge(
+ local, remote, merged, base, tempDir, toolName, prompt,
+ gui, this::promptForLaunch, this::informUserNoTool);
+ if (optionalResult.isPresent()) {
+ ExecutionResult result = optionalResult.get();
+ outw.println(new String(result.getStdout().toByteArray()));
+ outw.flush();
+ errw.println(new String(result.getStderr().toByteArray()));
+ 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()) {
- errw.println(e.getMessage());
throw die(CLIText.get().mergeToolExecutionError, e);
}
}
@@ -380,19 +389,23 @@ class MergeTool extends TextBuiltin {
return hasUserAccepted(CLIText.get().mergeToolWasMergeSuccessfull);
}
- private boolean isLaunch(String toolNamePrompt) throws IOException {
- boolean launch = true;
- outw.print(MessageFormat.format(CLIText.get().mergeToolLaunch,
- toolNamePrompt) + " "); //$NON-NLS-1$
- outw.flush();
- BufferedReader br = inputReader;
- String line = null;
- if ((line = br.readLine()) != null) {
- if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("")) { //$NON-NLS-1$ //$NON-NLS-2$
- launch = false;
+ private boolean promptForLaunch(String toolNamePrompt) {
+ try {
+ boolean launch = true;
+ outw.print(MessageFormat.format(CLIText.get().mergeToolLaunch,
+ toolNamePrompt) + " "); //$NON-NLS-1$
+ outw.flush();
+ BufferedReader br = inputReader;
+ String line = null;
+ if ((line = br.readLine()) != null) {
+ if (!line.equalsIgnoreCase("y") && !line.equalsIgnoreCase("")) { //$NON-NLS-1$ //$NON-NLS-2$
+ launch = false;
+ }
}
+ return launch;
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
}
- return launch;
}
private int getDeletedMergeDecision() throws IOException {
@@ -420,14 +433,16 @@ class MergeTool extends TextBuiltin {
}
private void showToolHelp() throws IOException {
+ Map<String, ExternalMergeTool> predefTools = mergeTools
+ .getPredefinedTools(true);
StringBuilder availableToolNames = new StringBuilder();
- for (String name : mergeTools.getAvailableTools().keySet()) {
- availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
- }
StringBuilder notAvailableToolNames = new StringBuilder();
- for (String name : mergeTools.getNotAvailableTools().keySet()) {
- notAvailableToolNames
- .append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ for (String name : predefTools.keySet()) {
+ if (predefTools.get(name).isAvailable()) {
+ availableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ } else {
+ notAvailableToolNames.append(MessageFormat.format("\t\t{0}\n", name)); //$NON-NLS-1$
+ }
}
StringBuilder userToolNames = new StringBuilder();
Map<String, ExternalMergeTool> userTools = mergeTools
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
index 989e649b72..e06f150e51 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/internal/CLIText.java
@@ -139,6 +139,8 @@ public class CLIText extends TranslationBundle {
/***/ public String diffToolHelpSetToFollowing;
/***/ public String diffToolLaunch;
/***/ public String diffToolDied;
+ /***/ public String diffToolPromptToolName;
+ /***/ public String diffToolUnknownToolName;
/***/ public String doesNotExist;
/***/ public String dontOverwriteLocalChanges;
/***/ public String everythingUpToDate;
@@ -185,6 +187,8 @@ public class CLIText extends TranslationBundle {
/***/ public String mergeToolContinueUnresolvedPaths;
/***/ public String mergeToolWasMergeSuccessfull;
/***/ public String mergeToolDeletedMergeDecision;
+ /***/ public String mergeToolPromptToolName;
+ /***/ public String mergeToolUnknownToolName;
/***/ public String mergeFailed;
/***/ public String mergeCheckoutFailed;
/***/ public String mergeMadeBy;