diff options
author | Andrey Loskutov <loskutov@gmx.de> | 2022-06-03 15:49:45 +0200 |
---|---|---|
committer | Andrey Loskutov <loskutov@gmx.de> | 2022-06-03 15:51:54 +0200 |
commit | 2ef2a3562e9aa5c826ce063a2f1d3d8ffef1f0ce (patch) | |
tree | b0f2988a40474499808220cd7d5fe677d87b6600 /org.eclipse.jgit.pgm | |
parent | 7b1ade51d24f6efacfddd91fcfed7137c27642d3 (diff) | |
parent | c32694e5ae98e5c1373afcb535a76d37e5d82a29 (diff) | |
download | jgit-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')
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; |