From f2e57150d84beb469be11e6da7a6011c3bafda96 Mon Sep 17 00:00:00 2001 From: Nadya Zabrodina Date: Mon, 6 Jun 2016 21:14:05 +0300 Subject: [PATCH] [patch]: provide base path to patch writer to be able construct additional info properly * PatchEP use project based path to provide additional info, so we need to provide base patch path also to patch writer; * fix create patch from local history: do not ignore encoding field; * reuse PatchWriter in PatchCreator; * remove innecessary methods; * annotations added; * NOTE: there are still several problems with additional info creation and migrations from patch to shelf and vise versa, especially with renamed files --- .../integration/patches/PatchCreator.java | 24 ++++----------- .../ui/models/HistoryDialogModel.java | 6 ++-- .../integration/ui/views/HistoryDialog.java | 2 +- ...rectoryHistoryDialogPatchCreationTest.java | 4 ++- .../diff/impl/patch/UnifiedDiffWriter.java | 30 ++++++++++++++++--- .../patch/CreatePatchCommitExecutor.java | 5 ++-- .../vcs/changes/patch/PatchWriter.java | 14 ++++----- .../ApplyPatchSaveToFileExecutor.java | 3 +- 8 files changed, 51 insertions(+), 37 deletions(-) diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/patches/PatchCreator.java b/platform/lvcs-impl/src/com/intellij/history/integration/patches/PatchCreator.java index 02ff8fc1b7ae..a99b8882ccc7 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/patches/PatchCreator.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/patches/PatchCreator.java @@ -18,25 +18,22 @@ package com.intellij.history.integration.patches; import com.intellij.openapi.diff.impl.patch.FilePatch; import com.intellij.openapi.diff.impl.patch.IdeaTextPatchBuilder; -import com.intellij.openapi.diff.impl.patch.UnifiedDiffWriter; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vcs.changes.CommitContext; -import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.openapi.vcs.changes.patch.PatchWriter; import com.intellij.util.ObjectUtils; import org.jetbrains.annotations.NotNull; -import java.io.FileOutputStream; import java.io.IOException; -import java.io.OutputStreamWriter; -import java.io.Writer; +import java.nio.charset.Charset; import java.util.List; public class PatchCreator { public static void create(Project p, List changes, String filePath, boolean isReverse, CommitContext commitContext) throws IOException, VcsException { - create(p, ObjectUtils.assertNotNull(p.getBasePath()), changes, filePath, isReverse, commitContext); + create(p, ObjectUtils.assertNotNull(p.getBasePath()), changes, filePath, isReverse, commitContext, Charset.defaultCharset()); } public static void create(Project p, @@ -44,20 +41,9 @@ public class PatchCreator { List changes, String filePath, boolean isReverse, - CommitContext commitContext) + CommitContext commitContext, Charset charset) throws IOException, VcsException { List patches = IdeaTextPatchBuilder.buildPatch(p, changes, basePath, isReverse); - writeFilePatches(p, filePath, patches, commitContext); - } - - public static void writeFilePatches(Project p, String filePath, List patches, CommitContext commitContext) throws IOException { - Writer writer = new OutputStreamWriter(new FileOutputStream(filePath)); - try { - String lineSeparator = CodeStyleSettingsManager.getInstance(p).getCurrentSettings().getLineSeparator(); - UnifiedDiffWriter.write(p, patches, writer, lineSeparator, commitContext); - } - finally { - writer.close(); - } + PatchWriter.writePatches(p, filePath, basePath, patches, commitContext, charset); } } diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/HistoryDialogModel.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/HistoryDialogModel.java index 1e42e8fb8ef8..d9883e0a156f 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/HistoryDialogModel.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/models/HistoryDialogModel.java @@ -35,9 +35,11 @@ import com.intellij.openapi.vcs.VcsException; import com.intellij.openapi.vcs.changes.Change; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.IOException; +import java.nio.charset.Charset; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -191,8 +193,8 @@ public abstract class HistoryDialogModel { return new Change(d.getLeftContentRevision(myGateway), d.getRightContentRevision(myGateway)); } - public void createPatch(String path, String basePath, boolean isReverse) throws VcsException, IOException { - PatchCreator.create(myProject, basePath, getChanges(), path, isReverse, null); + public void createPatch(String path, String basePath, boolean isReverse, @NotNull Charset charset) throws VcsException, IOException { + PatchCreator.create(myProject, basePath, getChanges(), path, isReverse, null, charset); } public abstract Reverter createReverter(); diff --git a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java index 9d0c73c8d2ea..bd5b82b94570 100644 --- a/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java +++ b/platform/lvcs-impl/src/com/intellij/history/integration/ui/views/HistoryDialog.java @@ -458,7 +458,7 @@ public abstract class HistoryDialog extends FrameW p.setFileName(getDefaultPatchFile()); p.setCommonParentPath(ChangesUtil.findCommonAncestor(myModel.getChanges())); if (!showAsDialog(p)) return; - myModel.createPatch(p.getFileName(), p.getBaseDirName(), p.isReversePatch()); + myModel.createPatch(p.getFileName(), p.getBaseDirName(), p.isReversePatch(), p.getEncoding()); showNotification(LocalHistoryBundle.message("message.patch.created")); ShowFilePathAction.openFile(new File(p.getFileName())); diff --git a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/DirectoryHistoryDialogPatchCreationTest.java b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/DirectoryHistoryDialogPatchCreationTest.java index 1a0260607482..5cacba564cc4 100644 --- a/platform/platform-tests/testSrc/com/intellij/history/integration/ui/DirectoryHistoryDialogPatchCreationTest.java +++ b/platform/platform-tests/testSrc/com/intellij/history/integration/ui/DirectoryHistoryDialogPatchCreationTest.java @@ -19,6 +19,8 @@ package com.intellij.history.integration.ui; import com.intellij.history.integration.PatchingTestCase; import com.intellij.history.integration.ui.models.DirectoryHistoryDialogModel; +import java.nio.charset.Charset; + public class DirectoryHistoryDialogPatchCreationTest extends PatchingTestCase { public void testPatchCreation() throws Exception { createChildData(myRoot, "f1.txt"); @@ -29,7 +31,7 @@ public class DirectoryHistoryDialogPatchCreationTest extends PatchingTestCase { assertSize(3, m.getRevisions()); m.selectRevisions(0, 2); - m.createPatch(patchFilePath, myProject.getBasePath(), false); + m.createPatch(patchFilePath, myProject.getBasePath(), false, Charset.defaultCharset()); clearRoot(); applyPatch(); diff --git a/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/diff/impl/patch/UnifiedDiffWriter.java b/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/diff/impl/patch/UnifiedDiffWriter.java index 59910be0b100..f09c0d0c9b2f 100644 --- a/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/diff/impl/patch/UnifiedDiffWriter.java +++ b/platform/vcs-api/vcs-api-core/src/com/intellij/openapi/diff/impl/patch/UnifiedDiffWriter.java @@ -24,12 +24,16 @@ package com.intellij.openapi.diff.impl.patch; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vcs.changes.CommitContext; +import com.intellij.util.ObjectUtils; import com.intellij.util.containers.HashMap; import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.io.File; import java.io.IOException; import java.io.Writer; import java.text.MessageFormat; @@ -56,13 +60,23 @@ public class UnifiedDiffWriter { public static void write(Project project, Collection patches, Writer writer, final String lineSeparator, final PatchEP[] extensions, final CommitContext commitContext) throws IOException { + write(project, project == null ? null : project.getBasePath(), patches, writer, lineSeparator, extensions, commitContext); + } + + public static void write(Project project, + @Nullable String basePath, + Collection patches, + Writer writer, + final String lineSeparator, + @NotNull final PatchEP[] extensions, + final CommitContext commitContext) throws IOException { for(FilePatch filePatch: patches) { if (!(filePatch instanceof TextFilePatch)) continue; - TextFilePatch patch = (TextFilePatch) filePatch; - final String path = patch.getBeforeName() == null ? patch.getAfterName() : patch.getBeforeName(); - final Map additionalMap = new HashMap(); + TextFilePatch patch = (TextFilePatch)filePatch; + String pathRelatedToProjectDir = getPathRelatedToDir(ObjectUtils.assertNotNull(project.getBasePath()), basePath, patch); + final Map additionalMap = new HashMap(); for (PatchEP extension : extensions) { - final CharSequence charSequence = extension.provideContent(path, commitContext); + final CharSequence charSequence = extension.provideContent(pathRelatedToProjectDir, commitContext); if (! StringUtil.isEmpty(charSequence)) { additionalMap.put(extension.getName(), charSequence); } @@ -98,6 +112,14 @@ public class UnifiedDiffWriter { } } + @NotNull + private static String getPathRelatedToDir(@NotNull String newBaseDir, @Nullable String basePath, @NotNull TextFilePatch patch) { + final String path = ObjectUtils.assertNotNull(patch.getBeforeName() == null ? patch.getAfterName() : patch.getBeforeName()); + if (basePath == null) return path; + String result = FileUtil.getRelativePath(new File(newBaseDir), new File(basePath, path)); + return result == null ? path : result; + } + private static void writeFileHeading(final FilePatch patch, final Writer writer, final String lineSeparator, diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java index 6e8af3f4b0e8..69c142b361cc 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/CreatePatchCommitExecutor.java @@ -208,8 +208,9 @@ public class CreatePatchCommitExecutor extends LocalCommitExecutor implements Pr VcsApplicationSettings.getInstance().PATCH_STORAGE_LOCATION = PATCH_PATH; final boolean reversePatch = myPanel.isReversePatch(); - List patches = IdeaTextPatchBuilder.buildPatch(myProject, changes, myPanel.getBaseDirName(), reversePatch); - PatchWriter.writePatches(myProject, fileName, patches, myCommitContext, myPanel.getEncoding()); + String baseDirName = myPanel.getBaseDirName(); + List patches = IdeaTextPatchBuilder.buildPatch(myProject, changes, baseDirName, reversePatch); + PatchWriter.writePatches(myProject, fileName, baseDirName, patches, myCommitContext, myPanel.getEncoding()); final String message; if (binaryCount == 0) { message = VcsBundle.message("create.patch.success.confirmation", file.getPath()); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchWriter.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchWriter.java index d3462326c2b8..366337a4e006 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchWriter.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/patch/PatchWriter.java @@ -17,10 +17,13 @@ package com.intellij.openapi.vcs.changes.patch; import com.intellij.codeStyle.CodeStyleFacade; import com.intellij.openapi.diff.impl.patch.FilePatch; +import com.intellij.openapi.diff.impl.patch.PatchEP; import com.intellij.openapi.diff.impl.patch.UnifiedDiffWriter; +import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.project.Project; import com.intellij.openapi.vcs.changes.CommitContext; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.io.FileOutputStream; import java.io.IOException; @@ -29,24 +32,21 @@ import java.io.Writer; import java.nio.charset.Charset; import java.util.List; -/** - * @author irengrig - * Date: 2/25/11 - * Time: 6:41 PM - */ public class PatchWriter { private PatchWriter() { } - public static void writePatches(final Project project, + public static void writePatches(@NotNull final Project project, String fileName, + @Nullable String basePath, List patches, CommitContext commitContext, @NotNull Charset charset) throws IOException { Writer writer = new OutputStreamWriter(new FileOutputStream(fileName), charset); try { final String lineSeparator = CodeStyleFacade.getInstance(project).getLineSeparator(); - UnifiedDiffWriter.write(project, patches, writer, lineSeparator, commitContext); + UnifiedDiffWriter + .write(project, basePath, patches, writer, lineSeparator, Extensions.getExtensions(PatchEP.EP_NAME, project), commitContext); } finally { writer.close(); diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java index 91368ac3ec5d..ab8574d5e32e 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/treeConflict/ApplyPatchSaveToFileExecutor.java @@ -87,7 +87,8 @@ public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor textPatches = patchGroupsToOneGroup(patchGroupsToApply, baseForPatch); - PatchWriter.writePatches(myProject, save.getFile().getPath(), textPatches, commitContext, CharsetToolkit.UTF8_CHARSET); + PatchWriter.writePatches(myProject, save.getFile().getPath(), baseForPatch.getPath(), textPatches, commitContext, + CharsetToolkit.UTF8_CHARSET); } catch (final IOException e) { LOG.info(e);