Add command line support for "git difftool"
see: http://git-scm.com/docs/git-difftool * add command line support for "jgit difftool" * show supported commands with "jgit difftool --help" * added "git difftool --tool-help" to show the tools (empty now) * prepare for all other commands Bug: 356832 Change-Id: Ice0c13ef7953a20feaf25e7746d62b94ff4e89e5 Signed-off-by: Andre Bossert <andre.bossert@siemens.com> Signed-off-by: Simeon Andreev <simeon.danailov.andreev@gmail.com>
This commit is contained in:
parent
4453a6e042
commit
48f4d97a22
|
@ -15,6 +15,7 @@ Import-Package: org.eclipse.jgit.api;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.file;version="6.1.0",
|
org.eclipse.jgit.internal.storage.file;version="6.1.0",
|
||||||
org.eclipse.jgit.junit;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.junit;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.lib;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.lib;version="[6.1.0,6.2.0)",
|
||||||
|
org.eclipse.jgit.lib.internal;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.merge;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.merge;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.pgm;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.pgm;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.pgm.internal;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.pgm.internal;version="[6.1.0,6.2.0)",
|
||||||
|
|
|
@ -0,0 +1,195 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021, Simeon Andreev <simeon.danailov.andreev@gmail.com> and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
package org.eclipse.jgit.pgm;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.api.Git;
|
||||||
|
import org.eclipse.jgit.diff.DiffEntry;
|
||||||
|
import org.eclipse.jgit.lib.CLIRepositoryTestCase;
|
||||||
|
import org.eclipse.jgit.pgm.opt.CmdLineParser;
|
||||||
|
import org.eclipse.jgit.pgm.opt.SubcommandHandler;
|
||||||
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
|
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||||
|
import org.eclipse.jgit.treewalk.TreeWalk;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.kohsuke.args4j.Argument;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing the {@code difftool} command.
|
||||||
|
*/
|
||||||
|
public class DiffToolTest extends CLIRepositoryTestCase {
|
||||||
|
public static class GitCliJGitWrapperParser {
|
||||||
|
@Argument(index = 0, metaVar = "metaVar_command", required = true, handler = SubcommandHandler.class)
|
||||||
|
TextBuiltin subcommand;
|
||||||
|
|
||||||
|
@Argument(index = 1, metaVar = "metaVar_arg")
|
||||||
|
List<String> arguments = new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] runAndCaptureUsingInitRaw(String... args)
|
||||||
|
throws Exception {
|
||||||
|
CLIGitCommand.Result result = new CLIGitCommand.Result();
|
||||||
|
|
||||||
|
GitCliJGitWrapperParser bean = new GitCliJGitWrapperParser();
|
||||||
|
CmdLineParser clp = new CmdLineParser(bean);
|
||||||
|
clp.parseArgument(args);
|
||||||
|
|
||||||
|
TextBuiltin cmd = bean.subcommand;
|
||||||
|
cmd.initRaw(db, null, null, result.out, result.err);
|
||||||
|
cmd.execute(bean.arguments.toArray(new String[bean.arguments.size()]));
|
||||||
|
if (cmd.getOutputWriter() != null) {
|
||||||
|
cmd.getOutputWriter().flush();
|
||||||
|
}
|
||||||
|
if (cmd.getErrorWriter() != null) {
|
||||||
|
cmd.getErrorWriter().flush();
|
||||||
|
}
|
||||||
|
return result.outLines().toArray(new String[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Git git;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
git = new Git(db);
|
||||||
|
git.commit().setMessage("initial commit").call();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testTool() throws Exception {
|
||||||
|
RevCommit commit = createUnstagedChanges();
|
||||||
|
List<DiffEntry> changes = getRepositoryChanges(commit);
|
||||||
|
String[] expectedOutput = getExpectedDiffToolOutput(changes);
|
||||||
|
|
||||||
|
String[] options = {
|
||||||
|
"--tool",
|
||||||
|
"-t",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (String option : options) {
|
||||||
|
assertArrayOfLinesEquals("Incorrect output for option: " + option,
|
||||||
|
expectedOutput,
|
||||||
|
runAndCaptureUsingInitRaw("difftool", option,
|
||||||
|
"some_tool"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToolTrustExitCode() throws Exception {
|
||||||
|
RevCommit commit = createUnstagedChanges();
|
||||||
|
List<DiffEntry> changes = getRepositoryChanges(commit);
|
||||||
|
String[] expectedOutput = getExpectedDiffToolOutput(changes);
|
||||||
|
|
||||||
|
String[] options = { "--tool", "-t", };
|
||||||
|
|
||||||
|
for (String option : options) {
|
||||||
|
assertArrayOfLinesEquals("Incorrect output for option: " + option,
|
||||||
|
expectedOutput, runAndCaptureUsingInitRaw("difftool",
|
||||||
|
"--trust-exit-code", option, "some_tool"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToolNoGuiNoPromptNoTrustExitcode() throws Exception {
|
||||||
|
RevCommit commit = createUnstagedChanges();
|
||||||
|
List<DiffEntry> changes = getRepositoryChanges(commit);
|
||||||
|
String[] expectedOutput = getExpectedDiffToolOutput(changes);
|
||||||
|
|
||||||
|
String[] options = { "--tool", "-t", };
|
||||||
|
|
||||||
|
for (String option : options) {
|
||||||
|
assertArrayOfLinesEquals("Incorrect output for option: " + option,
|
||||||
|
expectedOutput, runAndCaptureUsingInitRaw("difftool",
|
||||||
|
"--no-gui", "--no-prompt", "--no-trust-exit-code",
|
||||||
|
option, "some_tool"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToolCached() throws Exception {
|
||||||
|
RevCommit commit = createStagedChanges();
|
||||||
|
List<DiffEntry> changes = getRepositoryChanges(commit);
|
||||||
|
String[] expectedOutput = getExpectedDiffToolOutput(changes);
|
||||||
|
|
||||||
|
String[] options = { "--cached", "--staged", };
|
||||||
|
|
||||||
|
for (String option : options) {
|
||||||
|
assertArrayOfLinesEquals("Incorrect output for option: " + option,
|
||||||
|
expectedOutput, runAndCaptureUsingInitRaw("difftool",
|
||||||
|
option, "--tool", "some_tool"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToolHelp() throws Exception {
|
||||||
|
String[] expectedOutput = {
|
||||||
|
"git difftool --tool=<tool> may be set to one of the following:",
|
||||||
|
"user-defined:",
|
||||||
|
"The following tools are valid, but not currently available:",
|
||||||
|
"Some of the tools listed above only work in a windowed",
|
||||||
|
"environment. If run in a terminal-only session, they will fail.", };
|
||||||
|
|
||||||
|
String option = "--tool-help";
|
||||||
|
assertArrayOfLinesEquals("Incorrect output for option: " + option,
|
||||||
|
expectedOutput, runAndCaptureUsingInitRaw("difftool", option));
|
||||||
|
}
|
||||||
|
|
||||||
|
private RevCommit createUnstagedChanges() throws Exception {
|
||||||
|
writeTrashFile("a", "Hello world a");
|
||||||
|
writeTrashFile("b", "Hello world b");
|
||||||
|
git.add().addFilepattern(".").call();
|
||||||
|
RevCommit commit = git.commit().setMessage("files a & b").call();
|
||||||
|
writeTrashFile("a", "New Hello world a");
|
||||||
|
writeTrashFile("b", "New Hello world b");
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private RevCommit createStagedChanges() throws Exception {
|
||||||
|
RevCommit commit = createUnstagedChanges();
|
||||||
|
git.add().addFilepattern(".").call();
|
||||||
|
return commit;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DiffEntry> getRepositoryChanges(RevCommit commit)
|
||||||
|
throws Exception {
|
||||||
|
TreeWalk tw = new TreeWalk(db);
|
||||||
|
tw.addTree(commit.getTree());
|
||||||
|
FileTreeIterator modifiedTree = new FileTreeIterator(db);
|
||||||
|
tw.addTree(modifiedTree);
|
||||||
|
List<DiffEntry> changes = DiffEntry.scan(tw);
|
||||||
|
return changes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] getExpectedDiffToolOutput(List<DiffEntry> changes) {
|
||||||
|
String[] expectedToolOutput = new String[changes.size()];
|
||||||
|
for (int i = 0; i < changes.size(); ++i) {
|
||||||
|
DiffEntry change = changes.get(i);
|
||||||
|
String newPath = change.getNewPath();
|
||||||
|
String oldPath = change.getOldPath();
|
||||||
|
String newIdName = change.getNewId().name();
|
||||||
|
String oldIdName = change.getOldId().name();
|
||||||
|
String expectedLine = "M\t" + newPath + " (" + newIdName + ")"
|
||||||
|
+ "\t" + oldPath + " (" + oldIdName + ")";
|
||||||
|
expectedToolOutput[i] = expectedLine;
|
||||||
|
}
|
||||||
|
return expectedToolOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void assertArrayOfLinesEquals(String failMessage,
|
||||||
|
String[] expected, String[] actual) {
|
||||||
|
assertEquals(failMessage, toString(expected), toString(actual));
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,6 +24,7 @@ Import-Package: javax.servlet;version="[3.1.0,5.0.0)",
|
||||||
org.eclipse.jgit.errors;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.errors;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.gitrepo;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.gitrepo;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.file;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.storage.file;version="[6.1.0,6.2.0)",
|
||||||
|
org.eclipse.jgit.internal.diffmergetool;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.io;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.storage.io;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.pack;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.storage.pack;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.reftable;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.storage.reftable;version="[6.1.0,6.2.0)",
|
||||||
|
@ -33,6 +34,7 @@ Import-Package: javax.servlet;version="[3.1.0,5.0.0)",
|
||||||
org.eclipse.jgit.lfs.server.s3;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.lfs.server.s3;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.lib;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.lib;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.merge;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.merge;version="[6.1.0,6.2.0)",
|
||||||
|
org.eclipse.jgit.lib.internal;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.nls;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.nls;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.notes;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.notes;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.revplot;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.revplot;version="[6.1.0,6.2.0)",
|
||||||
|
|
|
@ -12,6 +12,7 @@ org.eclipse.jgit.pgm.ConvertRefStorage
|
||||||
org.eclipse.jgit.pgm.Daemon
|
org.eclipse.jgit.pgm.Daemon
|
||||||
org.eclipse.jgit.pgm.Describe
|
org.eclipse.jgit.pgm.Describe
|
||||||
org.eclipse.jgit.pgm.Diff
|
org.eclipse.jgit.pgm.Diff
|
||||||
|
org.eclipse.jgit.pgm.DiffTool
|
||||||
org.eclipse.jgit.pgm.DiffTree
|
org.eclipse.jgit.pgm.DiffTree
|
||||||
org.eclipse.jgit.pgm.Fetch
|
org.eclipse.jgit.pgm.Fetch
|
||||||
org.eclipse.jgit.pgm.Gc
|
org.eclipse.jgit.pgm.Gc
|
||||||
|
|
|
@ -58,6 +58,9 @@ couldNotCreateBranch=Could not create branch {0}: {1}
|
||||||
dateInfo=Date: {0}
|
dateInfo=Date: {0}
|
||||||
deletedBranch=Deleted branch {0}
|
deletedBranch=Deleted branch {0}
|
||||||
deletedRemoteBranch=Deleted remote branch {0}
|
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 {0}
|
||||||
doesNotExist={0} does not exist
|
doesNotExist={0} does not exist
|
||||||
dontOverwriteLocalChanges=error: Your local changes to the following file would be overwritten by merge:
|
dontOverwriteLocalChanges=error: Your local changes to the following file would be overwritten by merge:
|
||||||
everythingUpToDate=Everything up-to-date
|
everythingUpToDate=Everything up-to-date
|
||||||
|
@ -145,6 +148,7 @@ metaVar_s3StorageClass=STORAGE-CLASS
|
||||||
metaVar_seconds=SECONDS
|
metaVar_seconds=SECONDS
|
||||||
metaVar_service=SERVICE
|
metaVar_service=SERVICE
|
||||||
metaVar_tagLocalUser=<GPG key ID>
|
metaVar_tagLocalUser=<GPG key ID>
|
||||||
|
metaVar_tool=TOOL
|
||||||
metaVar_treeish=tree-ish
|
metaVar_treeish=tree-ish
|
||||||
metaVar_uriish=uri-ish
|
metaVar_uriish=uri-ish
|
||||||
metaVar_url=URL
|
metaVar_url=URL
|
||||||
|
@ -249,6 +253,8 @@ usage_DiffAlgorithms=Test performance of jgit's diff algorithms
|
||||||
usage_DisplayTheVersionOfJgit=Display the version of jgit
|
usage_DisplayTheVersionOfJgit=Display the version of jgit
|
||||||
usage_Gc=Cleanup unnecessary files and optimize the local repository
|
usage_Gc=Cleanup unnecessary files and optimize the local repository
|
||||||
usage_Glog=View commit history as a graph
|
usage_Glog=View commit history as a graph
|
||||||
|
usage_DiffGuiTool=When git-difftool is invoked with the -g or --gui option the default diff tool will be read from the configured diff.guitool variable instead of diff.tool.
|
||||||
|
usage_noGui=The --no-gui option can be used to override -g or --gui setting.
|
||||||
usage_IndexPack=Build pack index file for an existing packed archive
|
usage_IndexPack=Build pack index file for an existing packed archive
|
||||||
usage_LFSDirectory=Directory to store large objects
|
usage_LFSDirectory=Directory to store large objects
|
||||||
usage_LFSPort=Server http port
|
usage_LFSPort=Server http port
|
||||||
|
@ -295,6 +301,7 @@ usage_ShowRef=List references in a local repository
|
||||||
usage_Status=Show the working tree status
|
usage_Status=Show the working tree status
|
||||||
usage_StopTrackingAFile=Stop tracking a file
|
usage_StopTrackingAFile=Stop tracking a file
|
||||||
usage_TextHashFunctions=Scan repository to compute maximum number of collisions for hash functions
|
usage_TextHashFunctions=Scan repository to compute maximum number of collisions for hash functions
|
||||||
|
usage_ToolForDiff=Use the diff tool specified by <tool>. Run git difftool --tool-help for the list of valid <tool> settings.\nIf a diff tool is not specified, git difftool will use the configuration variable diff.tool.
|
||||||
usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs
|
usage_UpdateRemoteRepositoryFromLocalRefs=Update remote repository from local refs
|
||||||
usage_UseAll=Use all refs found in refs/
|
usage_UseAll=Use all refs found in refs/
|
||||||
usage_UseTags=Use any tag including lightweight tags
|
usage_UseTags=Use any tag including lightweight tags
|
||||||
|
@ -341,6 +348,7 @@ usage_deleteFullyMergedBranch=delete fully merged branch
|
||||||
usage_date=date format, one of default, rfc, local, iso, short, raw (as defined by git-log(1) ), locale or localelocal (jgit extensions)
|
usage_date=date format, one of default, rfc, local, iso, short, raw (as defined by git-log(1) ), locale or localelocal (jgit extensions)
|
||||||
usage_detectRenames=detect renamed files
|
usage_detectRenames=detect renamed files
|
||||||
usage_diffAlgorithm=the diff algorithm to use. Currently supported are: 'myers', 'histogram'
|
usage_diffAlgorithm=the diff algorithm to use. Currently supported are: 'myers', 'histogram'
|
||||||
|
usage_DiffTool=git difftool is a Git command that allows you to compare and edit files between revisions using common diff tools.\ngit difftool is a frontend to git diff and accepts the same options and arguments.
|
||||||
usage_directoriesToExport=directories to export
|
usage_directoriesToExport=directories to export
|
||||||
usage_disableTheServiceInAllRepositories=disable the service in all repositories
|
usage_disableTheServiceInAllRepositories=disable the service in all repositories
|
||||||
usage_displayAListOfAllRegisteredJgitCommands=Display a list of all registered jgit commands
|
usage_displayAListOfAllRegisteredJgitCommands=Display a list of all registered jgit commands
|
||||||
|
@ -395,6 +403,8 @@ usage_pathToXml=path to the repo manifest XML file
|
||||||
usage_performFsckStyleChecksOnReceive=perform fsck style checks on receive
|
usage_performFsckStyleChecksOnReceive=perform fsck style checks on receive
|
||||||
usage_portNumberToListenOn=port number to listen on
|
usage_portNumberToListenOn=port number to listen on
|
||||||
usage_printOnlyBranchesThatContainTheCommit=print only branches that contain the commit
|
usage_printOnlyBranchesThatContainTheCommit=print only branches that contain the commit
|
||||||
|
usage_prompt=Prompt before each invocation of the diff tool. This is the default behaviour; the option is provided to override any configuration settings.
|
||||||
|
usage_noPrompt=Do not prompt before launching a diff tool.
|
||||||
usage_pruneStaleTrackingRefs=prune stale tracking refs
|
usage_pruneStaleTrackingRefs=prune stale tracking refs
|
||||||
usage_pushUrls=push URLs are manipulated
|
usage_pushUrls=push URLs are manipulated
|
||||||
usage_quiet=don't show progress messages
|
usage_quiet=don't show progress messages
|
||||||
|
@ -422,6 +432,8 @@ usage_srcPrefix=show the source prefix instead of "a/"
|
||||||
usage_sshDriver=Selects the built-in ssh library to use, JSch or Apache MINA sshd.
|
usage_sshDriver=Selects the built-in ssh library to use, JSch or Apache MINA sshd.
|
||||||
usage_symbolicVersionForTheProject=Symbolic version for the project
|
usage_symbolicVersionForTheProject=Symbolic version for the project
|
||||||
usage_tags=fetch all tags
|
usage_tags=fetch all tags
|
||||||
|
usage_trustExitCode=git-difftool invokes a diff tool individually on each file. Errors reported by the diff tool are ignored by default. Use --trust-exit-code to make git-difftool exit when an invoked diff tool returns a non-zero exit code.\ngit-difftool will forward the exit code of the invoked tool when --trust-exit-code is used.
|
||||||
|
usage_noTrustExitCode=This option can be used to override --trust-exit-code setting.
|
||||||
usage_notags=do not fetch tags
|
usage_notags=do not fetch tags
|
||||||
usage_tagAnnotated=create an annotated tag, unsigned unless -s or -u are given, or config tag.gpgSign is true
|
usage_tagAnnotated=create an annotated tag, unsigned unless -s or -u are given, or config tag.gpgSign is true
|
||||||
usage_tagDelete=delete tag
|
usage_tagDelete=delete tag
|
||||||
|
@ -430,6 +442,7 @@ usage_tagMessage=create an annotated tag with the given message, unsigned unless
|
||||||
usage_tagSign=create a signed annotated tag
|
usage_tagSign=create a signed annotated tag
|
||||||
usage_tagNoSign=suppress signing the tag
|
usage_tagNoSign=suppress signing the tag
|
||||||
usage_tagVerify=Verify the GPG signature
|
usage_tagVerify=Verify the GPG signature
|
||||||
|
usage_toolHelp=Print a list of diff tools that may be used with --tool.
|
||||||
usage_untrackedFilesMode=show untracked files
|
usage_untrackedFilesMode=show untracked files
|
||||||
usage_updateRef=reference to update
|
usage_updateRef=reference to update
|
||||||
usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository
|
usage_updateRemoteRefsFromAnotherRepository=Update remote refs from another repository
|
||||||
|
|
|
@ -0,0 +1,255 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021, Andre Bossert <andre.bossert@siemens.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
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.jgit.pgm;
|
||||||
|
|
||||||
|
import static org.eclipse.jgit.lib.Constants.HEAD;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.text.MessageFormat;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.diff.DiffEntry;
|
||||||
|
import org.eclipse.jgit.diff.DiffFormatter;
|
||||||
|
import org.eclipse.jgit.dircache.DirCacheIterator;
|
||||||
|
import org.eclipse.jgit.errors.AmbiguousObjectException;
|
||||||
|
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
|
||||||
|
import org.eclipse.jgit.errors.RevisionSyntaxException;
|
||||||
|
import org.eclipse.jgit.internal.diffmergetool.DiffTools;
|
||||||
|
import org.eclipse.jgit.internal.diffmergetool.ExternalDiffTool;
|
||||||
|
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.internal.BooleanTriState;
|
||||||
|
import org.eclipse.jgit.pgm.internal.CLIText;
|
||||||
|
import org.eclipse.jgit.pgm.opt.PathTreeFilterHandler;
|
||||||
|
import org.eclipse.jgit.treewalk.AbstractTreeIterator;
|
||||||
|
import org.eclipse.jgit.treewalk.CanonicalTreeParser;
|
||||||
|
import org.eclipse.jgit.treewalk.FileTreeIterator;
|
||||||
|
import org.eclipse.jgit.treewalk.filter.TreeFilter;
|
||||||
|
import org.eclipse.jgit.util.StringUtils;
|
||||||
|
import org.kohsuke.args4j.Argument;
|
||||||
|
import org.kohsuke.args4j.Option;
|
||||||
|
|
||||||
|
@Command(name = "difftool", common = true, usage = "usage_DiffTool")
|
||||||
|
class DiffTool extends TextBuiltin {
|
||||||
|
private DiffFormatter diffFmt;
|
||||||
|
|
||||||
|
private DiffTools diffTools;
|
||||||
|
|
||||||
|
@Argument(index = 0, metaVar = "metaVar_treeish")
|
||||||
|
private AbstractTreeIterator oldTree;
|
||||||
|
|
||||||
|
@Argument(index = 1, metaVar = "metaVar_treeish")
|
||||||
|
private AbstractTreeIterator newTree;
|
||||||
|
|
||||||
|
@Option(name = "--tool", aliases = {
|
||||||
|
"-t" }, metaVar = "metaVar_tool", usage = "usage_ToolForDiff")
|
||||||
|
private String toolName;
|
||||||
|
|
||||||
|
@Option(name = "--cached", aliases = { "--staged" }, usage = "usage_cached")
|
||||||
|
private boolean cached;
|
||||||
|
|
||||||
|
private BooleanTriState prompt = BooleanTriState.UNSET;
|
||||||
|
|
||||||
|
@Option(name = "--prompt", usage = "usage_prompt")
|
||||||
|
void setPrompt(@SuppressWarnings("unused") boolean on) {
|
||||||
|
prompt = BooleanTriState.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(name = "--no-prompt", aliases = { "-y" }, usage = "usage_noPrompt")
|
||||||
|
void noPrompt(@SuppressWarnings("unused") boolean on) {
|
||||||
|
prompt = BooleanTriState.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(name = "--tool-help", usage = "usage_toolHelp")
|
||||||
|
private boolean toolHelp;
|
||||||
|
|
||||||
|
private BooleanTriState gui = BooleanTriState.UNSET;
|
||||||
|
|
||||||
|
@Option(name = "--gui", aliases = { "-g" }, usage = "usage_DiffGuiTool")
|
||||||
|
void setGui(@SuppressWarnings("unused") boolean on) {
|
||||||
|
gui = BooleanTriState.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(name = "--no-gui", usage = "usage_noGui")
|
||||||
|
void noGui(@SuppressWarnings("unused") boolean on) {
|
||||||
|
gui = BooleanTriState.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BooleanTriState trustExitCode = BooleanTriState.UNSET;
|
||||||
|
|
||||||
|
@Option(name = "--trust-exit-code", usage = "usage_trustExitCode")
|
||||||
|
void setTrustExitCode(@SuppressWarnings("unused") boolean on) {
|
||||||
|
trustExitCode = BooleanTriState.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(name = "--no-trust-exit-code", usage = "usage_noTrustExitCode")
|
||||||
|
void noTrustExitCode(@SuppressWarnings("unused") boolean on) {
|
||||||
|
trustExitCode = BooleanTriState.FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Option(name = "--", metaVar = "metaVar_paths", handler = PathTreeFilterHandler.class)
|
||||||
|
private TreeFilter pathFilter = TreeFilter.ALL;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void init(Repository repository, String gitDir) {
|
||||||
|
super.init(repository, gitDir);
|
||||||
|
diffFmt = new DiffFormatter(new BufferedOutputStream(outs));
|
||||||
|
diffTools = new DiffTools(repository);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void run() {
|
||||||
|
try {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outw.flush();
|
||||||
|
} catch (RevisionSyntaxException | IOException e) {
|
||||||
|
throw die(e.getMessage(), e);
|
||||||
|
} finally {
|
||||||
|
diffFmt.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compare(List<DiffEntry> files, boolean showPrompt,
|
||||||
|
String toolNamePrompt) throws IOException {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
if (launchCompare) {
|
||||||
|
switch (ent.getChangeType()) {
|
||||||
|
case MODIFY:
|
||||||
|
outw.println("M\t" + ent.getNewPath() //$NON-NLS-1$
|
||||||
|
+ " (" + ent.getNewId().name() + ")" //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
+ "\t" + ent.getOldPath() //$NON-NLS-1$
|
||||||
|
+ " (" + ent.getOldId().name() + ")"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
|
int ret = diffTools.compare(ent.getNewPath(),
|
||||||
|
ent.getOldPath(), ent.getNewId().name(),
|
||||||
|
ent.getOldId().name(), toolName, prompt, gui,
|
||||||
|
trustExitCode);
|
||||||
|
if (ret != 0) {
|
||||||
|
throw die(MessageFormat.format(
|
||||||
|
CLIText.get().diffToolDied, mergedFilePath));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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));
|
||||||
|
outw.flush();
|
||||||
|
BufferedReader br = new BufferedReader(new InputStreamReader(ins));
|
||||||
|
String line = null;
|
||||||
|
if ((line = br.readLine()) != null) {
|
||||||
|
if (!line.equalsIgnoreCase("Y")) { //$NON-NLS-1$
|
||||||
|
launchCompare = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return launchCompare;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showToolHelp() throws IOException {
|
||||||
|
String availableToolNames = new String();
|
||||||
|
for (String name : diffTools.getAvailableTools().keySet()) {
|
||||||
|
availableToolNames += String.format("\t\t{0}\n", name); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
String notAvailableToolNames = new String();
|
||||||
|
for (String name : diffTools.getNotAvailableTools().keySet()) {
|
||||||
|
notAvailableToolNames += String.format("\t\t{0}\n", name); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
String userToolNames = new String();
|
||||||
|
Map<String, ExternalDiffTool> userTools = diffTools
|
||||||
|
.getUserDefinedTools();
|
||||||
|
for (String name : userTools.keySet()) {
|
||||||
|
availableToolNames += String.format("\t\t{0}.cmd {1}\n", //$NON-NLS-1$
|
||||||
|
name, userTools.get(name).getCommand());
|
||||||
|
}
|
||||||
|
outw.println(MessageFormat.format(
|
||||||
|
CLIText.get().diffToolHelpSetToFollowing, availableToolNames,
|
||||||
|
userToolNames, notAvailableToolNames));
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<DiffEntry> getFiles()
|
||||||
|
throws RevisionSyntaxException, AmbiguousObjectException,
|
||||||
|
IncorrectObjectTypeException, IOException {
|
||||||
|
diffFmt.setRepository(db);
|
||||||
|
if (cached) {
|
||||||
|
if (oldTree == null) {
|
||||||
|
ObjectId head = db.resolve(HEAD + "^{tree}"); //$NON-NLS-1$
|
||||||
|
if (head == null) {
|
||||||
|
die(MessageFormat.format(CLIText.get().notATree, HEAD));
|
||||||
|
}
|
||||||
|
CanonicalTreeParser p = new CanonicalTreeParser();
|
||||||
|
try (ObjectReader reader = db.newObjectReader()) {
|
||||||
|
p.reset(reader, head);
|
||||||
|
}
|
||||||
|
oldTree = p;
|
||||||
|
}
|
||||||
|
newTree = new DirCacheIterator(db.readDirCache());
|
||||||
|
} else if (oldTree == null) {
|
||||||
|
oldTree = new DirCacheIterator(db.readDirCache());
|
||||||
|
newTree = new FileTreeIterator(db);
|
||||||
|
} else if (newTree == null) {
|
||||||
|
newTree = new FileTreeIterator(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
TextProgressMonitor pm = new TextProgressMonitor(errw);
|
||||||
|
pm.setDelayStart(2, TimeUnit.SECONDS);
|
||||||
|
diffFmt.setProgressMonitor(pm);
|
||||||
|
diffFmt.setPathFilter(pathFilter);
|
||||||
|
|
||||||
|
List<DiffEntry> files = diffFmt.scan(oldTree, newTree);
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -136,6 +136,9 @@ public static String fatalError(String message) {
|
||||||
/***/ public String dateInfo;
|
/***/ public String dateInfo;
|
||||||
/***/ public String deletedBranch;
|
/***/ public String deletedBranch;
|
||||||
/***/ public String deletedRemoteBranch;
|
/***/ public String deletedRemoteBranch;
|
||||||
|
/***/ public String diffToolHelpSetToFollowing;
|
||||||
|
/***/ public String diffToolLaunch;
|
||||||
|
/***/ public String diffToolDied;
|
||||||
/***/ public String doesNotExist;
|
/***/ public String doesNotExist;
|
||||||
/***/ public String dontOverwriteLocalChanges;
|
/***/ public String dontOverwriteLocalChanges;
|
||||||
/***/ public String everythingUpToDate;
|
/***/ public String everythingUpToDate;
|
||||||
|
|
|
@ -33,6 +33,7 @@ Import-Package: com.googlecode.javaewah;version="[1.1.6,2.0.0)",
|
||||||
org.eclipse.jgit.ignore;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.ignore;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.ignore.internal;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.ignore.internal;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal;version="[6.1.0,6.2.0)",
|
||||||
|
org.eclipse.jgit.internal.diffmergetool;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.fsck;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.fsck;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.revwalk;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.revwalk;version="[6.1.0,6.2.0)",
|
||||||
org.eclipse.jgit.internal.storage.dfs;version="[6.1.0,6.2.0)",
|
org.eclipse.jgit.internal.storage.dfs;version="[6.1.0,6.2.0)",
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2021, Simeon Andreev <simeon.danailov.andreev@gmail.com> and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
package org.eclipse.jgit.internal.diffmergetool;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.internal.BooleanTriState;
|
||||||
|
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Testing external diff tools.
|
||||||
|
*/
|
||||||
|
public class ExternalDiffToolTest extends ExternalToolTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testToolNames() {
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
Set<String> actualToolNames = manager.getToolNames();
|
||||||
|
Set<String> expectedToolNames = Collections.emptySet();
|
||||||
|
assertEquals("Incorrect set of external diff tool names",
|
||||||
|
expectedToolNames,
|
||||||
|
actualToolNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAllTools() {
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
Set<String> actualToolNames = manager.getAvailableTools().keySet();
|
||||||
|
Set<String> expectedToolNames = Collections.emptySet();
|
||||||
|
assertEquals("Incorrect set of available external diff tools",
|
||||||
|
expectedToolNames,
|
||||||
|
actualToolNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUserDefinedTools() {
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
Set<String> actualToolNames = manager.getUserDefinedTools().keySet();
|
||||||
|
Set<String> expectedToolNames = Collections.emptySet();
|
||||||
|
assertEquals("Incorrect set of user defined external diff tools",
|
||||||
|
expectedToolNames,
|
||||||
|
actualToolNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotAvailableTools() {
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
Set<String> actualToolNames = manager.getNotAvailableTools().keySet();
|
||||||
|
Set<String> expectedToolNames = Collections.emptySet();
|
||||||
|
assertEquals("Incorrect set of not available external diff tools",
|
||||||
|
expectedToolNames,
|
||||||
|
actualToolNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCompare() {
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
|
||||||
|
String newPath = "";
|
||||||
|
String oldPath = "";
|
||||||
|
String newId = "";
|
||||||
|
String oldId = "";
|
||||||
|
String toolName = "";
|
||||||
|
BooleanTriState prompt = BooleanTriState.UNSET;
|
||||||
|
BooleanTriState gui = BooleanTriState.UNSET;
|
||||||
|
BooleanTriState trustExitCode = BooleanTriState.UNSET;
|
||||||
|
|
||||||
|
int expectedCompareResult = 0;
|
||||||
|
int compareResult = manager.compare(newPath, oldPath, newId, oldId,
|
||||||
|
toolName, prompt, gui, trustExitCode);
|
||||||
|
assertEquals("Incorrect compare result for external diff tool",
|
||||||
|
expectedCompareResult,
|
||||||
|
compareResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDefaultTool() throws Exception {
|
||||||
|
FileBasedConfig config = db.getConfig();
|
||||||
|
// the default diff tool is configured without a subsection
|
||||||
|
String subsection = null;
|
||||||
|
config.setString("diff", subsection, "tool", "customTool");
|
||||||
|
|
||||||
|
DiffTools manager = new DiffTools(db);
|
||||||
|
BooleanTriState gui = BooleanTriState.UNSET;
|
||||||
|
String defaultToolName = manager.getDefaultToolName(gui);
|
||||||
|
assertEquals(
|
||||||
|
"Expected configured difftool to be the default external diff tool",
|
||||||
|
"my_default_toolname", defaultToolName);
|
||||||
|
|
||||||
|
gui = BooleanTriState.TRUE;
|
||||||
|
String defaultGuiToolName = manager.getDefaultToolName(gui);
|
||||||
|
assertEquals(
|
||||||
|
"Expected configured difftool to be the default external diff tool",
|
||||||
|
"my_gui_tool", defaultGuiToolName);
|
||||||
|
|
||||||
|
config.setString("diff", subsection, "guitool", "customGuiTool");
|
||||||
|
manager = new DiffTools(db);
|
||||||
|
defaultGuiToolName = manager.getDefaultToolName(gui);
|
||||||
|
assertEquals(
|
||||||
|
"Expected configured difftool to be the default external diff guitool",
|
||||||
|
"my_gui_tool", defaultGuiToolName);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020-2021, Simeon Andreev <simeon.danailov.andreev@gmail.com> and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
package org.eclipse.jgit.internal.diffmergetool;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.junit.RepositoryTestCase;
|
||||||
|
import org.eclipse.jgit.util.FS;
|
||||||
|
import org.eclipse.jgit.util.FS_POSIX;
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Assume;
|
||||||
|
import org.junit.Before;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base test case for external merge and diff tool tests.
|
||||||
|
*/
|
||||||
|
public abstract class ExternalToolTest extends RepositoryTestCase {
|
||||||
|
|
||||||
|
protected static final String DEFAULT_CONTENT = "line1";
|
||||||
|
|
||||||
|
protected File localFile;
|
||||||
|
|
||||||
|
protected File remoteFile;
|
||||||
|
|
||||||
|
protected File mergedFile;
|
||||||
|
|
||||||
|
protected File baseFile;
|
||||||
|
|
||||||
|
protected File commandResult;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
|
||||||
|
localFile = writeTrashFile("localFile.txt", DEFAULT_CONTENT + "\n");
|
||||||
|
localFile.deleteOnExit();
|
||||||
|
remoteFile = writeTrashFile("remoteFile.txt", DEFAULT_CONTENT + "\n");
|
||||||
|
remoteFile.deleteOnExit();
|
||||||
|
mergedFile = writeTrashFile("mergedFile.txt", "");
|
||||||
|
mergedFile.deleteOnExit();
|
||||||
|
baseFile = writeTrashFile("baseFile.txt", "");
|
||||||
|
baseFile.deleteOnExit();
|
||||||
|
commandResult = writeTrashFile("commandResult.txt", "");
|
||||||
|
commandResult.deleteOnExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
Files.delete(localFile.toPath());
|
||||||
|
Files.delete(remoteFile.toPath());
|
||||||
|
Files.delete(mergedFile.toPath());
|
||||||
|
Files.delete(baseFile.toPath());
|
||||||
|
Files.delete(commandResult.toPath());
|
||||||
|
|
||||||
|
super.tearDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected static void assumePosixPlatform() {
|
||||||
|
Assume.assumeTrue(
|
||||||
|
"This test can run only in Linux tests",
|
||||||
|
FS.DETECTED instanceof FS_POSIX);
|
||||||
|
}
|
||||||
|
}
|
|
@ -70,7 +70,10 @@ Export-Package: org.eclipse.jgit.annotations;version="6.1.0",
|
||||||
org.eclipse.jgit.internal;version="6.1.0";
|
org.eclipse.jgit.internal;version="6.1.0";
|
||||||
x-friends:="org.eclipse.jgit.test,
|
x-friends:="org.eclipse.jgit.test,
|
||||||
org.eclipse.jgit.http.test",
|
org.eclipse.jgit.http.test",
|
||||||
|
org.eclipse.jgit.internal.diffmergetool;version="6.1.0";
|
||||||
org.eclipse.jgit.internal.fsck;version="6.1.0";
|
org.eclipse.jgit.internal.fsck;version="6.1.0";
|
||||||
|
x-friends:="org.eclipse.jgit.test,
|
||||||
|
org.eclipse.jgit.pgm",
|
||||||
x-friends:="org.eclipse.jgit.test",
|
x-friends:="org.eclipse.jgit.test",
|
||||||
org.eclipse.jgit.internal.revwalk;version="6.1.0";
|
org.eclipse.jgit.internal.revwalk;version="6.1.0";
|
||||||
x-friends:="org.eclipse.jgit.test",
|
x-friends:="org.eclipse.jgit.test",
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021, Andre Bossert <andre.bossert@siemens.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
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.jgit.internal.diffmergetool;
|
||||||
|
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.eclipse.jgit.lib.Repository;
|
||||||
|
import org.eclipse.jgit.lib.internal.BooleanTriState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manages diff tools.
|
||||||
|
*/
|
||||||
|
public class DiffTools {
|
||||||
|
|
||||||
|
private Map<String, ExternalDiffTool> predefinedTools;
|
||||||
|
|
||||||
|
private Map<String, ExternalDiffTool> userDefinedTools;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the external diff-tools manager for given repository.
|
||||||
|
*
|
||||||
|
* @param repo
|
||||||
|
* the repository database
|
||||||
|
*/
|
||||||
|
public DiffTools(Repository repo) {
|
||||||
|
setupPredefinedTools();
|
||||||
|
setupUserDefinedTools();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compare two versions of a file.
|
||||||
|
*
|
||||||
|
* @param newPath
|
||||||
|
* the new file path
|
||||||
|
* @param oldPath
|
||||||
|
* the old file path
|
||||||
|
* @param newId
|
||||||
|
* the new object ID
|
||||||
|
* @param oldId
|
||||||
|
* the old object ID
|
||||||
|
* @param toolName
|
||||||
|
* the selected tool name (can be null)
|
||||||
|
* @param prompt
|
||||||
|
* the prompt option
|
||||||
|
* @param gui
|
||||||
|
* the GUI option
|
||||||
|
* @param trustExitCode
|
||||||
|
* the "trust exit code" option
|
||||||
|
* @return the return code from executed tool
|
||||||
|
*/
|
||||||
|
public int compare(String newPath, String oldPath, String newId,
|
||||||
|
String oldId, String toolName, BooleanTriState prompt,
|
||||||
|
BooleanTriState gui, BooleanTriState trustExitCode) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tool names
|
||||||
|
*/
|
||||||
|
public Set<String> getToolNames() {
|
||||||
|
return Collections.emptySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the user defined tools
|
||||||
|
*/
|
||||||
|
public Map<String, ExternalDiffTool> getUserDefinedTools() {
|
||||||
|
return Collections.unmodifiableMap(userDefinedTools);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the available predefined tools
|
||||||
|
*/
|
||||||
|
public Map<String, ExternalDiffTool> getAvailableTools() {
|
||||||
|
return Collections.unmodifiableMap(predefinedTools);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the NOT available predefined tools
|
||||||
|
*/
|
||||||
|
public Map<String, ExternalDiffTool> getNotAvailableTools() {
|
||||||
|
return Collections.unmodifiableMap(new TreeMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param gui
|
||||||
|
* use the diff.guitool setting ?
|
||||||
|
* @return the default tool name
|
||||||
|
*/
|
||||||
|
public String getDefaultToolName(BooleanTriState gui) {
|
||||||
|
return gui != BooleanTriState.UNSET ? "my_gui_tool" //$NON-NLS-1$
|
||||||
|
: "my_default_toolname"; //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return is interactive (config prompt enabled) ?
|
||||||
|
*/
|
||||||
|
public boolean isInteractive() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupPredefinedTools() {
|
||||||
|
predefinedTools = new TreeMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupUserDefinedTools() {
|
||||||
|
userDefinedTools = new TreeMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2018-2021, Andre Bossert <andre.bossert@siemens.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
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.eclipse.jgit.internal.diffmergetool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The external tool interface.
|
||||||
|
*/
|
||||||
|
public interface ExternalDiffTool {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tool name
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tool path
|
||||||
|
*/
|
||||||
|
String getPath();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the tool command
|
||||||
|
*/
|
||||||
|
String getCommand();
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2021 Simeon Andreev <simeon.danailov.andreev@gmail.com> and others
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials are made available under the
|
||||||
|
* terms of the Eclipse Distribution License v. 1.0 which is available at
|
||||||
|
* https://www.eclipse.org/org/documents/edl-v10.php.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
package org.eclipse.jgit.lib.internal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean value that can also have an unset state.
|
||||||
|
*/
|
||||||
|
public enum BooleanTriState {
|
||||||
|
/**
|
||||||
|
* Value equivalent to {@code true}.
|
||||||
|
*/
|
||||||
|
TRUE,
|
||||||
|
/**
|
||||||
|
* Value equivalent to {@code false}.
|
||||||
|
*/
|
||||||
|
FALSE,
|
||||||
|
/**
|
||||||
|
* Value is not set.
|
||||||
|
*/
|
||||||
|
UNSET;
|
||||||
|
}
|
Loading…
Reference in New Issue