summaryrefslogtreecommitdiffstats
path: root/org.eclipse.jgit.pgm
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.pgm')
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/DiffTool.java173
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/MergeTool.java137
2 files changed, 155 insertions, 155 deletions
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 e5a3c53e3f..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,6 +23,7 @@ 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;
@@ -40,6 +42,7 @@ 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;
@@ -60,7 +63,6 @@ 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.FS.ExecutionResult;
-import org.eclipse.jgit.util.StringUtils;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option;
@@ -76,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;
@@ -98,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;
@@ -141,16 +147,10 @@ class DiffTool extends TextBuiltin {
if (toolHelp) {
showToolHelp();
} else {
- boolean showPrompt = diffTools.isInteractive();
- if (prompt != BooleanTriState.UNSET) {
- showPrompt = prompt == BooleanTriState.TRUE;
- }
- // get passed or default tool name
- String toolNameToUse = promptToolName();
// get the changed files
List<DiffEntry> files = getFiles();
if (files.size() > 0) {
- compare(files, showPrompt, toolNameToUse);
+ compare(files);
}
}
} catch (RevisionSyntaxException | IOException e) {
@@ -160,79 +160,103 @@ class DiffTool extends TextBuiltin {
}
}
- private String promptToolName() throws IOException {
- String toolNameToUse = toolName;
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- toolNameToUse = diffTools.getDefaultToolName(gui);
- }
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- Map<String, ExternalDiffTool> predefTools = diffTools
- .getPredefinedTools(false);
+ private void informUserNoTool(List<String> tools) {
+ try {
StringBuilder toolNames = new StringBuilder();
- for (String name : predefTools.keySet()) {
+ for (String name : tools) {
toolNames.append(name + " "); //$NON-NLS-1$
}
outw.println(MessageFormat.format(
CLIText.get().diffToolPromptToolName, toolNames));
outw.flush();
- toolNameToUse = diffTools.getFirstAvailableTool();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
}
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- throw new IOException(MessageFormat
- .format(CLIText.get().diffToolUnknownToolName, toolName));
+ }
+
+ 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$
+ }
}
- return toolNameToUse;
}
- private void compare(List<DiffEntry> files, boolean showPrompt,
- String toolNameToUse) throws IOException {
+ 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, toolNameToUse);
+
+ 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, toolNameToUse, 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()));
errw.flush();
- } catch (ToolException e) {
- outw.println(e.getResultStdout());
- outw.flush();
- errw.println(e.getMessage());
- errw.flush();
- throw die(MessageFormat.format(
- CLIText.get().diffToolDied, mergedFilePath, e),
- e);
}
- } 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 {
@@ -240,22 +264,6 @@ 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);
@@ -314,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,
@@ -348,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 f5884c44da..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,30 +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.util.StringUtils;
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;
@@ -62,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;
@@ -81,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")
@@ -116,17 +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 toolNameToUse = promptToolName();
// get the changed files
Map<String, StageState> files = getFiles();
if (files.size() > 0) {
- merge(files, showPrompt, toolNameToUse);
+ merge(files);
} else {
outw.println(CLIText.get().mergeToolNoFiles);
}
@@ -137,32 +135,21 @@ class MergeTool extends TextBuiltin {
}
}
- private String promptToolName() throws IOException {
- String toolNameToUse = toolName;
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- toolNameToUse = mergeTools.getDefaultToolName(gui);
- }
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- Map<String, ExternalMergeTool> predefTools = mergeTools
- .getPredefinedTools(false);
+ private void informUserNoTool(List<String> tools) {
+ try {
StringBuilder toolNames = new StringBuilder();
- for (String name : predefTools.keySet()) {
+ for (String name : tools) {
toolNames.append(name + " "); //$NON-NLS-1$
}
outw.println(MessageFormat
.format(CLIText.get().mergeToolPromptToolName, toolNames));
outw.flush();
- toolNameToUse = mergeTools.getFirstAvailableTool();
+ } catch (IOException e) {
+ throw new IllegalStateException("Cannot output text", e); //$NON-NLS-1$
}
- if (StringUtils.isEmptyOrNull(toolNameToUse)) {
- throw new IOException(MessageFormat
- .format(CLIText.get().mergeToolUnknownToolName, toolName));
- }
- return toolNameToUse;
}
- private void merge(Map<String, StageState> files, boolean showPrompt,
- String toolNamePrompt) throws Exception {
+ private void merge(Map<String, StageState> files) throws Exception {
// sort file names
List<String> mergedFilePaths = new ArrayList<>(files.keySet());
Collections.sort(mergedFilePaths);
@@ -174,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) {
@@ -191,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,
@@ -206,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());
@@ -232,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,
@@ -255,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;
}
@@ -297,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);
}
}
@@ -402,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 {