[patch]: implement applying binary files from patchFile

* show binaries inside the same apply patch dialog;
* move all common parts for shelved and simple binary files;
This commit is contained in:
Nadya Zabrodina
2016-08-23 17:09:13 +03:00
committed by Nadya Zabrodina
parent 3779db5e74
commit 03593ea9ca
8 changed files with 270 additions and 84 deletions
@@ -516,6 +516,7 @@ revert.changes.title=Revert Changes
action.revert.selected.changes.text=Revert Selected Changes
revert.changes.default.name=Revert: {0}
shelved.version.name=Shelved version
patched.version.name=Patched version
local.version.title=Local version
change.file.renamed.from.text=- renamed from {0}
change.file.moved.from.text=- moved from {0}
@@ -15,6 +15,7 @@
*/
package com.intellij.openapi.diff.impl.patch;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class BinaryFilePatch extends FilePatch {
@@ -43,4 +44,12 @@ public class BinaryFilePatch extends FilePatch {
public byte[] getAfterContent() {
return myAfterContent;
}
@NotNull
public BinaryFilePatch copy() {
BinaryFilePatch copied = new BinaryFilePatch(this.getBeforeContent(), this.getAfterContent());
copied.setBeforeName(this.getBeforeName());
copied.setAfterName(this.getAfterName());
return copied;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.openapi.diff.impl.patch.BinaryFilePatch;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.*;
import com.intellij.openapi.vcs.changes.shelf.SimpleBinaryContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
public class BinaryFilePatchInProgress extends CommonBinaryFilePatchInProgress<BinaryFilePatch> {
protected BinaryFilePatchInProgress(@NotNull BinaryFilePatch patch,
@Nullable Collection<VirtualFile> autoBases,
@NotNull VirtualFile baseDir) {
super(patch.copy(), autoBases, baseDir);
}
@NotNull
@Override
protected BinaryContentRevision createNewContentRevision(@NotNull FilePath newFilePath) {
return new SimpleBinaryContentRevision(newFilePath) {
@Nullable
@Override
public byte[] getBinaryContent() throws VcsException {
return myPatch.getAfterContent();
}
};
}
@NotNull
@Override
protected Change createChange(Project project) {
ContentRevision before = null;
ContentRevision after = null;
if (!myPatch.isNewFile()) {
before = new CurrentBinaryContentRevision(getFilePath()) {
@NotNull
@Override
public VcsRevisionNumber getRevisionNumber() {
return new TextRevisionNumber(VcsBundle.message("local.version.title"));
}
};
}
if (!myPatch.isDeletedFile()) {
after = createNewContentRevision(getFilePath());
}
return new Change(before, after);
}
}
@@ -0,0 +1,110 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes.patch;
/*
* Copyright 2000-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import com.intellij.diff.chains.DiffRequestProducer;
import com.intellij.diff.chains.DiffRequestProducerException;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.openapi.diff.impl.patch.FilePatch;
import com.intellij.openapi.diff.impl.patch.PatchReader;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
public abstract class CommonBinaryFilePatchInProgress<T extends FilePatch> extends AbstractFilePatchInProgress<T> {
protected CommonBinaryFilePatchInProgress(T patch,
Collection<VirtualFile> autoBases,
VirtualFile baseDir) {
super(patch, autoBases, baseDir);
}
@Override
public ContentRevision getNewContentRevision() {
if (FilePatchStatus.DELETED.equals(myStatus)) return null;
if (myNewContentRevision != null) return myNewContentRevision;
if (myPatch.getAfterFileName() != null) {
FilePath newFilePath = getFilePath();
myNewContentRevision = createNewContentRevision(newFilePath);
}
return myNewContentRevision;
}
@NotNull
protected abstract BinaryContentRevision createNewContentRevision(@NotNull final FilePath newFilePath);
@NotNull
protected abstract Change createChange(Project project);
@NotNull
protected FilePath getFilePath() {
return FilePatchStatus.ADDED.equals(myStatus) ? VcsUtil.getFilePath(myIoCurrentBase, false)
: detectNewFilePathForMovedOrModified();
}
@NotNull
@Override
public DiffRequestProducer getDiffRequestProducers(final Project project, final PatchReader baseContents) {
return new DiffRequestProducer() {
@NotNull
@Override
public DiffRequest process(@NotNull UserDataHolder context, @NotNull ProgressIndicator indicator)
throws DiffRequestProducerException, ProcessCanceledException {
return PatchDiffRequestFactory.createDiffRequest(project, createChange(project), getName(), context, indicator);
}
@NotNull
@Override
public String getName() {
final File file1 = new File(VfsUtilCore.virtualToIoFile(getBase()),
myPatch.getAfterName() == null ? myPatch.getBeforeName() : myPatch.getAfterName());
return FileUtil.toSystemDependentName(file1.getPath());
}
};
}
}
@@ -16,6 +16,7 @@
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diff.impl.patch.BinaryFilePatch;
import com.intellij.openapi.diff.impl.patch.FilePatch;
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
import com.intellij.openapi.diff.impl.patch.apply.GenericPatchApplier;
@@ -334,6 +335,7 @@ public class MatchPatchPaths {
private static AbstractFilePatchInProgress createPatchInProgress(@NotNull FilePatch patch, @NotNull VirtualFile dir) {
if (patch instanceof TextFilePatch) return new TextFilePatchInProgress((TextFilePatch)patch, null, dir);
if (patch instanceof ShelvedBinaryFilePatch) return new ShelvedBinaryFilePatchInProgress((ShelvedBinaryFilePatch)patch, null, dir);
if (patch instanceof BinaryFilePatch) return new BinaryFilePatchInProgress((BinaryFilePatch)patch, null, dir);
return null;
}
}
@@ -15,30 +15,18 @@
*/
package com.intellij.openapi.vcs.changes.patch;
import com.intellij.diff.chains.DiffRequestProducer;
import com.intellij.diff.chains.DiffRequestProducerException;
import com.intellij.diff.requests.DiffRequest;
import com.intellij.openapi.diff.impl.patch.PatchReader;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolder;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
import com.intellij.openapi.vcs.changes.Change;
import com.intellij.openapi.vcs.changes.ContentRevision;
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryContentRevision;
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryFile;
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryFilePatch;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.vcsUtil.VcsUtil;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Collection;
public class ShelvedBinaryFilePatchInProgress extends AbstractFilePatchInProgress<ShelvedBinaryFilePatch> {
public class ShelvedBinaryFilePatchInProgress extends CommonBinaryFilePatchInProgress<ShelvedBinaryFilePatch> {
protected ShelvedBinaryFilePatchInProgress(ShelvedBinaryFilePatch patch,
Collection<VirtualFile> autoBases,
@@ -46,39 +34,14 @@ public class ShelvedBinaryFilePatchInProgress extends AbstractFilePatchInProgres
super(ShelvedBinaryFilePatch.patchCopy(patch), autoBases, baseDir);
}
@NotNull
@Override
public ContentRevision getNewContentRevision() {
if (FilePatchStatus.DELETED.equals(myStatus)) return null;
if (myNewContentRevision != null) return myNewContentRevision;
if (myPatch.getAfterFileName() != null) {
final FilePath newFilePath = FilePatchStatus.ADDED.equals(myStatus) ? VcsUtil.getFilePath(myIoCurrentBase, false)
: detectNewFilePathForMovedOrModified();
myNewContentRevision = new ShelvedBinaryContentRevision(newFilePath, myPatch.getShelvedBinaryFile().SHELVED_PATH);
}
return myNewContentRevision;
protected BinaryContentRevision createNewContentRevision(@NotNull FilePath newFilePath) {
return new ShelvedBinaryContentRevision(newFilePath, myPatch.getShelvedBinaryFile().SHELVED_PATH);
}
@NotNull
@Override
public DiffRequestProducer getDiffRequestProducers(final Project project, final PatchReader baseContents) {
final ShelvedBinaryFile file = getPatch().getShelvedBinaryFile();
return new DiffRequestProducer() {
@NotNull
@Override
public DiffRequest process(@NotNull UserDataHolder context, @NotNull ProgressIndicator indicator)
throws DiffRequestProducerException, ProcessCanceledException {
Change change = file.createChange(project);
return PatchDiffRequestFactory.createDiffRequest(project, change, getName(), context, indicator);
}
@NotNull
@Override
public String getName() {
final File file1 = new File(VfsUtilCore.virtualToIoFile(getBase()),
file.AFTER_PATH == null ? file.BEFORE_PATH : file.AFTER_PATH);
return FileUtil.toSystemDependentName(file1.getPath());
}
};
protected Change createChange(Project project) {
return myPatch.getShelvedBinaryFile().createChange(project);
}
}
@@ -19,26 +19,16 @@ import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 12/17/12
* Time: 3:59 PM
*/
public class ShelvedBinaryContentRevision implements BinaryContentRevision {
private final FilePath myPath;
public class ShelvedBinaryContentRevision extends SimpleBinaryContentRevision {
private final String myShelvedContentPath;
public ShelvedBinaryContentRevision(FilePath path, final String shelvedContentPath) {
myPath = path;
super(path, VcsBundle.message("shelved.version.name"));
myShelvedContentPath = shelvedContentPath;
}
@@ -52,32 +42,4 @@ public class ShelvedBinaryContentRevision implements BinaryContentRevision {
throw new VcsException(e);
}
}
@Nullable
@Override
public String getContent() throws VcsException {
throw new IllegalStateException();
}
@NotNull
@Override
public FilePath getFile() {
return myPath;
}
@NotNull
@Override
public VcsRevisionNumber getRevisionNumber() {
return new VcsRevisionNumber() {
@Override
public String asString() {
return VcsBundle.message("shelved.version.name");
}
@Override
public int compareTo(VcsRevisionNumber o) {
return -1;
}
};
}
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.openapi.vcs.changes.shelf;
import com.intellij.openapi.vcs.FilePath;
import com.intellij.openapi.vcs.VcsBundle;
import com.intellij.openapi.vcs.VcsException;
import com.intellij.openapi.vcs.changes.BinaryContentRevision;
import com.intellij.openapi.vcs.history.VcsRevisionNumber;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public abstract class SimpleBinaryContentRevision implements BinaryContentRevision {
@NotNull private final FilePath myPath;
@NotNull private final String myRevisionPresentationName;
public SimpleBinaryContentRevision(@NotNull FilePath path) {
myPath = path;
myRevisionPresentationName = VcsBundle.message("patched.version.name");
}
public SimpleBinaryContentRevision(@NotNull FilePath path, @NotNull String presentationName) {
myPath = path;
myRevisionPresentationName = presentationName;
}
@Nullable
@Override
public String getContent() throws VcsException {
throw new IllegalStateException();
}
@NotNull
@Override
public FilePath getFile() {
return myPath;
}
@NotNull
@Override
public VcsRevisionNumber getRevisionNumber() {
return new VcsRevisionNumber() {
@Override
public String asString() {
return myRevisionPresentationName;
}
@Override
public int compareTo(VcsRevisionNumber o) {
return -1;
}
};
}
}