mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
[vcs] IDEA-94335 Shelve changes supports binary files; IDEA-139877 Error applying patch when name conflict appears during rename/move
* show binary files in unshelve dialog; * implement show diff for shelved binary; * create generic AbstractFilePatchInProgress to store base and generic file patch information; * change ApplyPatchExecutor to be generic, too : for different types of file patches; * perform rename when unshelve to third name if file with destination name already exist in source directory * cleanUp * fix potential NPE * smart matching for binary shelved files implemented: do the same matching as for text file patches, except context matching; * choose the best matched variant for binary by strip counter (instead of context) * FilePatchInProgress renamed to TextFilePatchInProgress
This commit is contained in:
+1
-1
@@ -29,7 +29,7 @@ public class ApplyBinaryFilePatch extends ApplyFilePatchBase<BinaryFilePatch> {
|
||||
super(patch);
|
||||
}
|
||||
|
||||
protected void applyCreate(final VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
protected void applyCreate(Project project, final VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
newFile.setBinaryContent(myPatch.getAfterContent());
|
||||
}
|
||||
|
||||
|
||||
+30
-11
@@ -15,12 +15,18 @@
|
||||
*/
|
||||
package com.intellij.openapi.diff.impl.patch.apply;
|
||||
|
||||
import com.intellij.openapi.diff.impl.patch.ApplyPatchStatus;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.CommitContext;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchForBaseRevisionTexts;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -29,18 +35,31 @@ public class ApplyBinaryShelvedFilePatch extends ApplyFilePatchBase<ShelveChange
|
||||
super(patch);
|
||||
}
|
||||
|
||||
// todo check the case!!!
|
||||
// todo check the case!!!
|
||||
// todo check the case!!!
|
||||
// todo check the case!!!
|
||||
// todo check the case!!!
|
||||
// todo check the case!!!
|
||||
@Override
|
||||
protected Result applyChange(Project project, VirtualFile fileToPatch, FilePath pathBeforeRename, Getter<CharSequence> baseContents) throws IOException {
|
||||
return null;
|
||||
protected void applyCreate(Project project, final VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
applyChange(project, newFile, null, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyCreate(VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
protected Result applyChange(Project project, final VirtualFile fileToPatch, FilePath pathBeforeRename, Getter<CharSequence> baseContents)
|
||||
throws IOException {
|
||||
try {
|
||||
ContentRevision contentRevision = myPatch.getShelvedBinaryFile().createChange(project).getAfterRevision();
|
||||
if (contentRevision != null) {
|
||||
assert (contentRevision instanceof ShelvedBinaryContentRevision);
|
||||
byte[] binaryContent = ((ShelvedBinaryContentRevision)contentRevision).getBinaryContent();
|
||||
//it may be new empty binary file
|
||||
fileToPatch.setBinaryContent(binaryContent != null ? binaryContent : ArrayUtil.EMPTY_BYTE_ARRAY);
|
||||
}
|
||||
}
|
||||
catch (VcsException e) {
|
||||
LOG.error("Couldn't apply shelved binary patch", e);
|
||||
return new Result(ApplyPatchStatus.FAILURE) {
|
||||
|
||||
@Override
|
||||
public ApplyPatchForBaseRevisionTexts getMergeData() {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
+6
-5
@@ -18,7 +18,7 @@ package com.intellij.openapi.diff.impl.patch.apply;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.patch.ApplyPatchContext;
|
||||
import com.intellij.openapi.diff.impl.patch.FilePatch;
|
||||
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
|
||||
import com.intellij.openapi.fileEditor.FileEditorManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
@@ -30,7 +30,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class ApplyFilePatchBase<T extends FilePatch> implements ApplyFilePatch {
|
||||
private final static Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase");
|
||||
protected final static Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.patch.apply.ApplyFilePatchBase");
|
||||
protected final T myPatch;
|
||||
|
||||
public ApplyFilePatchBase(T patch) {
|
||||
@@ -50,9 +50,9 @@ public abstract class ApplyFilePatchBase<T extends FilePatch> implements ApplyFi
|
||||
LOG.debug("apply patch called for : " + fileToPatch.getPath());
|
||||
}
|
||||
if (myPatch.isNewFile()) {
|
||||
applyCreate(fileToPatch, commitContext);
|
||||
applyCreate(project, fileToPatch, commitContext);
|
||||
} else if (myPatch.isDeletedFile()) {
|
||||
FileEditorManagerImpl.getInstance(project).closeFile(fileToPatch);
|
||||
FileEditorManager.getInstance(project).closeFile(fileToPatch);
|
||||
fileToPatch.delete(this);
|
||||
}
|
||||
else {
|
||||
@@ -61,7 +61,8 @@ public abstract class ApplyFilePatchBase<T extends FilePatch> implements ApplyFi
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
protected abstract void applyCreate(VirtualFile newFile, CommitContext commitContext) throws IOException;
|
||||
protected abstract void applyCreate(Project project, VirtualFile newFile, CommitContext commitContext) throws IOException;
|
||||
|
||||
protected abstract Result applyChange(Project project, VirtualFile fileToPatch, FilePath pathBeforeRename, Getter<CharSequence> baseContents) throws IOException;
|
||||
|
||||
@Nullable
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@ public class ApplyTextFilePatch extends ApplyFilePatchBase<TextFilePatch> {
|
||||
};
|
||||
}
|
||||
|
||||
protected void applyCreate(final VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
protected void applyCreate(Project project, final VirtualFile newFile, CommitContext commitContext) throws IOException {
|
||||
final Document document = FileDocumentManager.getInstance().getDocument(newFile);
|
||||
if (document == null) {
|
||||
throw new IOException("Failed to set contents for new file " + newFile.getPath());
|
||||
|
||||
+37
-6
@@ -26,16 +26,19 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.ThrowableComputable;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.vcs.*;
|
||||
import com.intellij.openapi.vcs.changes.patch.RelativePathCalculator;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.CalledInAwt;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
@@ -110,7 +113,7 @@ public class PathsVerifier<BinaryType extends FilePatch> {
|
||||
}
|
||||
return affected;
|
||||
}
|
||||
|
||||
|
||||
private void addAllFilePath(final Collection<VirtualFile> files, final Collection<FilePath> paths) {
|
||||
for (VirtualFile file : files) {
|
||||
paths.add(VcsUtil.getFilePath(file));
|
||||
@@ -337,9 +340,12 @@ public class PathsVerifier<BinaryType extends FilePatch> {
|
||||
if (patch instanceof TextFilePatch) {
|
||||
myTextPatches.add(Pair.create(file, ApplyFilePatchFactory.create((TextFilePatch)patch)));
|
||||
} else {
|
||||
final ApplyFilePatchBase<BinaryType> applyBinaryPatch = (ApplyFilePatchBase<BinaryType>) ((patch instanceof BinaryFilePatch) ? ApplyFilePatchFactory
|
||||
.create((BinaryFilePatch) patch) :
|
||||
ApplyFilePatchFactory.create((ShelveChangesManager.ShelvedBinaryFilePatch) patch));
|
||||
final ApplyFilePatchBase<BinaryType> applyBinaryPatch = (ApplyFilePatchBase<BinaryType>)((patch instanceof BinaryFilePatch)
|
||||
? ApplyFilePatchFactory
|
||||
.create((BinaryFilePatch)patch)
|
||||
:
|
||||
ApplyFilePatchFactory.create(
|
||||
(ShelveChangesManager.ShelvedBinaryFilePatch)patch));
|
||||
myBinaryPatches.add(Pair.create(file, applyBinaryPatch));
|
||||
}
|
||||
myWritableFiles.add(file);
|
||||
@@ -512,14 +518,39 @@ public class PathsVerifier<BinaryType extends FilePatch> {
|
||||
|
||||
public VirtualFile doMove() throws IOException {
|
||||
final VirtualFile oldParent = myCurrent.getParent();
|
||||
if (! Comparing.equal(myCurrent.getName(), myNewName)) {
|
||||
boolean needRename = !Comparing.equal(myCurrent.getName(), myNewName);
|
||||
boolean needMove = !myNewParent.equals(oldParent);
|
||||
if (needRename) {
|
||||
if (needMove) {
|
||||
File oldParentFile = VfsUtilCore.virtualToIoFile(oldParent);
|
||||
File targetAfterRenameFile = new File(oldParentFile, myNewName);
|
||||
if (targetAfterRenameFile.exists() && myCurrent.exists()) {
|
||||
// if there is a conflict during first rename we have to rename to third name, then move, then rename to final target
|
||||
performRenameWithConflicts(oldParentFile);
|
||||
return myCurrent;
|
||||
}
|
||||
}
|
||||
myCurrent.rename(PatchApplier.class, myNewName);
|
||||
}
|
||||
if (! myNewParent.equals(oldParent)) {
|
||||
if (needMove) {
|
||||
myCurrent.move(PatchApplier.class, myNewParent);
|
||||
}
|
||||
return myCurrent;
|
||||
}
|
||||
|
||||
private void performRenameWithConflicts(@NotNull File oldParent) throws IOException {
|
||||
File tmpFileWithUniqueName = FileUtil.createTempFile(oldParent, "tempFileToMove", null, false);
|
||||
File newParentFile = VfsUtilCore.virtualToIoFile(myNewParent);
|
||||
File destFile = new File(newParentFile, tmpFileWithUniqueName.getName());
|
||||
while (destFile.exists()) {
|
||||
destFile = new File(newParentFile,
|
||||
FileUtil.createTempFile(oldParent, FileUtil.getNameWithoutExtension(destFile.getName()), null, false)
|
||||
.getName());
|
||||
}
|
||||
myCurrent.rename(PatchApplier.class, destFile.getName());
|
||||
myCurrent.move(PatchApplier.class, myNewParent);
|
||||
myCurrent.rename(PatchApplier.class, myNewName);
|
||||
}
|
||||
}
|
||||
|
||||
public interface BaseMapper {
|
||||
|
||||
+60
-79
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -15,9 +15,7 @@
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes.patch;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diff.impl.patch.FilePatch;
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
|
||||
import com.intellij.openapi.diff.impl.patch.formove.PathMerger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
@@ -29,11 +27,11 @@ import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.CurrentContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.SimpleContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.actions.ChangeDiffRequestPresentable;
|
||||
import com.intellij.openapi.vcs.changes.actions.DiffRequestPresentable;
|
||||
import com.intellij.openapi.vcs.changes.actions.DiffRequestPresentableProxy;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.PathUtil;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -44,24 +42,22 @@ import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public class FilePatchInProgress implements Strippable {
|
||||
private final TextFilePatch myPatch;
|
||||
public abstract class AbstractFilePatchInProgress<T extends FilePatch> implements Strippable {
|
||||
protected final T myPatch;
|
||||
private final PatchStrippable myStrippable;
|
||||
private final FilePatchStatus myStatus;
|
||||
protected final FilePatchStatus myStatus;
|
||||
|
||||
private VirtualFile myBase;
|
||||
private File myIoCurrentBase;
|
||||
private VirtualFile myCurrentBase;
|
||||
protected File myIoCurrentBase;
|
||||
protected VirtualFile myCurrentBase;
|
||||
private boolean myBaseExists;
|
||||
private ContentRevision myNewContentRevision;
|
||||
protected ContentRevision myNewContentRevision;
|
||||
private ContentRevision myCurrentRevision;
|
||||
private final List<VirtualFile> myAutoBases;
|
||||
private volatile Boolean myConflicts;
|
||||
protected volatile Boolean myConflicts;
|
||||
|
||||
private File myAfterFile;
|
||||
|
||||
public FilePatchInProgress(final TextFilePatch patch, final Collection<VirtualFile> autoBases, final VirtualFile baseDir) {
|
||||
myPatch = patch.pathsOnlyCopy();
|
||||
protected AbstractFilePatchInProgress(final T patch, final Collection<VirtualFile> autoBases, final VirtualFile baseDir) {
|
||||
myPatch = patch; //should be a copy of FilePatch! because names may be changes during processing variants
|
||||
myStrippable = new PatchStrippable(patch);
|
||||
myAutoBases = new ArrayList<VirtualFile>();
|
||||
if (autoBases != null) {
|
||||
@@ -70,7 +66,8 @@ public class FilePatchInProgress implements Strippable {
|
||||
myStatus = getStatus(myPatch);
|
||||
if (myAutoBases.isEmpty()) {
|
||||
setNewBase(baseDir);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setNewBase(myAutoBases.get(0));
|
||||
}
|
||||
}
|
||||
@@ -85,13 +82,14 @@ public class FilePatchInProgress implements Strippable {
|
||||
}
|
||||
}
|
||||
|
||||
private static FilePatchStatus getStatus(final TextFilePatch patch) {
|
||||
final String beforeName = patch.getBeforeName().replace("\\", "/");
|
||||
final String afterName = patch.getAfterName().replace("\\", "/");
|
||||
|
||||
private FilePatchStatus getStatus(final T patch) {
|
||||
final String beforeName = PathUtil.toSystemIndependentName(patch.getBeforeName());
|
||||
final String afterName = PathUtil.toSystemIndependentName(patch.getAfterName());
|
||||
|
||||
if (patch.isNewFile() || (beforeName == null)) {
|
||||
return FilePatchStatus.ADDED;
|
||||
} else if (patch.isDeletedFile() || (afterName == null)) {
|
||||
}
|
||||
else if (patch.isDeletedFile() || (afterName == null)) {
|
||||
return FilePatchStatus.DELETED;
|
||||
}
|
||||
|
||||
@@ -107,7 +105,6 @@ public class FilePatchInProgress implements Strippable {
|
||||
myBase = base;
|
||||
myNewContentRevision = null;
|
||||
myCurrentRevision = null;
|
||||
myAfterFile = null;
|
||||
myConflicts = null;
|
||||
|
||||
final String beforeName = myPatch.getBeforeName();
|
||||
@@ -115,7 +112,8 @@ public class FilePatchInProgress implements Strippable {
|
||||
myIoCurrentBase = PathMerger.getFile(new File(myBase.getPath()), beforeName);
|
||||
myCurrentBase = myIoCurrentBase == null ? null : VcsUtil.getVirtualFileWithRefresh(myIoCurrentBase);
|
||||
myBaseExists = (myCurrentBase != null) && myCurrentBase.exists();
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
// creation
|
||||
final String afterName = myPatch.getAfterName();
|
||||
myBaseExists = true;
|
||||
@@ -144,11 +142,11 @@ public class FilePatchInProgress implements Strippable {
|
||||
return myBase;
|
||||
}
|
||||
|
||||
public TextFilePatch getPatch() {
|
||||
public T getPatch() {
|
||||
return myPatch;
|
||||
}
|
||||
|
||||
public boolean isBaseExists() {
|
||||
private boolean isBaseExists() {
|
||||
return myBaseExists;
|
||||
}
|
||||
|
||||
@@ -156,49 +154,30 @@ public class FilePatchInProgress implements Strippable {
|
||||
return myBaseExists || FilePatchStatus.ADDED.equals(myStatus);
|
||||
}
|
||||
|
||||
public ContentRevision getNewContentRevision() {
|
||||
if (FilePatchStatus.DELETED.equals(myStatus)) return null;
|
||||
protected abstract ContentRevision getNewContentRevision();
|
||||
|
||||
if (myNewContentRevision == null) {
|
||||
myConflicts = null;
|
||||
if (FilePatchStatus.ADDED.equals(myStatus)) {
|
||||
final FilePath newFilePath = VcsUtil.getFilePathOnNonLocal(myIoCurrentBase.getAbsolutePath(), false);
|
||||
final String content = myPatch.getNewFileText();
|
||||
myNewContentRevision = new SimpleContentRevision(content, newFilePath, myPatch.getAfterVersionId());
|
||||
} else {
|
||||
final FilePath newFilePath;
|
||||
if (FilePatchStatus.MOVED_OR_RENAMED.equals(myStatus)) {
|
||||
newFilePath = VcsUtil.getFilePath(PathMerger.getFile(new File(myBase.getPath()), myPatch.getAfterName()), false);
|
||||
} else {
|
||||
newFilePath = (myCurrentBase != null) ? VcsUtil.getFilePath(myCurrentBase) : VcsUtil.getFilePath(myIoCurrentBase, false);
|
||||
}
|
||||
myNewContentRevision = new LazyPatchContentRevision(myCurrentBase, newFilePath, myPatch.getAfterVersionId(), myPatch);
|
||||
if (myCurrentBase != null) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
public void run() {
|
||||
((LazyPatchContentRevision) myNewContentRevision).getContent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return myNewContentRevision;
|
||||
@NotNull
|
||||
protected FilePath detectNewFilePathForMovedOrModified() {
|
||||
return FilePatchStatus.MOVED_OR_RENAMED.equals(myStatus)
|
||||
? VcsUtil.getFilePath(PathMerger.getFile(new File(myBase.getPath()), myPatch.getAfterName()), false)
|
||||
: (myCurrentBase != null) ? VcsUtil.getFilePath(myCurrentBase) : VcsUtil.getFilePath(myIoCurrentBase, false);
|
||||
}
|
||||
|
||||
public boolean isConflictingChange() {
|
||||
private boolean isConflictingChange() {
|
||||
if (myConflicts == null) {
|
||||
if ((myCurrentBase != null) && (myNewContentRevision instanceof LazyPatchContentRevision)) {
|
||||
((LazyPatchContentRevision) myNewContentRevision).getContent();
|
||||
myConflicts = ((LazyPatchContentRevision) myNewContentRevision).isPatchApplyFailed();
|
||||
} else {
|
||||
((LazyPatchContentRevision)myNewContentRevision).getContent();
|
||||
myConflicts = ((LazyPatchContentRevision)myNewContentRevision).isPatchApplyFailed();
|
||||
}
|
||||
else {
|
||||
myConflicts = false;
|
||||
}
|
||||
}
|
||||
return myConflicts;
|
||||
}
|
||||
|
||||
public ContentRevision getCurrentRevision() {
|
||||
if (FilePatchStatus.ADDED.equals(myStatus)) return null;
|
||||
private ContentRevision getCurrentRevision() {
|
||||
if (FilePatchStatus.ADDED.equals(myStatus)) return null;
|
||||
if (myCurrentRevision == null) {
|
||||
FilePath filePath = (myCurrentBase != null) ? VcsUtil.getFilePath(myCurrentBase) : VcsUtil.getFilePath(myIoCurrentBase, false);
|
||||
myCurrentRevision = new CurrentContentRevision(filePath);
|
||||
@@ -207,15 +186,17 @@ public class FilePatchInProgress implements Strippable {
|
||||
}
|
||||
|
||||
public static class PatchChange extends Change {
|
||||
private final FilePatchInProgress myPatchInProgress;
|
||||
private final AbstractFilePatchInProgress myPatchInProgress;
|
||||
|
||||
public PatchChange(ContentRevision beforeRevision, ContentRevision afterRevision, FilePatchInProgress patchInProgress) {
|
||||
public PatchChange(ContentRevision beforeRevision, ContentRevision afterRevision, AbstractFilePatchInProgress patchInProgress) {
|
||||
super(beforeRevision, afterRevision,
|
||||
patchInProgress.isBaseExists() || FilePatchStatus.ADDED.equals(patchInProgress.getStatus()) ? null : FileStatus.MERGED_WITH_CONFLICTS);
|
||||
patchInProgress.isBaseExists() || FilePatchStatus.ADDED.equals(patchInProgress.getStatus())
|
||||
? null
|
||||
: FileStatus.MERGED_WITH_CONFLICTS);
|
||||
myPatchInProgress = patchInProgress;
|
||||
}
|
||||
|
||||
public FilePatchInProgress getPatchInProgress() {
|
||||
public AbstractFilePatchInProgress getPatchInProgress() {
|
||||
return myPatchInProgress;
|
||||
}
|
||||
|
||||
@@ -226,17 +207,9 @@ public class FilePatchInProgress implements Strippable {
|
||||
@Override
|
||||
public DiffRequestPresentable init() throws VcsException {
|
||||
if (myPatchInProgress.isConflictingChange()) {
|
||||
final Getter<ApplyPatchForBaseRevisionTexts> revisionTextsGetter = new Getter<ApplyPatchForBaseRevisionTexts>() {
|
||||
@Override
|
||||
public ApplyPatchForBaseRevisionTexts get() {
|
||||
return ApplyPatchForBaseRevisionTexts.create(project, myPatchInProgress.getCurrentBase(),
|
||||
VcsUtil.getFilePath(myPatchInProgress.getCurrentBase()),
|
||||
myPatchInProgress.getPatch(), baseContents);
|
||||
}
|
||||
};
|
||||
return new MergedDiffRequestPresentable(project, revisionTextsGetter,
|
||||
myPatchInProgress.getCurrentBase(), myPatchInProgress.getPatch().getAfterVersionId());
|
||||
} else {
|
||||
return myPatchInProgress.diffRequestForConflictingChanges(project, PatchChange.this, baseContents);
|
||||
}
|
||||
else {
|
||||
return new ChangeDiffRequestPresentable(project, PatchChange.this);
|
||||
}
|
||||
}
|
||||
@@ -250,6 +223,12 @@ public class FilePatchInProgress implements Strippable {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected DiffRequestPresentable diffRequestForConflictingChanges(@NotNull Project project,
|
||||
@NotNull PatchChange change,
|
||||
@NotNull Getter<CharSequence> baseContents) {
|
||||
return new ChangeDiffRequestPresentable(project, change);
|
||||
}
|
||||
|
||||
public List<VirtualFile> getAutoBasesCopy() {
|
||||
final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(myAutoBases.size() + 1);
|
||||
@@ -309,7 +288,7 @@ public class FilePatchInProgress implements Strippable {
|
||||
private final int[] myParts;
|
||||
|
||||
private StripCapablePath(final String path) {
|
||||
final String corrected = path.trim().replace('\\', '/');
|
||||
final String corrected = PathUtil.toSystemIndependentName(path.trim());
|
||||
mySourcePath = new StringBuilder(corrected);
|
||||
final String[] steps = corrected.split("/");
|
||||
myStripMax = steps.length - 1;
|
||||
@@ -342,13 +321,13 @@ public class FilePatchInProgress implements Strippable {
|
||||
|
||||
public void up() {
|
||||
if (canUp()) {
|
||||
++ myCurrentStrip;
|
||||
++myCurrentStrip;
|
||||
}
|
||||
}
|
||||
|
||||
public void down() {
|
||||
if (canDown()) {
|
||||
-- myCurrentStrip;
|
||||
--myCurrentStrip;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -392,14 +371,16 @@ public class FilePatchInProgress implements Strippable {
|
||||
if (patch.getAfterName() != null) {
|
||||
myAfterIdx = 0;
|
||||
myParts[cnt] = new StripCapablePath(patch.getAfterName());
|
||||
++ cnt;
|
||||
} else {
|
||||
++cnt;
|
||||
}
|
||||
else {
|
||||
myAfterIdx = -1;
|
||||
}
|
||||
if (cnt < size) {
|
||||
myParts[cnt] = new StripCapablePath(patch.getBeforeName());
|
||||
myBeforeIdx = cnt;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myBeforeIdx = 0;
|
||||
}
|
||||
}
|
||||
@@ -486,7 +467,7 @@ public class FilePatchInProgress implements Strippable {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
|
||||
FilePatchInProgress that = (FilePatchInProgress)o;
|
||||
AbstractFilePatchInProgress that = (AbstractFilePatchInProgress)o;
|
||||
|
||||
if (!myStrippable.equals(that.myStrippable)) return false;
|
||||
|
||||
@@ -200,7 +200,7 @@ public class ApplyPatchAction extends DumbAwareAction {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static CharSequence getBaseContents(final TextFilePatch patchBase, final CommitContext commitContext, final Project project) {
|
||||
private static CharSequence getBaseContents(final FilePatch patchBase, final CommitContext commitContext, final Project project) {
|
||||
final BaseRevisionTextPatchEP baseRevisionTextPatchEP = Extensions.findExtension(PatchEP.EP_NAME, project, BaseRevisionTextPatchEP.class);
|
||||
if (baseRevisionTextPatchEP != null) {
|
||||
final String path = patchBase.getBeforeName() == null ? patchBase.getAfterName() : patchBase.getBeforeName();
|
||||
|
||||
+7
-12
@@ -39,12 +39,7 @@ import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
* Date: 2/25/11
|
||||
* Time: 5:58 PM
|
||||
*/
|
||||
public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor {
|
||||
public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor<AbstractFilePatchInProgress> {
|
||||
private final Project myProject;
|
||||
|
||||
public ApplyPatchDefaultExecutor(Project project) {
|
||||
@@ -58,7 +53,7 @@ public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(MultiMap<VirtualFile, FilePatchInProgress> patchGroups,
|
||||
public void apply(MultiMap<VirtualFile, AbstractFilePatchInProgress> patchGroups,
|
||||
LocalChangeList localList,
|
||||
String fileName,
|
||||
TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) {
|
||||
@@ -69,8 +64,8 @@ public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor {
|
||||
for (VirtualFile base : patchGroups.keySet()) {
|
||||
final PatchApplier patchApplier =
|
||||
new PatchApplier<BinaryFilePatch>(myProject, base, ObjectsConvertor.convert(patchGroups.get(base),
|
||||
new Convertor<FilePatchInProgress, FilePatch>() {
|
||||
public FilePatch convert(FilePatchInProgress o) {
|
||||
new Convertor<AbstractFilePatchInProgress, FilePatch>() {
|
||||
public FilePatch convert(AbstractFilePatchInProgress o) {
|
||||
return o.getPatch();
|
||||
}
|
||||
}), localList, null, commitContext);
|
||||
@@ -144,10 +139,10 @@ public class ApplyPatchDefaultExecutor implements ApplyPatchExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
public static Set<String> pathsFromGroups(MultiMap<VirtualFile, FilePatchInProgress> patchGroups) {
|
||||
public static Set<String> pathsFromGroups(MultiMap<VirtualFile, AbstractFilePatchInProgress> patchGroups) {
|
||||
final Set<String> selectedPaths = new HashSet<String>();
|
||||
final Collection<? extends FilePatchInProgress> values = patchGroups.values();
|
||||
for (FilePatchInProgress value : values) {
|
||||
final Collection<? extends AbstractFilePatchInProgress> values = patchGroups.values();
|
||||
for (AbstractFilePatchInProgress value : values) {
|
||||
final String path = value.getPatch().getBeforeName() == null ? value.getPatch().getAfterName() : value.getPatch().getBeforeName();
|
||||
selectedPaths.add(path);
|
||||
}
|
||||
|
||||
+144
-108
@@ -20,10 +20,7 @@ import com.intellij.ide.util.PropertiesComponent;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diff.impl.patch.PatchReader;
|
||||
import com.intellij.openapi.diff.impl.patch.PatchSyntaxException;
|
||||
import com.intellij.openapi.diff.impl.patch.PatchVirtualFileReader;
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
|
||||
import com.intellij.openapi.diff.impl.patch.*;
|
||||
import com.intellij.openapi.fileChooser.FileChooser;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
|
||||
@@ -40,12 +37,13 @@ import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vcs.VcsBundle;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.changes.actions.DiffRequestPresentable;
|
||||
import com.intellij.openapi.vcs.changes.actions.ShowDiffAction;
|
||||
import com.intellij.openapi.vcs.changes.actions.ShowDiffUIContext;
|
||||
import com.intellij.openapi.vcs.changes.actions.*;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryFile;
|
||||
import com.intellij.openapi.vcs.changes.ui.*;
|
||||
import com.intellij.openapi.vfs.*;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
@@ -76,7 +74,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
private final ZipperUpdater myLoadQueue;
|
||||
private final TextFieldWithBrowseButton myPatchFile;
|
||||
|
||||
private final List<FilePatchInProgress> myPatches;
|
||||
private final List<AbstractFilePatchInProgress> myPatches;
|
||||
private final List<ShelveChangesManager.ShelvedBinaryFilePatch> myBinaryShelvedPatches;
|
||||
private final MyChangeTreeList myChangesTreeList;
|
||||
|
||||
private JComponent myCenterPanel;
|
||||
@@ -98,9 +97,20 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
private final boolean myCanChangePatchFile;
|
||||
private String myHelpId = "reference.dialogs.vcs.patch.apply";
|
||||
|
||||
|
||||
public ApplyPatchDifferentiatedDialog(final Project project,
|
||||
final ApplyPatchExecutor callback,
|
||||
final List<ApplyPatchExecutor> executors,
|
||||
@NotNull final ApplyPatchMode applyPatchMode,
|
||||
@NotNull final VirtualFile patchFile,
|
||||
List<ShelveChangesManager.ShelvedBinaryFilePatch> binaryShelvedPatches) {
|
||||
this(project, callback, executors, applyPatchMode, patchFile, null, null, binaryShelvedPatches);
|
||||
}
|
||||
|
||||
|
||||
public ApplyPatchDifferentiatedDialog(final Project project, final ApplyPatchExecutor callback, final List<ApplyPatchExecutor> executors,
|
||||
@NotNull final ApplyPatchMode applyPatchMode, @NotNull final VirtualFile patchFile) {
|
||||
this(project, callback, executors, applyPatchMode, patchFile, null, null);
|
||||
this(project, callback, executors, applyPatchMode, patchFile, null, null, null);
|
||||
}
|
||||
|
||||
public ApplyPatchDifferentiatedDialog(final Project project,
|
||||
@@ -109,7 +119,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
@NotNull final ApplyPatchMode applyPatchMode,
|
||||
@NotNull final List<TextFilePatch> patches,
|
||||
@Nullable final LocalChangeList defaultList) {
|
||||
this(project, callback, executors, applyPatchMode, null, patches, defaultList);
|
||||
this(project, callback, executors, applyPatchMode, null, patches, defaultList, null);
|
||||
}
|
||||
|
||||
private ApplyPatchDifferentiatedDialog(final Project project,
|
||||
@@ -118,7 +128,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
@NotNull final ApplyPatchMode applyPatchMode,
|
||||
@Nullable final VirtualFile patchFile,
|
||||
@Nullable final List<TextFilePatch> patches,
|
||||
@Nullable final LocalChangeList defaultList) {
|
||||
@Nullable final LocalChangeList defaultList,
|
||||
@Nullable List<ShelveChangesManager.ShelvedBinaryFilePatch> binaryShelvedPatches) {
|
||||
super(project, true);
|
||||
myCallback = callback;
|
||||
myExecutors = executors;
|
||||
@@ -129,17 +140,18 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
descriptor.setTitle(VcsBundle.message("patch.apply.select.title"));
|
||||
|
||||
myProject = project;
|
||||
myPatches = new LinkedList<FilePatchInProgress>();
|
||||
myPatches = new LinkedList<AbstractFilePatchInProgress>();
|
||||
myRecentPathFileChange = new AtomicReference<FilePresentation>();
|
||||
myChangesTreeList = new MyChangeTreeList(project, Collections.<FilePatchInProgress.PatchChange>emptyList(),
|
||||
myBinaryShelvedPatches = binaryShelvedPatches;
|
||||
myChangesTreeList = new MyChangeTreeList(project, Collections.<AbstractFilePatchInProgress.PatchChange>emptyList(),
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
final NamedTrinity includedTrinity = new NamedTrinity();
|
||||
final Collection<FilePatchInProgress.PatchChange> includedChanges =
|
||||
final Collection<AbstractFilePatchInProgress.PatchChange> includedChanges =
|
||||
myChangesTreeList.getIncludedChanges();
|
||||
final Set<Couple<String>> set = new HashSet<Couple<String>>();
|
||||
for (FilePatchInProgress.PatchChange change : includedChanges) {
|
||||
final TextFilePatch patch = change.getPatchInProgress().getPatch();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : includedChanges) {
|
||||
final FilePatch patch = change.getPatchInProgress().getPatch();
|
||||
final Couple<String> pair = Couple.of(patch.getBeforeName(), patch.getAfterName());
|
||||
if (set.contains(pair)) continue;
|
||||
set.add(pair);
|
||||
@@ -226,8 +238,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
myLoadQueue.queue(myUpdater);
|
||||
}
|
||||
|
||||
private void init(@NotNull List<TextFilePatch> patches, final LocalChangeList localChangeList) {
|
||||
final List<FilePatchInProgress> matchedPatches = new MatchPatchPaths(myProject).execute(patches);
|
||||
private void init(List<? extends FilePatch> patches, final LocalChangeList localChangeList) {
|
||||
final List<AbstractFilePatchInProgress> matchedPatches = new MatchPatchPaths(myProject).execute(patches);
|
||||
//todo add shelved binary patches
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
if (localChangeList != null) {
|
||||
@@ -275,10 +288,10 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void runExecutor(ApplyPatchExecutor executor) {
|
||||
final Collection<FilePatchInProgress> included = getIncluded();
|
||||
final Collection<AbstractFilePatchInProgress> included = getIncluded();
|
||||
if (included.isEmpty()) return;
|
||||
final MultiMap<VirtualFile, FilePatchInProgress> patchGroups = new MultiMap<VirtualFile, FilePatchInProgress>();
|
||||
for (FilePatchInProgress patchInProgress : included) {
|
||||
final MultiMap<VirtualFile, AbstractFilePatchInProgress> patchGroups = new MultiMap<VirtualFile, AbstractFilePatchInProgress>();
|
||||
for (AbstractFilePatchInProgress patchInProgress : included) {
|
||||
patchGroups.putValue(patchInProgress.getBase(), patchInProgress);
|
||||
}
|
||||
final LocalChangeList selected = getSelectedChangeList();
|
||||
@@ -325,9 +338,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
final PatchReader patchReader = loadPatches(filePresentation);
|
||||
if (patchReader == null) return;
|
||||
|
||||
List<TextFilePatch> textPatches = patchReader.getPatches();
|
||||
final List<FilePatchInProgress> matchedPatches =
|
||||
textPatches != null ? new MatchPatchPaths(myProject).execute(textPatches) : ContainerUtil.<FilePatchInProgress>emptyList();
|
||||
List<FilePatch> filePatches = ContainerUtil.<FilePatch>newArrayList(patchReader.getPatches());
|
||||
filePatches.addAll(myBinaryShelvedPatches);
|
||||
final List<AbstractFilePatchInProgress> matchedPatches = new MatchPatchPaths(myProject).execute(filePatches);
|
||||
|
||||
ApplicationManager.getApplication().invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
@@ -394,7 +407,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
private void reset() {
|
||||
myPatches.clear();
|
||||
myChangesTreeList.setChangesToDisplay(Collections.<FilePatchInProgress.PatchChange>emptyList());
|
||||
myChangesTreeList.setChangesToDisplay(Collections.<AbstractFilePatchInProgress.PatchChange>emptyList());
|
||||
myChangesTreeList.repaint();
|
||||
myContainBasedChanges = false;
|
||||
paintBusy(false);
|
||||
@@ -469,40 +482,41 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyChangeTreeList extends ChangesTreeList<FilePatchInProgress.PatchChange> {
|
||||
private static class MyChangeTreeList extends ChangesTreeList<AbstractFilePatchInProgress.PatchChange> {
|
||||
private MyChangeTreeList(Project project,
|
||||
Collection<FilePatchInProgress.PatchChange> initiallyIncluded,
|
||||
Collection<AbstractFilePatchInProgress.PatchChange> initiallyIncluded,
|
||||
@Nullable Runnable inclusionListener,
|
||||
@Nullable ChangeNodeDecorator decorator) {
|
||||
super(project, initiallyIncluded, true, false, inclusionListener, decorator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DefaultTreeModel buildTreeModel(List<FilePatchInProgress.PatchChange> changes, ChangeNodeDecorator changeNodeDecorator) {
|
||||
protected DefaultTreeModel buildTreeModel(List<AbstractFilePatchInProgress.PatchChange> changes,
|
||||
ChangeNodeDecorator changeNodeDecorator) {
|
||||
TreeModelBuilder builder = new TreeModelBuilder(myProject, false);
|
||||
return builder.buildModel(ObjectsConvertor.convert(changes,
|
||||
new Convertor<FilePatchInProgress.PatchChange, Change>() {
|
||||
public Change convert(FilePatchInProgress.PatchChange o) {
|
||||
new Convertor<AbstractFilePatchInProgress.PatchChange, Change>() {
|
||||
public Change convert(AbstractFilePatchInProgress.PatchChange o) {
|
||||
return o;
|
||||
}
|
||||
}), changeNodeDecorator);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<FilePatchInProgress.PatchChange> getSelectedObjects(ChangesBrowserNode<FilePatchInProgress.PatchChange> node) {
|
||||
protected List<AbstractFilePatchInProgress.PatchChange> getSelectedObjects(ChangesBrowserNode<AbstractFilePatchInProgress.PatchChange> node) {
|
||||
final List<Change> under = node.getAllChangesUnder();
|
||||
return ObjectsConvertor.convert(under, new Convertor<Change, FilePatchInProgress.PatchChange>() {
|
||||
public FilePatchInProgress.PatchChange convert(Change o) {
|
||||
return (FilePatchInProgress.PatchChange)o;
|
||||
return ObjectsConvertor.convert(under, new Convertor<Change, AbstractFilePatchInProgress.PatchChange>() {
|
||||
public AbstractFilePatchInProgress.PatchChange convert(Change o) {
|
||||
return (AbstractFilePatchInProgress.PatchChange)o;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected FilePatchInProgress.PatchChange getLeadSelectedObject(ChangesBrowserNode node) {
|
||||
protected AbstractFilePatchInProgress.PatchChange getLeadSelectedObject(ChangesBrowserNode node) {
|
||||
final Object o = node.getUserObject();
|
||||
if (o instanceof FilePatchInProgress.PatchChange) {
|
||||
return (FilePatchInProgress.PatchChange)o;
|
||||
if (o instanceof AbstractFilePatchInProgress.PatchChange) {
|
||||
return (AbstractFilePatchInProgress.PatchChange)o;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -518,10 +532,10 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
if ((selectedChanges.size() >= 1) && (sameBase(selectedChanges))) {
|
||||
final FilePatchInProgress.PatchChange patchChange = selectedChanges.get(0);
|
||||
final FilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
final AbstractFilePatchInProgress.PatchChange patchChange = selectedChanges.get(0);
|
||||
final AbstractFilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
final List<VirtualFile> autoBases = patch.getAutoBasesCopy();
|
||||
if (autoBases.isEmpty() || (autoBases.size() == 1 && autoBases.get(0).equals(patch.getBase()))) {
|
||||
myNewBaseSelector.run();
|
||||
@@ -536,14 +550,14 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
e.getPresentation().setEnabled((selectedChanges.size() >= 1) && (sameBase(selectedChanges)));
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean sameBase(final List<FilePatchInProgress.PatchChange> selectedChanges) {
|
||||
private static boolean sameBase(final List<AbstractFilePatchInProgress.PatchChange> selectedChanges) {
|
||||
VirtualFile base = null;
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
final VirtualFile changeBase = change.getPatchInProgress().getBase();
|
||||
if (base == null) {
|
||||
base = changeBase;
|
||||
@@ -556,9 +570,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
private void updateTree(boolean doInitCheck) {
|
||||
final List<FilePatchInProgress> patchesToSelect = changes2patches(myChangesTreeList.getSelectedChanges());
|
||||
final List<FilePatchInProgress.PatchChange> changes = getAllChanges();
|
||||
final Collection<FilePatchInProgress.PatchChange> included = getIncluded(doInitCheck, changes);
|
||||
final List<AbstractFilePatchInProgress> patchesToSelect = changes2patches(myChangesTreeList.getSelectedChanges());
|
||||
final List<AbstractFilePatchInProgress.PatchChange> changes = getAllChanges();
|
||||
final Collection<AbstractFilePatchInProgress.PatchChange> included = getIncluded(doInitCheck, changes);
|
||||
|
||||
myChangesTreeList.setChangesToDisplay(changes);
|
||||
myChangesTreeList.setIncludedChanges(included);
|
||||
@@ -567,8 +581,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
myChangesTreeList.repaint();
|
||||
if ((!doInitCheck) && patchesToSelect != null) {
|
||||
final List<FilePatchInProgress.PatchChange> toSelect = new ArrayList<FilePatchInProgress.PatchChange>(patchesToSelect.size());
|
||||
for (FilePatchInProgress.PatchChange change : changes) {
|
||||
final List<AbstractFilePatchInProgress.PatchChange> toSelect =
|
||||
new ArrayList<AbstractFilePatchInProgress.PatchChange>(patchesToSelect.size());
|
||||
for (AbstractFilePatchInProgress.PatchChange change : changes) {
|
||||
if (patchesToSelect.contains(change.getPatchInProgress())) {
|
||||
toSelect.add(change);
|
||||
}
|
||||
@@ -577,7 +592,7 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
myContainBasedChanges = false;
|
||||
for (FilePatchInProgress patch : myPatches) {
|
||||
for (AbstractFilePatchInProgress patch : myPatches) {
|
||||
if (patch.baseExistsOrAdded()) {
|
||||
myContainBasedChanges = true;
|
||||
break;
|
||||
@@ -585,17 +600,17 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private List<FilePatchInProgress.PatchChange> getAllChanges() {
|
||||
private List<AbstractFilePatchInProgress.PatchChange> getAllChanges() {
|
||||
return ObjectsConvertor.convert(myPatches,
|
||||
new Convertor<FilePatchInProgress, FilePatchInProgress.PatchChange>() {
|
||||
public FilePatchInProgress.PatchChange convert(FilePatchInProgress o) {
|
||||
new Convertor<AbstractFilePatchInProgress, AbstractFilePatchInProgress.PatchChange>() {
|
||||
public AbstractFilePatchInProgress.PatchChange convert(AbstractFilePatchInProgress o) {
|
||||
return o.getChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void acceptChange(final NamedTrinity trinity, final FilePatchInProgress.PatchChange change) {
|
||||
final FilePatchInProgress patchInProgress = change.getPatchInProgress();
|
||||
private static void acceptChange(final NamedTrinity trinity, final AbstractFilePatchInProgress.PatchChange change) {
|
||||
final AbstractFilePatchInProgress patchInProgress = change.getPatchInProgress();
|
||||
if (FilePatchStatus.ADDED.equals(patchInProgress.getStatus())) {
|
||||
trinity.plusAdded();
|
||||
}
|
||||
@@ -607,16 +622,17 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<FilePatchInProgress.PatchChange> getIncluded(boolean doInitCheck, List<FilePatchInProgress.PatchChange> changes) {
|
||||
private Collection<AbstractFilePatchInProgress.PatchChange> getIncluded(boolean doInitCheck,
|
||||
List<AbstractFilePatchInProgress.PatchChange> changes) {
|
||||
final NamedTrinity totalTrinity = new NamedTrinity();
|
||||
final NamedTrinity includedTrinity = new NamedTrinity();
|
||||
|
||||
final Collection<FilePatchInProgress.PatchChange> included = new LinkedList<FilePatchInProgress.PatchChange>();
|
||||
final Collection<AbstractFilePatchInProgress.PatchChange> included = new LinkedList<AbstractFilePatchInProgress.PatchChange>();
|
||||
if (doInitCheck) {
|
||||
for (FilePatchInProgress.PatchChange change : changes) {
|
||||
for (AbstractFilePatchInProgress.PatchChange change : changes) {
|
||||
acceptChange(totalTrinity, change);
|
||||
final FilePatchInProgress filePatchInProgress = change.getPatchInProgress();
|
||||
if (filePatchInProgress.baseExistsOrAdded()) {
|
||||
final AbstractFilePatchInProgress abstractFilePatchInProgress = change.getPatchInProgress();
|
||||
if (abstractFilePatchInProgress.baseExistsOrAdded()) {
|
||||
acceptChange(includedTrinity, change);
|
||||
included.add(change);
|
||||
}
|
||||
@@ -624,14 +640,14 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
else {
|
||||
// todo maybe written pretty
|
||||
final Collection<FilePatchInProgress.PatchChange> includedNow = myChangesTreeList.getIncludedChanges();
|
||||
final Set<FilePatchInProgress> toBeIncluded = new HashSet<FilePatchInProgress>();
|
||||
for (FilePatchInProgress.PatchChange change : includedNow) {
|
||||
final FilePatchInProgress patch = change.getPatchInProgress();
|
||||
final Collection<AbstractFilePatchInProgress.PatchChange> includedNow = myChangesTreeList.getIncludedChanges();
|
||||
final Set<AbstractFilePatchInProgress> toBeIncluded = new HashSet<AbstractFilePatchInProgress>();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : includedNow) {
|
||||
final AbstractFilePatchInProgress patch = change.getPatchInProgress();
|
||||
toBeIncluded.add(patch);
|
||||
}
|
||||
for (FilePatchInProgress.PatchChange change : changes) {
|
||||
final FilePatchInProgress patch = change.getPatchInProgress();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : changes) {
|
||||
final AbstractFilePatchInProgress patch = change.getPatchInProgress();
|
||||
acceptChange(totalTrinity, change);
|
||||
if (toBeIncluded.contains(patch) && patch.baseExistsOrAdded()) {
|
||||
acceptChange(includedTrinity, change);
|
||||
@@ -653,10 +669,10 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
return;
|
||||
}
|
||||
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
if (selectedChanges.size() >= 1) {
|
||||
for (FilePatchInProgress.PatchChange patchChange : selectedChanges) {
|
||||
final FilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
for (AbstractFilePatchInProgress.PatchChange patchChange : selectedChanges) {
|
||||
final AbstractFilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
patch.setNewBase(selectedFile);
|
||||
}
|
||||
updateTree(false);
|
||||
@@ -664,9 +680,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private static List<FilePatchInProgress> changes2patches(final List<FilePatchInProgress.PatchChange> selectedChanges) {
|
||||
return ObjectsConvertor.convert(selectedChanges, new Convertor<FilePatchInProgress.PatchChange, FilePatchInProgress>() {
|
||||
public FilePatchInProgress convert(FilePatchInProgress.PatchChange o) {
|
||||
private static List<AbstractFilePatchInProgress> changes2patches(final List<AbstractFilePatchInProgress.PatchChange> selectedChanges) {
|
||||
return ObjectsConvertor.convert(selectedChanges, new Convertor<AbstractFilePatchInProgress.PatchChange, AbstractFilePatchInProgress>() {
|
||||
public AbstractFilePatchInProgress convert(AbstractFilePatchInProgress.PatchChange o) {
|
||||
return o.getPatchInProgress();
|
||||
}
|
||||
});
|
||||
@@ -691,10 +707,10 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
myNewBaseSelector.run();
|
||||
return null;
|
||||
}
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
if (selectedChanges.size() >= 1) {
|
||||
for (FilePatchInProgress.PatchChange patchChange : selectedChanges) {
|
||||
final FilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
for (AbstractFilePatchInProgress.PatchChange patchChange : selectedChanges) {
|
||||
final AbstractFilePatchInProgress patch = patchChange.getPatchInProgress();
|
||||
patch.setNewBase(selectedValue);
|
||||
}
|
||||
updateTree(false);
|
||||
@@ -789,11 +805,11 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
private static class MyChangeNodeDecorator implements ChangeNodeDecorator {
|
||||
public void decorate(Change change, SimpleColoredComponent component, boolean isShowFlatten) {
|
||||
if (change instanceof FilePatchInProgress.PatchChange) {
|
||||
final FilePatchInProgress.PatchChange patchChange = (FilePatchInProgress.PatchChange)change;
|
||||
if (change instanceof AbstractFilePatchInProgress.PatchChange) {
|
||||
final AbstractFilePatchInProgress.PatchChange patchChange = (AbstractFilePatchInProgress.PatchChange)change;
|
||||
if (!isShowFlatten) {
|
||||
// add change sub path
|
||||
final TextFilePatch filePatch = patchChange.getPatchInProgress().getPatch();
|
||||
final FilePatch filePatch = patchChange.getPatchInProgress().getPatch();
|
||||
final String patchPath = filePatch.getAfterName() == null ? filePatch.getBeforeName() : filePatch.getAfterName();
|
||||
component.append(" ");
|
||||
component.append("[" + patchPath + "]", SimpleTextAttributes.GRAY_ATTRIBUTES);
|
||||
@@ -817,8 +833,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
|
||||
public List<Pair<String, Stress>> stressPartsOfFileName(final Change change, final String parentPath) {
|
||||
if (change instanceof FilePatchInProgress.PatchChange) {
|
||||
final FilePatchInProgress.PatchChange patchChange = (FilePatchInProgress.PatchChange)change;
|
||||
if (change instanceof AbstractFilePatchInProgress.PatchChange) {
|
||||
final AbstractFilePatchInProgress.PatchChange patchChange = (AbstractFilePatchInProgress.PatchChange)change;
|
||||
final String basePath = patchChange.getPatchInProgress().getBase().getPath();
|
||||
final String basePathCorrected = basePath.trim().replace('/', File.separatorChar);
|
||||
if (parentPath.startsWith(basePathCorrected)) {
|
||||
@@ -833,10 +849,10 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<FilePatchInProgress> getIncluded() {
|
||||
private Collection<AbstractFilePatchInProgress> getIncluded() {
|
||||
return ObjectsConvertor.convert(myChangesTreeList.getIncludedChanges(),
|
||||
new Convertor<FilePatchInProgress.PatchChange, FilePatchInProgress>() {
|
||||
public FilePatchInProgress convert(FilePatchInProgress.PatchChange o) {
|
||||
new Convertor<AbstractFilePatchInProgress.PatchChange, AbstractFilePatchInProgress>() {
|
||||
public AbstractFilePatchInProgress convert(AbstractFilePatchInProgress.PatchChange o) {
|
||||
return o.getPatchInProgress();
|
||||
}
|
||||
});
|
||||
@@ -859,8 +875,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
change.getPatchInProgress().setZero();
|
||||
}
|
||||
updateTree(false);
|
||||
@@ -880,17 +896,17 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (!isEnabled()) return;
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
change.getPatchInProgress().down();
|
||||
}
|
||||
updateTree(false);
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
if (selectedChanges.isEmpty()) return false;
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
if (!change.getPatchInProgress().canDown()) return false;
|
||||
}
|
||||
return true;
|
||||
@@ -910,17 +926,17 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
if (!isEnabled()) return;
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
change.getPatchInProgress().up();
|
||||
}
|
||||
updateTree(false);
|
||||
}
|
||||
|
||||
private boolean isEnabled() {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
if (selectedChanges.isEmpty()) return false;
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
if (!change.getPatchInProgress().canUp()) return false;
|
||||
}
|
||||
return true;
|
||||
@@ -934,8 +950,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (FilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
final List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
for (AbstractFilePatchInProgress.PatchChange change : selectedChanges) {
|
||||
change.getPatchInProgress().reset();
|
||||
}
|
||||
updateTree(false);
|
||||
@@ -961,9 +977,9 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
private void showDiff() {
|
||||
if (ChangeListManager.getInstance(myProject).isFreezedWithNotification(null)) return;
|
||||
if (myPatches.isEmpty() || (!myContainBasedChanges)) return;
|
||||
final List<FilePatchInProgress.PatchChange> changes = getAllChanges();
|
||||
final List<AbstractFilePatchInProgress.PatchChange> changes = getAllChanges();
|
||||
Collections.sort(changes, myMyChangeComparator);
|
||||
List<FilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
List<AbstractFilePatchInProgress.PatchChange> selectedChanges = myChangesTreeList.getSelectedChanges();
|
||||
|
||||
int selectedIdx = 0;
|
||||
final ArrayList<DiffRequestPresentable> diffRequestPresentableList = new ArrayList<DiffRequestPresentable>(changes.size());
|
||||
@@ -971,19 +987,39 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
selectedChanges = changes;
|
||||
}
|
||||
if (!selectedChanges.isEmpty()) {
|
||||
final FilePatchInProgress.PatchChange c = selectedChanges.get(0);
|
||||
for (FilePatchInProgress.PatchChange change : changes) {
|
||||
final FilePatchInProgress patchInProgress = change.getPatchInProgress();
|
||||
final AbstractFilePatchInProgress.PatchChange c = selectedChanges.get(0);
|
||||
for (AbstractFilePatchInProgress.PatchChange change : changes) {
|
||||
final AbstractFilePatchInProgress patchInProgress = change.getPatchInProgress();
|
||||
if (!patchInProgress.baseExistsOrAdded()) continue;
|
||||
final TextFilePatch patch = patchInProgress.getPatch();
|
||||
final String path = patch.getBeforeName() == null ? patch.getAfterName() : patch.getBeforeName();
|
||||
final DiffRequestPresentable diffRequestPresentable =
|
||||
change.createDiffRequestPresentable(myProject, new Getter<CharSequence>() {
|
||||
DiffRequestPresentable diffRequestPresentable;
|
||||
if (patchInProgress instanceof BinaryFilePatchInProgress) {
|
||||
final ShelvedBinaryFile file = ((BinaryFilePatchInProgress)patchInProgress).getPatch().getShelvedBinaryFile();
|
||||
diffRequestPresentable = new DiffRequestPresentableProxy() {
|
||||
@NotNull
|
||||
@Override
|
||||
public CharSequence get() {
|
||||
return myReader.getBaseRevision(myProject, path);
|
||||
public DiffRequestPresentable init() throws VcsException {
|
||||
return new ChangeDiffRequestPresentable(myProject, file.createChange(myProject));
|
||||
}
|
||||
});
|
||||
|
||||
@Override
|
||||
public String getPathPresentation() {
|
||||
final File file1 = new File(VfsUtilCore.virtualToIoFile(patchInProgress.getBase()),
|
||||
file.AFTER_PATH == null ? file.BEFORE_PATH : file.AFTER_PATH);
|
||||
return FileUtil.toSystemDependentName(file1.getPath());
|
||||
}
|
||||
};
|
||||
}
|
||||
else {
|
||||
final FilePatch patch = patchInProgress.getPatch();
|
||||
final String path = patch.getBeforeName() == null ? patch.getAfterName() : patch.getBeforeName();
|
||||
diffRequestPresentable =
|
||||
change.createDiffRequestPresentable(myProject, new Getter<CharSequence>() {
|
||||
@Override
|
||||
public CharSequence get() {
|
||||
return myReader.getBaseRevision(myProject, path);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (diffRequestPresentable != null) {
|
||||
diffRequestPresentableList.add(diffRequestPresentable);
|
||||
}
|
||||
@@ -997,8 +1033,8 @@ public class ApplyPatchDifferentiatedDialog extends DialogWrapper {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyChangeComparator implements Comparator<FilePatchInProgress.PatchChange> {
|
||||
public int compare(FilePatchInProgress.PatchChange o1, FilePatchInProgress.PatchChange o2) {
|
||||
private class MyChangeComparator implements Comparator<AbstractFilePatchInProgress.PatchChange> {
|
||||
public int compare(AbstractFilePatchInProgress.PatchChange o1, AbstractFilePatchInProgress.PatchChange o2) {
|
||||
if (PropertiesComponent.getInstance(myProject).isTrueValue("ChangesBrowser.SHOW_FLATTEN")) {
|
||||
return o1.getPatchInProgress().getIoCurrentBase().getName().compareTo(o2.getPatchInProgress().getIoCurrentBase().getName());
|
||||
}
|
||||
|
||||
+3
-2
@@ -28,9 +28,10 @@ import java.util.Map;
|
||||
* Date: 2/25/11
|
||||
* Time: 5:18 PM
|
||||
*/
|
||||
public interface ApplyPatchExecutor {
|
||||
public interface ApplyPatchExecutor<T extends AbstractFilePatchInProgress> {
|
||||
String getName();
|
||||
void apply(final MultiMap<VirtualFile, FilePatchInProgress> patchGroups,
|
||||
|
||||
void apply(final MultiMap<VirtualFile, T> patchGroups,
|
||||
final LocalChangeList localList,
|
||||
String fileName,
|
||||
TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo);
|
||||
|
||||
@@ -38,7 +38,7 @@ public class AutoMatchIterator {
|
||||
myStrategies.add(new DefaultPatchStrategy(baseDir));
|
||||
}
|
||||
|
||||
public List<FilePatchInProgress> execute(final List<TextFilePatch> list) {
|
||||
public List<TextFilePatchInProgress> execute(final List<TextFilePatch> list) {
|
||||
final List<TextFilePatch> creations = new LinkedList<TextFilePatch>();
|
||||
|
||||
final PatchBaseDirectoryDetector directoryDetector = PatchBaseDirectoryDetector.getInstance(myProject);
|
||||
|
||||
+23
-15
@@ -28,21 +28,24 @@ import java.util.List;
|
||||
|
||||
abstract class AutoMatchStrategy {
|
||||
protected final VirtualFile myBaseDir;
|
||||
protected MultiMap<String,VirtualFile> myFolderDecisions;
|
||||
protected final List<FilePatchInProgress> myResult;
|
||||
protected MultiMap<String, VirtualFile> myFolderDecisions;
|
||||
protected final List<TextFilePatchInProgress> myResult;
|
||||
|
||||
AutoMatchStrategy(final VirtualFile baseDir) {
|
||||
myBaseDir = baseDir;
|
||||
myResult = new LinkedList<FilePatchInProgress>();
|
||||
myResult = new LinkedList<TextFilePatchInProgress>();
|
||||
myFolderDecisions = MultiMap.createSet();
|
||||
}
|
||||
|
||||
public abstract void acceptPatch(TextFilePatch patch, final Collection<VirtualFile> foundByName);
|
||||
|
||||
public abstract void processCreation(TextFilePatch creation);
|
||||
|
||||
public abstract void beforeCreations();
|
||||
|
||||
public abstract boolean succeeded();
|
||||
|
||||
public List<FilePatchInProgress> getResult() {
|
||||
public List<TextFilePatchInProgress> getResult() {
|
||||
return myResult;
|
||||
}
|
||||
|
||||
@@ -65,9 +68,10 @@ abstract class AutoMatchStrategy {
|
||||
protected void processCreationBasedOnFolderDecisions(final TextFilePatch creation) {
|
||||
final Collection<VirtualFile> variants = suggestFolderForCreation(creation);
|
||||
if (variants != null) {
|
||||
myResult.add(new FilePatchInProgress(creation, variants, myBaseDir));
|
||||
} else {
|
||||
myResult.add(new FilePatchInProgress(creation, null, myBaseDir));
|
||||
myResult.add(new TextFilePatchInProgress(creation, variants, myBaseDir));
|
||||
}
|
||||
else {
|
||||
myResult.add(new TextFilePatchInProgress(creation, null, myBaseDir));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +83,7 @@ abstract class AutoMatchStrategy {
|
||||
final Collection<VirtualFile> result = new LinkedList<VirtualFile>();
|
||||
for (VirtualFile vf : in) {
|
||||
final String vfPath = vf.getPath();
|
||||
if ((caseSensitive && vfPath.endsWith(path)) || ((! caseSensitive) && StringUtil.endsWithIgnoreCase(vfPath, path))) {
|
||||
if ((caseSensitive && vfPath.endsWith(path)) || ((!caseSensitive) && StringUtil.endsWithIgnoreCase(vfPath, path))) {
|
||||
result.add(vf);
|
||||
}
|
||||
}
|
||||
@@ -95,28 +99,32 @@ abstract class AutoMatchStrategy {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected FilePatchInProgress processMatch(final TextFilePatch patch, final VirtualFile file) {
|
||||
protected TextFilePatchInProgress processMatch(final TextFilePatch patch, final VirtualFile file) {
|
||||
final String beforeName = patch.getBeforeName();
|
||||
if (beforeName == null) return null;
|
||||
final String[] parts = beforeName.replace('\\', '/').split("/");
|
||||
VirtualFile parent = file.getParent();
|
||||
int idx = parts.length - 2;
|
||||
while ((parent != null) && (idx >= 0)) {
|
||||
if (! parent.getName().equals(parts[idx])) {
|
||||
if (!parent.getName().equals(parts[idx])) {
|
||||
break;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
-- idx;
|
||||
--idx;
|
||||
}
|
||||
if (parent != null) {
|
||||
final FilePatchInProgress result = new FilePatchInProgress(patch, null, myBaseDir);
|
||||
final TextFilePatchInProgress result = new TextFilePatchInProgress(patch, null, myBaseDir);
|
||||
result.setNewBase(parent);
|
||||
int numDown = idx + 1;
|
||||
for (int i = 0; i < numDown; i++) {
|
||||
result.up();
|
||||
}
|
||||
processStipUp(result, numDown);
|
||||
return result;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void processStipUp(AbstractFilePatchInProgress patchInProgress, int num) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
patchInProgress.up();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes.patch;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager.ShelvedBinaryFilePatch;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelvedBinaryContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class BinaryFilePatchInProgress extends AbstractFilePatchInProgress<ShelvedBinaryFilePatch> {
|
||||
|
||||
protected BinaryFilePatchInProgress(ShelvedBinaryFilePatch patch,
|
||||
Collection<VirtualFile> autoBases,
|
||||
VirtualFile baseDir) {
|
||||
super(ShelvedBinaryFilePatch.patchCopy(patch), autoBases, baseDir);
|
||||
}
|
||||
|
||||
@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.getFilePathOnNonLocal(myIoCurrentBase.getAbsolutePath(),
|
||||
false)
|
||||
: detectNewFilePathForMovedOrModified();
|
||||
myNewContentRevision = new ShelvedBinaryContentRevision(newFilePath, myPatch.getShelvedBinaryFile().SHELVED_PATH);
|
||||
}
|
||||
return myNewContentRevision;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -27,9 +27,9 @@ public class DefaultPatchStrategy extends AutoMatchStrategy {
|
||||
|
||||
@Override
|
||||
public void acceptPatch(TextFilePatch patch, Collection<VirtualFile> foundByName) {
|
||||
FilePatchInProgress longest = null;
|
||||
TextFilePatchInProgress longest = null;
|
||||
for (VirtualFile file : foundByName) {
|
||||
final FilePatchInProgress current = processMatch(patch, file);
|
||||
final TextFilePatchInProgress current = processMatch(patch, file);
|
||||
if ((current != null) && ((longest == null) || (longest.getCurrentStrip() > current.getCurrentStrip()))) {
|
||||
longest = current;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public class DefaultPatchStrategy extends AutoMatchStrategy {
|
||||
registerFolderDecision(longest.getPatch().getBeforeName(), longest.getBase());
|
||||
myResult.add(longest);
|
||||
} else {
|
||||
myResult.add(new FilePatchInProgress(patch, null, myBaseDir));
|
||||
myResult.add(new TextFilePatchInProgress(patch, null, myBaseDir));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+4
-4
@@ -48,7 +48,7 @@ import java.util.*;
|
||||
* Date: 2/25/11
|
||||
* Time: 6:21 PM
|
||||
*/
|
||||
public class ImportToShelfExecutor implements ApplyPatchExecutor {
|
||||
public class ImportToShelfExecutor implements ApplyPatchExecutor<TextFilePatchInProgress> {
|
||||
public static final String IMPORT_TO_SHELF = "Import to shelf";
|
||||
private final Project myProject;
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ImportToShelfExecutor implements ApplyPatchExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(final MultiMap<VirtualFile, FilePatchInProgress> patchGroups,
|
||||
public void apply(final MultiMap<VirtualFile, TextFilePatchInProgress> patchGroups,
|
||||
LocalChangeList localList,
|
||||
final String fileName,
|
||||
final TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) {
|
||||
@@ -75,8 +75,8 @@ public class ImportToShelfExecutor implements ApplyPatchExecutor {
|
||||
for (VirtualFile virtualFile : patchGroups.keySet()) {
|
||||
final File ioCurrentBase = new File(virtualFile.getPath());
|
||||
allPatches.addAll(ObjectsConvertor.convert(patchGroups.get(virtualFile),
|
||||
new Convertor<FilePatchInProgress, TextFilePatch>() {
|
||||
public TextFilePatch convert(FilePatchInProgress o) {
|
||||
new Convertor<TextFilePatchInProgress, TextFilePatch>() {
|
||||
public TextFilePatch convert(TextFilePatchInProgress o) {
|
||||
final TextFilePatch was = o.getPatch();
|
||||
was.setBeforeName(FileUtil.toSystemIndependentName(FileUtil.getRelativePath(ioBase,
|
||||
new File(ioCurrentBase, was.getBeforeName()))));
|
||||
|
||||
+3
-6
@@ -17,11 +17,8 @@ package com.intellij.openapi.vcs.changes.patch;
|
||||
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
||||
class IndividualPiecesStrategy extends AutoMatchStrategy {
|
||||
private boolean mySucceeded;
|
||||
@@ -39,9 +36,9 @@ class IndividualPiecesStrategy extends AutoMatchStrategy {
|
||||
final Collection<VirtualFile> variants = filterVariants(patch, foundByName);
|
||||
|
||||
if ((variants != null) && (! variants.isEmpty())) {
|
||||
final FilePatchInProgress filePatchInProgress = new FilePatchInProgress(patch, variants, myBaseDir);
|
||||
myResult.add(filePatchInProgress);
|
||||
registerFolderDecision(patch.getBeforeName(), filePatchInProgress.getBase());
|
||||
final TextFilePatchInProgress textFilePatchInProgress = new TextFilePatchInProgress(patch, variants, myBaseDir);
|
||||
myResult.add(textFilePatchInProgress);
|
||||
registerFolderDecision(patch.getBeforeName(), textFilePatchInProgress.getBase());
|
||||
} else {
|
||||
mySucceeded = false;
|
||||
}
|
||||
|
||||
@@ -16,15 +16,18 @@
|
||||
package com.intellij.openapi.vcs.changes.patch;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
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;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.vcs.ObjectsConvertor;
|
||||
import com.intellij.openapi.vcs.changes.shelf.ShelveChangesManager.ShelvedBinaryFilePatch;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.containers.MultiMap;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -36,6 +39,8 @@ import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static com.intellij.openapi.vcs.changes.patch.AutoMatchStrategy.processStipUp;
|
||||
|
||||
public class MatchPatchPaths {
|
||||
private static final int BIG_FILE_BOUND = 100000;
|
||||
private final Project myProject;
|
||||
@@ -46,34 +51,34 @@ public class MatchPatchPaths {
|
||||
myBaseDir = myProject.getBaseDir();
|
||||
}
|
||||
|
||||
public List<FilePatchInProgress> execute(@NotNull final List<TextFilePatch> list) {
|
||||
public List<AbstractFilePatchInProgress> execute(@NotNull final List<? extends FilePatch> list) {
|
||||
final PatchBaseDirectoryDetector directoryDetector = PatchBaseDirectoryDetector.getInstance(myProject);
|
||||
|
||||
final List<PatchAndVariants> candidates = new ArrayList<PatchAndVariants>(list.size());
|
||||
final List<TextFilePatch> newOrWithoutMatches = new ArrayList<TextFilePatch>();
|
||||
final List<FilePatch> newOrWithoutMatches = new ArrayList<FilePatch>();
|
||||
findCandidates(list, directoryDetector, candidates, newOrWithoutMatches);
|
||||
|
||||
final MultiMap<VirtualFile, FilePatchInProgress> result = new MultiMap<VirtualFile, FilePatchInProgress>();
|
||||
final MultiMap<VirtualFile, AbstractFilePatchInProgress> result = new MultiMap<VirtualFile, AbstractFilePatchInProgress>();
|
||||
// process exact matches: if one, leave and extract. if several - leave only them
|
||||
filterExactMatches(candidates, result);
|
||||
|
||||
// partially check by context
|
||||
selectByContext(candidates, result);
|
||||
selectByContextOrByStrip(candidates, result); // for text only
|
||||
// created or no variants
|
||||
workWithNotExisting(directoryDetector, newOrWithoutMatches, result);
|
||||
return new ArrayList<FilePatchInProgress>(result.values());
|
||||
return new ArrayList<AbstractFilePatchInProgress>(result.values());
|
||||
}
|
||||
|
||||
private void workWithNotExisting(PatchBaseDirectoryDetector directoryDetector,
|
||||
List<TextFilePatch> newOrWithoutMatches,
|
||||
MultiMap<VirtualFile, FilePatchInProgress> result) {
|
||||
for (TextFilePatch patch : newOrWithoutMatches) {
|
||||
private void workWithNotExisting(@NotNull PatchBaseDirectoryDetector directoryDetector,
|
||||
@NotNull List<FilePatch> newOrWithoutMatches,
|
||||
@NotNull MultiMap<VirtualFile, AbstractFilePatchInProgress> result) {
|
||||
for (FilePatch patch : newOrWithoutMatches) {
|
||||
final String[] strings = patch.getAfterName().replace('\\', '/').split("/");
|
||||
Pair<VirtualFile, Integer> best = null;
|
||||
for (int i = strings.length - 2; i >= 0; --i) {
|
||||
final String name = strings[i];
|
||||
final Collection<VirtualFile> files = findFilesFromIndex(directoryDetector, name);
|
||||
if (! files.isEmpty()) {
|
||||
if (!files.isEmpty()) {
|
||||
// check all candidates
|
||||
for (VirtualFile file : files) {
|
||||
Pair<VirtualFile, Integer> pair = compareNamesImpl(strings, file, i);
|
||||
@@ -86,53 +91,44 @@ public class MatchPatchPaths {
|
||||
}
|
||||
}
|
||||
if (best != null) {
|
||||
final FilePatchInProgress patchInProgress = new FilePatchInProgress(patch, null, myBaseDir);
|
||||
patchInProgress.setNewBase(best.getFirst());
|
||||
int numDown = best.getSecond();
|
||||
for (int i = 0; i < numDown; i++) {
|
||||
patchInProgress.up();
|
||||
}
|
||||
final AbstractFilePatchInProgress patchInProgress = createPatchInProgress(patch, best.getFirst());
|
||||
if (patchInProgress == null) break;
|
||||
processStipUp(patchInProgress, best.getSecond());
|
||||
result.putValue(best.getFirst(), patchInProgress);
|
||||
}
|
||||
else {
|
||||
final FilePatchInProgress patchInProgress = new FilePatchInProgress(patch, null, myBaseDir);
|
||||
final AbstractFilePatchInProgress patchInProgress = createPatchInProgress(patch, myBaseDir);
|
||||
if (patchInProgress == null) break;
|
||||
result.putValue(myBaseDir, patchInProgress);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void selectByContext(List<PatchAndVariants> candidates, MultiMap<VirtualFile, FilePatchInProgress> result) {
|
||||
private static void selectByContextOrByStrip(@NotNull List<PatchAndVariants> candidates,
|
||||
@NotNull MultiMap<VirtualFile, AbstractFilePatchInProgress> result) {
|
||||
for (final PatchAndVariants candidate : candidates) {
|
||||
int maxLines = -100;
|
||||
FilePatchInProgress best = null;
|
||||
for (FilePatchInProgress variant : candidate.getVariants()) {
|
||||
final int lines = getMatchingLines(variant);
|
||||
if (lines > maxLines) {
|
||||
maxLines = lines;
|
||||
best = variant;
|
||||
}
|
||||
}
|
||||
putSelected(result, candidate.getVariants(), best);
|
||||
candidate.findAndAddBestVariant(result);
|
||||
}
|
||||
}
|
||||
|
||||
private static void filterExactMatches(List<PatchAndVariants> candidates, MultiMap<VirtualFile, FilePatchInProgress> result) {
|
||||
private static void filterExactMatches(@NotNull List<PatchAndVariants> candidates,
|
||||
@NotNull MultiMap<VirtualFile, AbstractFilePatchInProgress> result) {
|
||||
for (Iterator<PatchAndVariants> iterator = candidates.iterator(); iterator.hasNext(); ) {
|
||||
final PatchAndVariants candidate = iterator.next();
|
||||
if (candidate.getVariants().size() == 1) {
|
||||
final FilePatchInProgress oneCandidate = candidate.getVariants().get(0);
|
||||
final AbstractFilePatchInProgress oneCandidate = candidate.getVariants().get(0);
|
||||
result.putValue(oneCandidate.getBase(), oneCandidate);
|
||||
iterator.remove();
|
||||
}
|
||||
else {
|
||||
final List<FilePatchInProgress> exact = new ArrayList<FilePatchInProgress>(candidate.getVariants().size());
|
||||
for (FilePatchInProgress patch : candidate.getVariants()) {
|
||||
final List<AbstractFilePatchInProgress> exact = new ArrayList<AbstractFilePatchInProgress>(candidate.getVariants().size());
|
||||
for (AbstractFilePatchInProgress patch : candidate.getVariants()) {
|
||||
if (patch.getCurrentStrip() == 0) {
|
||||
exact.add(patch);
|
||||
}
|
||||
}
|
||||
if (exact.size() == 1) {
|
||||
final FilePatchInProgress patchInProgress = exact.get(0);
|
||||
final AbstractFilePatchInProgress patchInProgress = exact.get(0);
|
||||
putSelected(result, candidate.getVariants(), patchInProgress);
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -143,10 +139,10 @@ public class MatchPatchPaths {
|
||||
}
|
||||
}
|
||||
|
||||
private void findCandidates(List<TextFilePatch> list,
|
||||
final PatchBaseDirectoryDetector directoryDetector,
|
||||
List<PatchAndVariants> candidates, List<TextFilePatch> newOrWithoutMatches) {
|
||||
for (final TextFilePatch patch : list) {
|
||||
private void findCandidates(@NotNull List<? extends FilePatch> list,
|
||||
@NotNull final PatchBaseDirectoryDetector directoryDetector,
|
||||
@NotNull List<PatchAndVariants> candidates, @NotNull List<FilePatch> newOrWithoutMatches) {
|
||||
for (final FilePatch patch : list) {
|
||||
final String fileName = patch.getBeforeFileName();
|
||||
if (patch.isNewFile() || (patch.getBeforeName() == null)) {
|
||||
newOrWithoutMatches.add(patch);
|
||||
@@ -164,12 +160,14 @@ public class MatchPatchPaths {
|
||||
newOrWithoutMatches.add(patch);
|
||||
}
|
||||
else {
|
||||
final List<FilePatchInProgress> variants = ObjectsConvertor.convert(files, new Convertor<VirtualFile, FilePatchInProgress>() {
|
||||
@Override
|
||||
public FilePatchInProgress convert(VirtualFile o) {
|
||||
return processMatch(patch, o);
|
||||
}
|
||||
}, ObjectsConvertor.NOT_NULL);
|
||||
//files order is not defined, so get the best variant depends on it, too
|
||||
final List<AbstractFilePatchInProgress> variants =
|
||||
ObjectsConvertor.convert(files, new Convertor<VirtualFile, AbstractFilePatchInProgress>() {
|
||||
@Override
|
||||
public AbstractFilePatchInProgress convert(VirtualFile o) {
|
||||
return processMatch(patch, o);
|
||||
}
|
||||
}, ObjectsConvertor.NOT_NULL);
|
||||
if (variants.isEmpty()) {
|
||||
newOrWithoutMatches.add(patch); // just to be sure
|
||||
}
|
||||
@@ -189,19 +187,19 @@ public class MatchPatchPaths {
|
||||
});
|
||||
}
|
||||
|
||||
private static void putSelected(MultiMap<VirtualFile, FilePatchInProgress> result,
|
||||
final List<FilePatchInProgress> variants,
|
||||
FilePatchInProgress patchInProgress) {
|
||||
patchInProgress.setAutoBases(ObjectsConvertor.convert(variants, new Convertor<FilePatchInProgress, VirtualFile>() {
|
||||
private static void putSelected(@NotNull MultiMap<VirtualFile, AbstractFilePatchInProgress> result,
|
||||
@NotNull final List<AbstractFilePatchInProgress> variants,
|
||||
@NotNull AbstractFilePatchInProgress patchInProgress) {
|
||||
patchInProgress.setAutoBases(ObjectsConvertor.convert(variants, new Convertor<AbstractFilePatchInProgress, VirtualFile>() {
|
||||
@Override
|
||||
public VirtualFile convert(FilePatchInProgress o) {
|
||||
public VirtualFile convert(AbstractFilePatchInProgress o) {
|
||||
return o.getBase();
|
||||
}
|
||||
}, ObjectsConvertor.NOT_NULL));
|
||||
result.putValue(patchInProgress.getBase(), patchInProgress);
|
||||
}
|
||||
|
||||
private static int getMatchingLines(final FilePatchInProgress patch) {
|
||||
private static int getMatchingLines(final AbstractFilePatchInProgress<TextFilePatch> patch) {
|
||||
final VirtualFile base = patch.getCurrentBase();
|
||||
if (base == null) return -1;
|
||||
String text;
|
||||
@@ -221,15 +219,43 @@ public class MatchPatchPaths {
|
||||
}
|
||||
|
||||
private static class PatchAndVariants {
|
||||
private final List<FilePatchInProgress> myVariants;
|
||||
@NotNull private final List<AbstractFilePatchInProgress> myVariants;
|
||||
|
||||
private PatchAndVariants(List<FilePatchInProgress> variants) {
|
||||
private PatchAndVariants(@NotNull List<AbstractFilePatchInProgress> variants) {
|
||||
myVariants = variants;
|
||||
}
|
||||
|
||||
public List<FilePatchInProgress> getVariants() {
|
||||
@NotNull
|
||||
public List<AbstractFilePatchInProgress> getVariants() {
|
||||
return myVariants;
|
||||
}
|
||||
|
||||
public void findAndAddBestVariant(@NotNull MultiMap<VirtualFile, AbstractFilePatchInProgress> result) {
|
||||
AbstractFilePatchInProgress best = ContainerUtil.getFirstItem(myVariants);
|
||||
if (best == null) return;
|
||||
if (best instanceof TextFilePatchInProgress) {
|
||||
//only for text patches
|
||||
int maxLines = -100;
|
||||
for (AbstractFilePatchInProgress variant : myVariants) {
|
||||
TextFilePatchInProgress textFilePAch = (TextFilePatchInProgress)variant;
|
||||
final int lines = getMatchingLines(textFilePAch);
|
||||
if (lines > maxLines) {
|
||||
maxLines = lines;
|
||||
best = textFilePAch;
|
||||
}
|
||||
}
|
||||
putSelected(result, myVariants, best);
|
||||
}
|
||||
else {
|
||||
int stripCounter = Integer.MAX_VALUE;
|
||||
for (AbstractFilePatchInProgress variant : myVariants) {
|
||||
if (variant.getCurrentStrip() < stripCounter) {
|
||||
best = variant;
|
||||
}
|
||||
}
|
||||
putSelected(result, myVariants, best);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Pair<VirtualFile, Integer> compareNames(final String beforeName, final VirtualFile file) {
|
||||
@@ -250,31 +276,23 @@ public class MatchPatchPaths {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private FilePatchInProgress processMatch(final TextFilePatch patch, final VirtualFile file) {
|
||||
private static AbstractFilePatchInProgress processMatch(final FilePatch patch, final VirtualFile file) {
|
||||
final String beforeName = patch.getBeforeName();
|
||||
/*if (beforeName == null) return null;
|
||||
final String[] parts = beforeName.replace('\\', '/').split("/");
|
||||
VirtualFile parent = file.getParent();
|
||||
int idx = parts.length - 2;
|
||||
while ((parent != null) && (idx >= 0)) {
|
||||
if (! parent.getName().equals(parts[idx])) {
|
||||
break;
|
||||
}
|
||||
parent = parent.getParent();
|
||||
-- idx;
|
||||
}*/
|
||||
final Pair<VirtualFile, Integer> pair = compareNames(beforeName, file);
|
||||
if (pair == null) return null;
|
||||
final VirtualFile parent = pair.getFirst();
|
||||
if (parent != null) {
|
||||
final FilePatchInProgress result = new FilePatchInProgress(patch, null, myBaseDir);
|
||||
result.setNewBase(parent);
|
||||
int numDown = pair.getSecond();
|
||||
for (int i = 0; i < numDown; i++) {
|
||||
result.up();
|
||||
}
|
||||
return result;
|
||||
if (parent == null) return null;
|
||||
final AbstractFilePatchInProgress result = createPatchInProgress(patch, parent);
|
||||
if (result != null) {
|
||||
processStipUp(result, pair.getSecond());
|
||||
}
|
||||
return null;
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static AbstractFilePatchInProgress createPatchInProgress(@NotNull FilePatch patch, @NotNull VirtualFile dir) {
|
||||
return patch instanceof TextFilePatch ? new TextFilePatchInProgress((TextFilePatch)patch, null, dir) :
|
||||
patch instanceof ShelvedBinaryFilePatch ? new BinaryFilePatchInProgress((ShelvedBinaryFilePatch)patch, null, dir)
|
||||
: null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,13 +24,13 @@ import java.util.*;
|
||||
|
||||
class OneBaseStrategy extends AutoMatchStrategy {
|
||||
private boolean mySucceeded;
|
||||
private final MultiMap<VirtualFile, FilePatchInProgress> myVariants;
|
||||
private final MultiMap<VirtualFile, TextFilePatchInProgress> myVariants;
|
||||
private boolean myCheckExistingVariants;
|
||||
|
||||
OneBaseStrategy(VirtualFile baseDir) {
|
||||
super(baseDir);
|
||||
mySucceeded = true;
|
||||
myVariants = new MultiMap<VirtualFile, FilePatchInProgress>();
|
||||
myVariants = new MultiMap<VirtualFile, TextFilePatchInProgress>();
|
||||
myCheckExistingVariants = false;
|
||||
}
|
||||
|
||||
@@ -42,15 +42,15 @@ class OneBaseStrategy extends AutoMatchStrategy {
|
||||
mySucceeded = false;
|
||||
return;
|
||||
}
|
||||
final List<FilePatchInProgress> results = new LinkedList<FilePatchInProgress>();
|
||||
final List<TextFilePatchInProgress> results = new LinkedList<TextFilePatchInProgress>();
|
||||
final Set<VirtualFile> keysToRemove = new HashSet<VirtualFile>(myVariants.keySet());
|
||||
for (VirtualFile file : foundByName) {
|
||||
final FilePatchInProgress filePatchInProgress = processMatch(patch, file);
|
||||
if (filePatchInProgress != null) {
|
||||
final VirtualFile base = filePatchInProgress.getBase();
|
||||
final TextFilePatchInProgress textFilePatchInProgress = processMatch(patch, file);
|
||||
if (textFilePatchInProgress != null) {
|
||||
final VirtualFile base = textFilePatchInProgress.getBase();
|
||||
if (myCheckExistingVariants && (! myVariants.containsKey(base))) continue;
|
||||
keysToRemove.remove(base);
|
||||
results.add(filePatchInProgress);
|
||||
results.add(textFilePatchInProgress);
|
||||
}
|
||||
}
|
||||
if (myCheckExistingVariants) {
|
||||
@@ -63,9 +63,9 @@ class OneBaseStrategy extends AutoMatchStrategy {
|
||||
}
|
||||
}
|
||||
final Collection<VirtualFile> exactMatch = filterVariants(patch, foundByName);
|
||||
for (FilePatchInProgress filePatchInProgress : results) {
|
||||
filePatchInProgress.setAutoBases(exactMatch);
|
||||
myVariants.putValue(filePatchInProgress.getBase(), filePatchInProgress);
|
||||
for (TextFilePatchInProgress textFilePatchInProgress : results) {
|
||||
textFilePatchInProgress.setAutoBases(exactMatch);
|
||||
myVariants.putValue(textFilePatchInProgress.getBase(), textFilePatchInProgress);
|
||||
}
|
||||
myCheckExistingVariants = true;
|
||||
}
|
||||
@@ -73,13 +73,13 @@ class OneBaseStrategy extends AutoMatchStrategy {
|
||||
@Override
|
||||
public void processCreation(TextFilePatch creation) {
|
||||
if (! mySucceeded) return;
|
||||
final FilePatchInProgress filePatchInProgress;
|
||||
final TextFilePatchInProgress textFilePatchInProgress;
|
||||
if (myVariants.isEmpty()) {
|
||||
filePatchInProgress = new FilePatchInProgress(creation, null, myBaseDir);
|
||||
textFilePatchInProgress = new TextFilePatchInProgress(creation, null, myBaseDir);
|
||||
} else {
|
||||
filePatchInProgress = new FilePatchInProgress(creation, null, myVariants.keySet().iterator().next());
|
||||
textFilePatchInProgress = new TextFilePatchInProgress(creation, null, myVariants.keySet().iterator().next());
|
||||
}
|
||||
myResult.add(filePatchInProgress);
|
||||
myResult.add(textFilePatchInProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,12 +91,12 @@ class OneBaseStrategy extends AutoMatchStrategy {
|
||||
public void beforeCreations() {
|
||||
if (! mySucceeded) return;
|
||||
if (myVariants.size() > 1) {
|
||||
Pair<VirtualFile, Collection<FilePatchInProgress>> privilegedSurvivor = null;
|
||||
Pair<VirtualFile, Collection<TextFilePatchInProgress>> privilegedSurvivor = null;
|
||||
for (VirtualFile file : myVariants.keySet()) {
|
||||
final Collection<FilePatchInProgress> patches = myVariants.get(file);
|
||||
final Collection<TextFilePatchInProgress> patches = myVariants.get(file);
|
||||
int numStrip = -1;
|
||||
boolean sameStrip = true;
|
||||
for (FilePatchInProgress patch : patches) {
|
||||
for (TextFilePatchInProgress patch : patches) {
|
||||
if (numStrip == -1) {
|
||||
numStrip = patch.getCurrentStrip();
|
||||
} else {
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
package com.intellij.openapi.vcs.changes.patch;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.diff.impl.patch.TextFilePatch;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.SimpleContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.actions.DiffRequestPresentable;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
public class TextFilePatchInProgress extends AbstractFilePatchInProgress<TextFilePatch> {
|
||||
|
||||
protected TextFilePatchInProgress(TextFilePatch patch,
|
||||
Collection<VirtualFile> autoBases,
|
||||
VirtualFile baseDir) {
|
||||
super(patch.pathsOnlyCopy(), autoBases, baseDir);
|
||||
}
|
||||
|
||||
public ContentRevision getNewContentRevision() {
|
||||
if (FilePatchStatus.DELETED.equals(myStatus)) return null;
|
||||
|
||||
if (myNewContentRevision == null) {
|
||||
myConflicts = null;
|
||||
if (FilePatchStatus.ADDED.equals(myStatus)) {
|
||||
final FilePath newFilePath = VcsUtil.getFilePathOnNonLocal(myIoCurrentBase.getAbsolutePath(), false);
|
||||
final String content = myPatch.getNewFileText();
|
||||
myNewContentRevision = new SimpleContentRevision(content, newFilePath, myPatch.getAfterVersionId());
|
||||
}
|
||||
else {
|
||||
final FilePath newFilePath = detectNewFilePathForMovedOrModified();
|
||||
myNewContentRevision = new LazyPatchContentRevision(myCurrentBase, newFilePath, myPatch.getAfterVersionId(), myPatch);
|
||||
if (myCurrentBase != null) {
|
||||
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
|
||||
public void run() {
|
||||
((LazyPatchContentRevision)myNewContentRevision).getContent();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
return myNewContentRevision;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected DiffRequestPresentable diffRequestForConflictingChanges(@NotNull final Project project,
|
||||
@NotNull PatchChange change,
|
||||
@NotNull final Getter<CharSequence> baseContents) {
|
||||
final Getter<ApplyPatchForBaseRevisionTexts> revisionTextsGetter = new Getter<ApplyPatchForBaseRevisionTexts>() {
|
||||
@Override
|
||||
public ApplyPatchForBaseRevisionTexts get() {
|
||||
final VirtualFile currentBase = getCurrentBase();
|
||||
return ApplyPatchForBaseRevisionTexts.create(project, currentBase,
|
||||
VcsUtil.getFilePath(currentBase),
|
||||
getPatch(), baseContents);
|
||||
}
|
||||
};
|
||||
return new MergedDiffRequestPresentable(project, revisionTextsGetter,
|
||||
getCurrentBase(), getPatch().getAfterVersionId());
|
||||
}
|
||||
}
|
||||
+71
-50
@@ -119,16 +119,16 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
final String showRecycled = element.getAttributeValue(ATTRIBUTE_SHOW_RECYCLED);
|
||||
if (showRecycled != null) {
|
||||
myShowRecycled = Boolean.parseBoolean(showRecycled);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myShowRecycled = true;
|
||||
}
|
||||
|
||||
readExternal(element, myShelvedChangeLists, myRecycledShelvedChangeLists);
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static void readExternal(final Element element, final List<ShelvedChangeList> changes, final List<ShelvedChangeList> recycled) throws InvalidDataException {
|
||||
public static void readExternal(final Element element, final List<ShelvedChangeList> changes, final List<ShelvedChangeList> recycled)
|
||||
throws InvalidDataException {
|
||||
changes.addAll(ShelvedChangeList.readChanges(element, false, true));
|
||||
|
||||
recycled.addAll(ShelvedChangeList.readChanges(element, true, true));
|
||||
@@ -138,17 +138,17 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
public void writeExternal(Element element) throws WriteExternalException {
|
||||
element.setAttribute(ATTRIBUTE_SHOW_RECYCLED, Boolean.toString(myShowRecycled));
|
||||
ShelvedChangeList.writeChanges(myShelvedChangeLists, myRecycledShelvedChangeLists, element);
|
||||
|
||||
}
|
||||
|
||||
public List<ShelvedChangeList> getShelvedChangeLists() {
|
||||
return Collections.unmodifiableList(myShelvedChangeLists);
|
||||
}
|
||||
|
||||
public ShelvedChangeList shelveChanges(final Collection<Change> changes, final String commitMessage, final boolean rollback) throws IOException, VcsException {
|
||||
public ShelvedChangeList shelveChanges(final Collection<Change> changes, final String commitMessage, final boolean rollback)
|
||||
throws IOException, VcsException {
|
||||
final List<Change> textChanges = new ArrayList<Change>();
|
||||
final List<ShelvedBinaryFile> binaryFiles = new ArrayList<ShelvedBinaryFile>();
|
||||
for(Change change: changes) {
|
||||
for (Change change : changes) {
|
||||
if (ChangesUtil.getFilePath(change).isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
@@ -164,19 +164,20 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
try {
|
||||
File patchPath = getPatchPath(commitMessage);
|
||||
ProgressManager.checkCanceled();
|
||||
final List<FilePatch> patches = IdeaTextPatchBuilder.buildPatch(myProject, textChanges, myProject.getBaseDir().getPresentableUrl(), false);
|
||||
final List<FilePatch> patches =
|
||||
IdeaTextPatchBuilder.buildPatch(myProject, textChanges, myProject.getBaseDir().getPresentableUrl(), false);
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
CommitContext commitContext = new CommitContext();
|
||||
baseRevisionsOfDvcsIntoContext(textChanges, commitContext);
|
||||
myFileProcessor.savePathFile(
|
||||
new CompoundShelfFileProcessor.ContentProvider(){
|
||||
@Override
|
||||
public void writeContentTo(final Writer writer, CommitContext commitContext) throws IOException {
|
||||
UnifiedDiffWriter.write(myProject, patches, writer, "\n", commitContext);
|
||||
}
|
||||
},
|
||||
patchPath, commitContext);
|
||||
new CompoundShelfFileProcessor.ContentProvider() {
|
||||
@Override
|
||||
public void writeContentTo(final Writer writer, CommitContext commitContext) throws IOException {
|
||||
UnifiedDiffWriter.write(myProject, patches, writer, "\n", commitContext);
|
||||
}
|
||||
},
|
||||
patchPath, commitContext);
|
||||
|
||||
changeList = new ShelvedChangeList(patchPath.toString(), commitMessage.replace('\n', ' '), binaryFiles);
|
||||
myShelvedChangeLists.add(changeList);
|
||||
@@ -215,22 +216,25 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
}
|
||||
|
||||
public ShelvedChangeList importFilePatches(final String fileName, final List<FilePatch> patches, final PatchEP[] patchTransitExtensions) throws IOException {
|
||||
public ShelvedChangeList importFilePatches(final String fileName, final List<FilePatch> patches, final PatchEP[] patchTransitExtensions)
|
||||
throws IOException {
|
||||
try {
|
||||
final File patchPath = getPatchPath(fileName);
|
||||
myFileProcessor.savePathFile(
|
||||
new CompoundShelfFileProcessor.ContentProvider(){
|
||||
@Override
|
||||
public void writeContentTo(final Writer writer, CommitContext commitContext) throws IOException {
|
||||
UnifiedDiffWriter.write(myProject, patches, writer, "\n", patchTransitExtensions, commitContext);
|
||||
}
|
||||
},
|
||||
patchPath, new CommitContext());
|
||||
new CompoundShelfFileProcessor.ContentProvider() {
|
||||
@Override
|
||||
public void writeContentTo(final Writer writer, CommitContext commitContext) throws IOException {
|
||||
UnifiedDiffWriter.write(myProject, patches, writer, "\n", patchTransitExtensions, commitContext);
|
||||
}
|
||||
},
|
||||
patchPath, new CommitContext());
|
||||
|
||||
final ShelvedChangeList changeList = new ShelvedChangeList(patchPath.toString(), fileName.replace('\n', ' '), new SmartList<ShelvedBinaryFile>());
|
||||
final ShelvedChangeList changeList =
|
||||
new ShelvedChangeList(patchPath.toString(), fileName.replace('\n', ' '), new SmartList<ShelvedBinaryFile>());
|
||||
myShelvedChangeLists.add(changeList);
|
||||
return changeList;
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
notifyStateChanged();
|
||||
}
|
||||
}
|
||||
@@ -239,7 +243,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
final List<VirtualFile> result = new ArrayList<VirtualFile>();
|
||||
|
||||
final LinkedList<VirtualFile> filesQueue = new LinkedList<VirtualFile>(files);
|
||||
while (! filesQueue.isEmpty()) {
|
||||
while (!filesQueue.isEmpty()) {
|
||||
ProgressManager.checkCanceled();
|
||||
final VirtualFile file = filesQueue.removeFirst();
|
||||
if (file.isDirectory()) {
|
||||
@@ -267,7 +271,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
file.getTimeStamp());
|
||||
try {
|
||||
final List<TextFilePatch> patchesList = loadPatches(myProject, file.getPath(), new CommitContext());
|
||||
if (! patchesList.isEmpty()) {
|
||||
if (!patchesList.isEmpty()) {
|
||||
FileUtil.copy(new File(file.getPath()), patchPath);
|
||||
// add only if ok to read patch
|
||||
myShelvedChangeLists.add(list);
|
||||
@@ -281,7 +285,8 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
exceptionConsumer.consume(new VcsException(e));
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
}
|
||||
finally {
|
||||
notifyStateChanged();
|
||||
}
|
||||
return result;
|
||||
@@ -321,7 +326,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
|
||||
return suggestPatchName(myProject, commitMessage.length() > PatchNameChecker.MAX ? commitMessage.substring(0, PatchNameChecker.MAX) :
|
||||
commitMessage, file, VcsConfiguration.PATCH);
|
||||
commitMessage, file, VcsConfiguration.PATCH);
|
||||
}
|
||||
|
||||
public static File suggestPatchName(Project project, final String commitMessage, final File file, String extension) {
|
||||
@@ -334,9 +339,9 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
while (true) {
|
||||
final File nonexistentFile = FileUtil.findSequentNonexistentFile(file, defaultPath,
|
||||
extension == null
|
||||
? VcsConfiguration.getInstance(project).getPatchFileExtension()
|
||||
: extension);
|
||||
extension == null
|
||||
? VcsConfiguration.getInstance(project).getPatchFileExtension()
|
||||
: extension);
|
||||
if (nonexistentFile.getName().length() >= PatchNameChecker.MAX) {
|
||||
defaultPath = defaultPath.substring(0, defaultPath.length() - 1);
|
||||
continue;
|
||||
@@ -346,7 +351,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
|
||||
public void unshelveChangeList(final ShelvedChangeList changeList, @Nullable final List<ShelvedChange> changes,
|
||||
@Nullable final List<ShelvedBinaryFile> binaryFiles, final LocalChangeList targetChangeList) {
|
||||
@Nullable final List<ShelvedBinaryFile> binaryFiles, final LocalChangeList targetChangeList) {
|
||||
unshelveChangeList(changeList, changes, binaryFiles, targetChangeList, true);
|
||||
}
|
||||
|
||||
@@ -405,8 +410,10 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
|
||||
final BinaryPatchApplier binaryPatchApplier = new BinaryPatchApplier();
|
||||
final PatchApplier<ShelvedBinaryFilePatch> patchApplier = new PatchApplier<ShelvedBinaryFilePatch>(myProject, myProject.getBaseDir(),
|
||||
patches, targetChangeList, binaryPatchApplier, commitContext, reverse, leftConflictTitle, rightConflictTitle);
|
||||
final PatchApplier<ShelvedBinaryFilePatch> patchApplier =
|
||||
new PatchApplier<ShelvedBinaryFilePatch>(myProject, myProject.getBaseDir(),
|
||||
patches, targetChangeList, binaryPatchApplier, commitContext, reverse, leftConflictTitle,
|
||||
rightConflictTitle);
|
||||
patchApplier.setIsSystemOperation(systemOperation);
|
||||
|
||||
// after patch applier part
|
||||
@@ -429,8 +436,12 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
});
|
||||
}
|
||||
|
||||
private static List<TextFilePatch> loadTextPatches(final Project project, final ShelvedChangeList changeList, final List<ShelvedChange> changes, final List<FilePatch> remainingPatches, final CommitContext commitContext)
|
||||
throws IOException, PatchSyntaxException {
|
||||
private static List<TextFilePatch> loadTextPatches(final Project project,
|
||||
final ShelvedChangeList changeList,
|
||||
final List<ShelvedChange> changes,
|
||||
final List<FilePatch> remainingPatches,
|
||||
final CommitContext commitContext)
|
||||
throws IOException, PatchSyntaxException {
|
||||
final List<TextFilePatch> textFilePatches = loadPatches(project, changeList.PATH, commitContext);
|
||||
|
||||
if (changes != null) {
|
||||
@@ -478,10 +489,11 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
return new ArrayList<ShelvedBinaryFile>(changeList.getBinaryFiles());
|
||||
}
|
||||
ArrayList<ShelvedBinaryFile> result = new ArrayList<ShelvedBinaryFile>();
|
||||
for(ShelvedBinaryFile file: changeList.getBinaryFiles()) {
|
||||
for (ShelvedBinaryFile file : changeList.getBinaryFiles()) {
|
||||
if (binaryFiles.contains(file)) {
|
||||
result.add(file);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
remainingBinaries.add(file);
|
||||
}
|
||||
}
|
||||
@@ -516,7 +528,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
|
||||
private static boolean needUnshelve(final FilePatch patch, final List<ShelvedChange> changes) {
|
||||
for(ShelvedChange change: changes) {
|
||||
for (ShelvedChange change : changes) {
|
||||
if (Comparing.equal(patch.getBeforeName(), change.getBeforePath())) {
|
||||
return true;
|
||||
}
|
||||
@@ -586,7 +598,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
private void recycleChangeList(final ShelvedChangeList listCopy, final ShelvedChangeList newList) {
|
||||
if (newList != null) {
|
||||
for (Iterator<ShelvedBinaryFile> shelvedChangeListIterator = listCopy.getBinaryFiles().iterator();
|
||||
shelvedChangeListIterator.hasNext();) {
|
||||
shelvedChangeListIterator.hasNext(); ) {
|
||||
final ShelvedBinaryFile binaryFile = shelvedChangeListIterator.next();
|
||||
for (ShelvedBinaryFile newBinary : newList.getBinaryFiles()) {
|
||||
if (Comparing.equal(newBinary.BEFORE_PATH, binaryFile.BEFORE_PATH)
|
||||
@@ -595,7 +607,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
}
|
||||
}
|
||||
for (Iterator<ShelvedChange> iterator = listCopy.getChanges(myProject).iterator(); iterator.hasNext();) {
|
||||
for (Iterator<ShelvedChange> iterator = listCopy.getChanges(myProject).iterator(); iterator.hasNext(); ) {
|
||||
final ShelvedChange change = iterator.next();
|
||||
for (ShelvedChange newChange : newList.getChanges(myProject)) {
|
||||
if (Comparing.equal(change.getBeforePath(), newChange.getBeforePath()) &&
|
||||
@@ -624,7 +636,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
}
|
||||
}
|
||||
|
||||
if (! listCopy.getBinaryFiles().isEmpty() || ! listCopy.getChanges(myProject).isEmpty()) {
|
||||
if (!listCopy.getBinaryFiles().isEmpty() || !listCopy.getChanges(myProject).isEmpty()) {
|
||||
listCopy.setRecycled(true);
|
||||
myRecycledShelvedChangeLists.add(listCopy);
|
||||
notifyStateChanged();
|
||||
@@ -639,9 +651,10 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
|
||||
public void deleteChangeList(final ShelvedChangeList changeList) {
|
||||
deleteListImpl(changeList);
|
||||
if (! changeList.isRecycled()) {
|
||||
if (!changeList.isRecycled()) {
|
||||
myShelvedChangeLists.remove(changeList);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
myRecycledShelvedChangeLists.remove(changeList);
|
||||
}
|
||||
notifyStateChanged();
|
||||
@@ -651,7 +664,7 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
File file = new File(changeList.PATH);
|
||||
myFileProcessor.delete(file.getName());
|
||||
|
||||
for(ShelvedBinaryFile binaryFile: changeList.getBinaryFiles()) {
|
||||
for (ShelvedBinaryFile binaryFile : changeList.getBinaryFiles()) {
|
||||
final String path = binaryFile.SHELVED_PATH;
|
||||
if (path != null) {
|
||||
File binFile = new File(path);
|
||||
@@ -701,22 +714,30 @@ public class ShelveChangesManager extends AbstractProjectComponent implements JD
|
||||
setAfterName(myShelvedBinaryFile.AFTER_PATH);
|
||||
}
|
||||
|
||||
public static ShelvedBinaryFilePatch patchCopy(@NotNull final ShelvedBinaryFilePatch patch) {
|
||||
return new ShelvedBinaryFilePatch(patch.getShelvedBinaryFile());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBeforeFileName() {
|
||||
String[] pathNameComponents = myShelvedBinaryFile.BEFORE_PATH.replace(File.separatorChar, '/').split("/");
|
||||
return pathNameComponents [pathNameComponents.length-1];
|
||||
return getFileName(myShelvedBinaryFile.BEFORE_PATH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAfterFileName() {
|
||||
String[] pathNameComponents = myShelvedBinaryFile.AFTER_PATH.replace(File.separatorChar, '/').split("/");
|
||||
return pathNameComponents [pathNameComponents.length-1];
|
||||
return getFileName(myShelvedBinaryFile.AFTER_PATH);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getFileName(String filePath) {
|
||||
return filePath != null ? PathUtil.getFileName(filePath) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNewFile() {
|
||||
return myShelvedBinaryFile.BEFORE_PATH == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDeletedFile() {
|
||||
return myShelvedBinaryFile.AFTER_PATH == null;
|
||||
|
||||
+13
-5
@@ -28,9 +28,12 @@ import com.intellij.openapi.vcs.changes.patch.ApplyPatchMode;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author irengrig
|
||||
@@ -46,17 +49,22 @@ public class UnshelveWithDialogAction extends DumbAwareAction {
|
||||
|
||||
FileDocumentManager.getInstance().saveAllDocuments();
|
||||
|
||||
final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(changeLists[0].PATH));
|
||||
ShelvedChangeList changeList = changeLists[0];
|
||||
final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(changeList.PATH));
|
||||
if (virtualFile == null) {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(project, "Can not find path file", MessageType.ERROR);
|
||||
return;
|
||||
}
|
||||
if (! changeLists[0].getBinaryFiles().isEmpty()) {
|
||||
VcsBalloonProblemNotifier.showOverChangesView(project, "Binary file(s) would be skipped.", MessageType.WARNING);
|
||||
}
|
||||
List<ShelveChangesManager.ShelvedBinaryFilePatch> binaryShelvedPatches =
|
||||
ContainerUtil.map(changeList.getBinaryFiles(), new Function<ShelvedBinaryFile, ShelveChangesManager.ShelvedBinaryFilePatch>() {
|
||||
@Override
|
||||
public ShelveChangesManager.ShelvedBinaryFilePatch fun(ShelvedBinaryFile file) {
|
||||
return new ShelveChangesManager.ShelvedBinaryFilePatch(file);
|
||||
}
|
||||
});
|
||||
final ApplyPatchDifferentiatedDialog dialog =
|
||||
new ApplyPatchDifferentiatedDialog(project, new ApplyPatchDefaultExecutor(project), Collections.<ApplyPatchExecutor>emptyList(),
|
||||
ApplyPatchMode.UNSHELVE, virtualFile);
|
||||
ApplyPatchMode.UNSHELVE, virtualFile, binaryShelvedPatches);
|
||||
dialog.setHelpId("reference.dialogs.vcs.unshelve");
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
+6
-6
@@ -33,8 +33,8 @@ import com.intellij.openapi.vcs.changes.CommitContext;
|
||||
import com.intellij.openapi.vcs.changes.LocalChangeList;
|
||||
import com.intellij.openapi.vcs.changes.TransparentlyFailedValueI;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor;
|
||||
import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress;
|
||||
import com.intellij.openapi.vcs.changes.patch.PatchWriter;
|
||||
import com.intellij.openapi.vcs.changes.patch.TextFilePatchInProgress;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -55,7 +55,7 @@ import java.util.Map;
|
||||
* Date: 5/17/12
|
||||
* Time: 6:02 PM
|
||||
*/
|
||||
public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor {
|
||||
public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor<TextFilePatchInProgress> {
|
||||
private static final Logger LOG = Logger.getInstance(ApplyPatchSaveToFileExecutor.class);
|
||||
|
||||
private final Project myProject;
|
||||
@@ -72,7 +72,7 @@ public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(MultiMap<VirtualFile, FilePatchInProgress> patchGroups,
|
||||
public void apply(MultiMap<VirtualFile, TextFilePatchInProgress> patchGroups,
|
||||
LocalChangeList localList,
|
||||
String fileName,
|
||||
TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) {
|
||||
@@ -101,17 +101,17 @@ public class ApplyPatchSaveToFileExecutor implements ApplyPatchExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<FilePatch> patchGroupsToOneGroup(MultiMap<VirtualFile, FilePatchInProgress> patchGroups, VirtualFile baseDir)
|
||||
public static List<FilePatch> patchGroupsToOneGroup(MultiMap<VirtualFile, TextFilePatchInProgress> patchGroups, VirtualFile baseDir)
|
||||
throws IOException {
|
||||
final List<FilePatch> textPatches = new ArrayList<FilePatch>();
|
||||
final String baseDirPath = baseDir.getPath();
|
||||
|
||||
for (Map.Entry<VirtualFile, Collection<FilePatchInProgress>> entry : patchGroups.entrySet()) {
|
||||
for (Map.Entry<VirtualFile, Collection<TextFilePatchInProgress>> entry : patchGroups.entrySet()) {
|
||||
final VirtualFile vf = entry.getKey();
|
||||
final String currBasePath = vf.getPath();
|
||||
final String relativePath = VfsUtilCore.getRelativePath(vf, baseDir, '/');
|
||||
final boolean toConvert = !StringUtil.isEmptyOrSpaces(relativePath) && !".".equals(relativePath);
|
||||
for (FilePatchInProgress patchInProgress : entry.getValue()) {
|
||||
for (TextFilePatchInProgress patchInProgress : entry.getValue()) {
|
||||
final TextFilePatch patch = patchInProgress.getPatch();
|
||||
if (toConvert) {
|
||||
//correct paths
|
||||
|
||||
+3
-3
@@ -35,7 +35,7 @@ import com.intellij.openapi.vcs.changes.committed.CommittedChangesTreeBrowser;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchDifferentiatedDialog;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchExecutor;
|
||||
import com.intellij.openapi.vcs.changes.patch.ApplyPatchMode;
|
||||
import com.intellij.openapi.vcs.changes.patch.FilePatchInProgress;
|
||||
import com.intellij.openapi.vcs.changes.patch.TextFilePatchInProgress;
|
||||
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
|
||||
import com.intellij.openapi.vcs.versionBrowser.ChangeBrowserSettings;
|
||||
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
|
||||
@@ -226,7 +226,7 @@ public class MergeFromTheirsResolver {
|
||||
}
|
||||
}
|
||||
|
||||
private class TreeConflictApplyTheirsPatchExecutor implements ApplyPatchExecutor {
|
||||
private class TreeConflictApplyTheirsPatchExecutor implements ApplyPatchExecutor<TextFilePatchInProgress> {
|
||||
private final SvnVcs myVcs;
|
||||
private final ContinuationContext myInner;
|
||||
private final VirtualFile myBaseDir;
|
||||
@@ -243,7 +243,7 @@ public class MergeFromTheirsResolver {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(MultiMap<VirtualFile, FilePatchInProgress> patchGroups, LocalChangeList localList, String fileName,
|
||||
public void apply(MultiMap<VirtualFile, TextFilePatchInProgress> patchGroups, LocalChangeList localList, String fileName,
|
||||
TransparentlyFailedValueI<Map<String, Map<String, CharSequence>>, PatchSyntaxException> additionalInfo) {
|
||||
final List<FilePatch> patches;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user