diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java index 3751c78b365e..4f38dcc7b8e3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/api/BaseSvnClient.java @@ -99,16 +99,31 @@ public abstract class BaseSvnClient implements SvnClient { @NotNull SvnCommandName name, @NotNull List parameters, @Nullable LineCommandListener listener) throws SvnBindException { - Command command = new Command(name); + Command command = newCommand(name); + command.put(parameters); + + return execute(vcs, target, workingDirectory, command, listener); + } + + @NotNull + public CommandExecutor execute(@NotNull SvnVcs vcs, + @NotNull SvnTarget target, + @Nullable File workingDirectory, + @NotNull Command command, + @Nullable LineCommandListener listener) throws SvnBindException { command.setTarget(target); command.setWorkingDirectory(workingDirectory); command.setResultBuilder(listener); - command.put(parameters); return newRuntime(vcs).runWithAuthenticationAttempt(command); } + @NotNull + public Command newCommand(@NotNull SvnCommandName name) { + return new Command(name); + } + @NotNull public CommandRuntime newRuntime(@NotNull SvnVcs vcs) { return new CommandRuntime(vcs, new AuthenticationService(vcs, myIsActive)); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdCheckinClient.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdCheckinClient.java index 6d8aa09cf9e9..50bd222e98c3 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdCheckinClient.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/checkin/CmdCheckinClient.java @@ -29,17 +29,13 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.idea.svn.SvnUtil; import org.jetbrains.idea.svn.api.BaseSvnClient; import org.jetbrains.idea.svn.api.Depth; -import org.jetbrains.idea.svn.commandLine.CommandUtil; -import org.jetbrains.idea.svn.commandLine.LineCommandAdapter; -import org.jetbrains.idea.svn.commandLine.SvnBindException; -import org.jetbrains.idea.svn.commandLine.SvnCommandName; +import org.jetbrains.idea.svn.commandLine.*; import org.jetbrains.idea.svn.status.Status; import org.jetbrains.idea.svn.status.StatusClient; import org.jetbrains.idea.svn.status.StatusType; import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; -import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; @@ -73,19 +69,18 @@ public class CmdCheckinClient extends BaseSvnClient implements CheckinClient { private CommitInfo[] runCommit(@NotNull List paths, @NotNull String message) throws VcsException { if (ContainerUtil.isEmpty(paths)) return new CommitInfo[]{CommitInfo.EMPTY}; - final List parameters = new ArrayList(); + Command command = newCommand(SvnCommandName.ci); - CommandUtil.put(parameters, Depth.EMPTY); - parameters.add("-m"); - parameters.add(message); + command.put(Depth.EMPTY); + command.put("-m", message); // TODO: seems that sort is not necessary here ContainerUtil.sort(paths); - CommandUtil.put(parameters, paths); + command.setTargets(paths); IdeaCommitHandler handler = new IdeaCommitHandler(ProgressManager.getInstance().getProgressIndicator()); CmdCheckinClient.CommandListener listener = new CommandListener(handler); listener.setBaseDirectory(CommandUtil.correctUpToExistingParent(paths.get(0))); - execute(myVcs, SvnTarget.fromFile(paths.get(0)), SvnCommandName.ci, parameters, listener); + execute(myVcs, SvnTarget.fromFile(paths.get(0)), null, command, listener); listener.throwExceptionIfOccurred(); long revision = validateRevisionNumber(listener.getCommittedRevision()); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java index a20e2db48495..9edd8906fa77 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/Command.java @@ -1,10 +1,12 @@ package org.jetbrains.idea.svn.commandLine; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.idea.svn.api.Depth; import org.jetbrains.idea.svn.api.ProgressTracker; import org.tmatesoft.svn.core.SVNURL; import org.tmatesoft.svn.core.wc.SVNRevision; @@ -13,6 +15,7 @@ import org.tmatesoft.svn.core.wc2.SvnTarget; import java.io.File; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.List; /** @@ -30,6 +33,7 @@ public class Command { @Nullable private LineCommandListener myResultBuilder; @Nullable private volatile SVNURL myRepositoryUrl; @NotNull private SvnTarget myTarget; + @Nullable private Collection myTargets; @Nullable private ProgressTracker myCanceller; @@ -37,6 +41,10 @@ public class Command { myName = name; } + public void put(@Nullable Depth depth) { + CommandUtil.put(myParameters, depth, false); + } + public void put(@NonNls @NotNull String... parameters) { put(Arrays.asList(parameters)); } @@ -92,6 +100,16 @@ public class Command { return myTarget; } + @Nullable + public List getTargetsPaths() { + return ContainerUtil.isEmpty(myTargets) ? null : ContainerUtil.map(myTargets, new Function() { + @Override + public String fun(File file) { + return file.getAbsolutePath(); + } + }); + } + @NotNull public SvnCommandName getName() { return myName; @@ -117,6 +135,10 @@ public class Command { myTarget = target; } + public void setTargets(@Nullable Collection targets) { + myTargets = targets; + } + // TODO: used only to ensure authentication info is not logged to file. Remove when command execution model is refactored // TODO: - so we could determine if parameter should be logged by the parameter itself. public void saveOriginalParameters() { @@ -139,6 +161,11 @@ public class Command { data.add(myName.getName()); data.addAll(myOriginalParameters); + List targetsPaths = getTargetsPaths(); + if (!ContainerUtil.isEmpty(targetsPaths)) { + data.addAll(targetsPaths); + } + return StringUtil.join(data, " "); } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java index 469731ed8628..88c896f60c98 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/commandLine/CommandExecutor.java @@ -26,7 +26,9 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.util.EventDispatcher; +import com.intellij.util.SystemProperties; import com.intellij.util.containers.ContainerUtil; +import com.intellij.vcsUtil.VcsFileUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -158,6 +160,7 @@ public class CommandExecutor { EncodingEnvironmentUtil.fixDefaultEncodingIfMac(myCommandLine, null); setupLocale(); ensureMessageFile(); + ensureTargetsAdded(); } private void setupLocale() { @@ -197,6 +200,21 @@ public class CommandExecutor { } } + private void ensureTargetsAdded() throws SvnBindException { + List targetsPaths = myCommand.getTargetsPaths(); + + if (!ContainerUtil.isEmpty(targetsPaths)) { + String targetsValue = StringUtil.join(targetsPaths, SystemProperties.getLineSeparator()); + + if (myCommandLine.getCommandLineString().length() + targetsValue.length() > VcsFileUtil.FILE_PATH_LIMIT) { + ensureCommandFile("command-targets", ".txt", targetsValue, "--targets"); + } + else { + myCommandLine.addParameters(targetsPaths); + } + } + } + private void deleteTempFiles() { for (File file : myTempFiles) { deleteTempFile(file);