merge: make file writable on applyLeft/applyRight

This commit is contained in:
Aleksey Pivovarov
2015-08-27 13:41:42 +03:00
committed by Aleksey Pivovarov
parent 6f78ade9cb
commit bbb2e5953a
5 changed files with 33 additions and 11 deletions
@@ -268,7 +268,7 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
contents.add(myContentFactory.createFromBytes(project, output, bytes));
}
return new BinaryMergeRequestImpl(outputContent, originalContent, contents, byteContents, title, contentTitles, applyCallback);
return new BinaryMergeRequestImpl(project, outputContent, originalContent, contents, byteContents, title, contentTitles, applyCallback);
}
catch (IOException e) {
throw new InvalidDiffRequestException("Can't read from file", e);
@@ -358,7 +358,7 @@ public class DiffRequestFactoryImpl extends DiffRequestFactory {
byteContents.add(file.contentsToByteArray()); // TODO: we can read contents from file when needed
}
return new BinaryMergeRequestImpl(outputContent, originalContent, contents, byteContents, title, contentTitles, applyCallback);
return new BinaryMergeRequestImpl(project, outputContent, originalContent, contents, byteContents, title, contentTitles, applyCallback);
}
catch (IOException e) {
throw new InvalidDiffRequestException("Can't read from file", e);
@@ -20,11 +20,13 @@ import com.intellij.diff.contents.DiffContent;
import com.intellij.diff.contents.FileContent;
import com.intellij.diff.merge.BinaryMergeRequest;
import com.intellij.diff.merge.MergeResult;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.ThreeSide;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -35,6 +37,7 @@ import java.util.List;
public class BinaryMergeRequestImpl extends BinaryMergeRequest {
private static final Logger LOG = Logger.getInstance(BinaryMergeRequestImpl.class);
@Nullable private final Project myProject;
@NotNull private final FileContent myFile;
@NotNull private final List<DiffContent> myContents;
@@ -46,7 +49,8 @@ public class BinaryMergeRequestImpl extends BinaryMergeRequest {
@Nullable private final Consumer<MergeResult> myApplyCallback;
public BinaryMergeRequestImpl(@NotNull FileContent file,
public BinaryMergeRequestImpl(@Nullable Project project,
@NotNull FileContent file,
@NotNull byte[] originalContent,
@NotNull List<DiffContent> contents,
@NotNull List<byte[]> byteContents,
@@ -57,6 +61,7 @@ public class BinaryMergeRequestImpl extends BinaryMergeRequest {
assert contents.size() == 3;
assert contentTitles.size() == 3;
myProject = project;
myFile = file;
myOriginalContent = originalContent;
@@ -123,11 +128,13 @@ public class BinaryMergeRequestImpl extends BinaryMergeRequest {
@Override
protected void run() throws Throwable {
try {
myFile.getFile().setBinaryContent(applyContent);
VirtualFile file = myFile.getFile();
if (!DiffUtil.makeWritable(myProject, file)) throw new IOException("File is read-only: " + file.getPresentableName());
file.setBinaryContent(applyContent);
}
catch (IOException e) {
LOG.error(e);
Messages.showErrorDialog((Project)null, "Can't apply result", CommonBundle.getErrorTitle());
Messages.showErrorDialog(myProject, "Can't apply result", CommonBundle.getErrorTitle());
}
}
}.execute();
@@ -18,8 +18,8 @@ package com.intellij.diff.requests;
import com.intellij.diff.contents.DocumentContent;
import com.intellij.diff.merge.MergeResult;
import com.intellij.diff.merge.TextMergeRequest;
import com.intellij.diff.util.DiffUtil;
import com.intellij.diff.util.ThreeSide;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Consumer;
@@ -108,12 +108,12 @@ public class TextMergeRequestImpl extends TextMergeRequest {
}
if (applyContent != null) {
new WriteCommandAction.Simple(myProject) {
DiffUtil.executeWriteCommand(myOutput.getDocument(), myProject, null, new Runnable() {
@Override
protected void run() throws Throwable {
public void run() {
myOutput.getDocument().setText(applyContent);
}
}.execute();
});
}
if (myApplyCallback != null) myApplyCallback.consume(result);
@@ -744,7 +744,11 @@ public class DiffUtil {
@CalledInAwt
public final void run() {
if (!makeWritable(myProject, myDocument)) return;
if (!makeWritable(myProject, myDocument)) {
VirtualFile file = FileDocumentManager.getInstance().getFile(myDocument);
LOG.warn("Document is read-only" + (file != null ? ": " + file.getPresentableName() : ""));
return;
}
ApplicationManager.getApplication().runWriteAction(new Runnable() {
public void run() {
@@ -797,6 +801,13 @@ public class DiffUtil {
return ReadonlyStatusHandler.ensureDocumentWritable(project, document);
}
@CalledInAwt
public static boolean makeWritable(@Nullable Project project, @NotNull VirtualFile file) {
if (file.isWritable()) return true;
if (project == null) return false;
return ReadonlyStatusHandler.ensureFilesWritable(project, file);
}
//
// Windows
//
@@ -22,7 +22,7 @@ import com.intellij.diff.DiffRequestFactory;
import com.intellij.diff.InvalidDiffRequestException;
import com.intellij.diff.merge.MergeRequest;
import com.intellij.diff.merge.MergeResult;
import com.intellij.diff.merge.MergeWindow;
import com.intellij.diff.util.DiffUtil;
import com.intellij.ide.presentation.VirtualFilePresentation;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
@@ -61,6 +61,7 @@ import javax.swing.event.ListSelectionListener;
import javax.swing.table.TableCellRenderer;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.*;
/**
@@ -236,6 +237,9 @@ public class MultipleFileMergeDialog extends DialogWrapper {
public void run() {
try {
if (!(myProvider instanceof MergeProvider2) || myMergeSession.canMerge(file)) {
if (!DiffUtil.makeWritable(myProject, file)) {
throw new IOException("File is read-only: " + file.getPresentableName());
}
MergeData data = myProvider.loadRevisions(file);
if (isCurrent) {
file.setBinaryContent(data.CURRENT);