use of com.intellij.openapi.vcs.FilePath in project intellij-community by JetBrains.
the class DiffRequestFactoryImpl method getTitle.
@NotNull
public static String getTitle(@NotNull FilePath path1, @NotNull FilePath path2, @NotNull String separator) {
if ((path1.isDirectory() || path2.isDirectory()) && path1.getPath().equals(path2.getPath())) {
return path1.getPresentableUrl();
}
String name1 = path1.getName();
String name2 = path2.getName();
if (path1.isDirectory() ^ path2.isDirectory()) {
if (path1.isDirectory())
name1 += File.separatorChar;
if (path2.isDirectory())
name2 += File.separatorChar;
}
FilePath parent1 = path1.getParentPath();
FilePath parent2 = path2.getParentPath();
return getRequestTitle(name1, path1.getPresentableUrl(), parent1 != null ? parent1.getPresentableUrl() : null, name2, path2.getPresentableUrl(), parent2 != null ? parent2.getPresentableUrl() : null, separator);
}
use of com.intellij.openapi.vcs.FilePath in project intellij-community by JetBrains.
the class BaseRevisionTextPatchEP method provideContent.
@Override
public CharSequence provideContent(@NotNull String path, CommitContext commitContext) {
if (commitContext == null)
return null;
if (Boolean.TRUE.equals(commitContext.getUserData(ourPutBaseRevisionTextKey))) {
final File file = new File(myBaseDir, path);
FilePath filePathOn = VcsContextFactory.SERVICE.getInstance().createFilePathOn(file);
final Change change = myChangeListManager.getChange(filePathOn);
List<FilePath> paths = commitContext.getUserData(ourBaseRevisionPaths);
if (change == null || change.getBeforeRevision() == null || paths == null || !paths.contains(filePathOn))
return null;
try {
final String content = change.getBeforeRevision().getContent();
return content;
} catch (VcsException e) {
LOG.info(e);
}
} else {
final Map<String, String> map = commitContext.getUserData(ourStoredTexts);
if (map != null) {
final File file = new File(myBaseDir, path);
return map.get(file.getPath());
}
}
return null;
}
use of com.intellij.openapi.vcs.FilePath in project intellij-community by JetBrains.
the class CommittedChangesTreeBrowser method zipChanges.
/**
* Zips changes by removing duplicates (changes in the same file) and compounding the diff.
* <b>NB:</b> changes must be given in the time-ascending order, i.e the first change in the list should be the oldest one.
*/
@NotNull
public static List<Change> zipChanges(@NotNull List<Change> changes) {
// TODO: further improvements needed
// We may want to process collisions more consistent
// Possible solution: avoid creating duplicate entries for the same FilePath. No changes in the output should have same beforePath or afterPath.
// We may take earliest and latest revisions for each file.
//
// The main problem would be to keep existing movements in non-conflicting cases (where input changes are taken from linear sequence of commits)
// case1: "a -> b; b -> c" - file renamed twice in the same revision (as source and as target)
// case2: "a -> b" "b -> c" - file renamed twice in consequent commits
// case3: "a -> b; b -> a" - files swapped vs "a -> b" "b -> a" - file rename canceled
// case4: "delete a" "b -> a" "modify a"
// ...
// but return "good enough" result for input with conflicting changes
// case1: "new a", "new a"
// case2: "a -> b", "new b"
// ...
//
// getting "actually good" results is impossible without knowledge of commits topology.
// key - after path (nullable)
LinkedMultiMap<FilePath, Change> map = new LinkedMultiMap<>();
for (Change change : changes) {
ContentRevision bRev = change.getBeforeRevision();
ContentRevision aRev = change.getAfterRevision();
FilePath bPath = bRev != null ? bRev.getFile() : null;
FilePath aPath = aRev != null ? aRev.getFile() : null;
if (bRev == null) {
map.putValue(aPath, change);
continue;
}
Collection<Change> bucket = map.get(bPath);
if (bucket.isEmpty()) {
map.putValue(aPath, change);
continue;
}
Change oldChange = bucket.iterator().next();
bucket.remove(oldChange);
ContentRevision oldRevision = oldChange.getBeforeRevision();
if (oldRevision != null || aRev != null) {
map.putValue(aPath, new Change(oldRevision, aRev));
}
}
// put deletions into appropriate place in list
Collection<Change> deleted = map.remove(null);
if (deleted != null) {
for (Change change : deleted) {
//noinspection ConstantConditions
map.putValue(change.getBeforeRevision().getFile(), change);
}
}
return new ArrayList<>(map.values());
}
use of com.intellij.openapi.vcs.FilePath in project intellij-community by JetBrains.
the class ChangeDiffRequestProducer method createRequest.
@NotNull
private DiffRequest createRequest(@Nullable Project project, @NotNull Change change, @NotNull UserDataHolder context, @NotNull ProgressIndicator indicator) throws DiffRequestProducerException {
if (ChangesUtil.isTextConflictingChange(change)) {
// three side diff
// FIXME: This part is ugly as a VCS merge subsystem itself.
FilePath path = ChangesUtil.getFilePath(change);
VirtualFile file = path.getVirtualFile();
if (file == null) {
file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path.getPath());
}
if (file == null)
throw new DiffRequestProducerException("Can't show merge conflict - file not found");
if (project == null) {
throw new DiffRequestProducerException("Can't show merge conflict - project is unknown");
}
final AbstractVcs vcs = ChangesUtil.getVcsForChange(change, project);
if (vcs == null || vcs.getMergeProvider() == null) {
throw new DiffRequestProducerException("Can't show merge conflict - operation nos supported");
}
try {
// FIXME: loadRevisions() can call runProcessWithProgressSynchronously() inside
final Ref<Throwable> exceptionRef = new Ref<>();
final Ref<MergeData> mergeDataRef = new Ref<>();
final VirtualFile finalFile = file;
ApplicationManager.getApplication().invokeAndWait(() -> {
try {
mergeDataRef.set(vcs.getMergeProvider().loadRevisions(finalFile));
} catch (VcsException e) {
exceptionRef.set(e);
}
});
if (!exceptionRef.isNull()) {
Throwable e = exceptionRef.get();
if (e instanceof VcsException)
throw (VcsException) e;
if (e instanceof Error)
throw (Error) e;
if (e instanceof RuntimeException)
throw (RuntimeException) e;
throw new RuntimeException(e);
}
MergeData mergeData = mergeDataRef.get();
ContentRevision bRev = change.getBeforeRevision();
ContentRevision aRev = change.getAfterRevision();
String beforeRevisionTitle = getRevisionTitle(bRev, "Your version");
String afterRevisionTitle = getRevisionTitle(aRev, "Server version");
String title = DiffRequestFactory.getInstance().getTitle(file);
List<String> titles = ContainerUtil.list(beforeRevisionTitle, "Base Version", afterRevisionTitle);
DiffContentFactory contentFactory = DiffContentFactory.getInstance();
List<DiffContent> contents = ContainerUtil.list(contentFactory.createFromBytes(project, mergeData.CURRENT, file), contentFactory.createFromBytes(project, mergeData.ORIGINAL, file), contentFactory.createFromBytes(project, mergeData.LAST, file));
SimpleDiffRequest request = new SimpleDiffRequest(title, contents, titles);
MergeUtil.putRevisionInfos(request, mergeData);
return request;
} catch (VcsException | IOException e) {
LOG.info(e);
throw new DiffRequestProducerException(e);
}
} else {
ContentRevision bRev = change.getBeforeRevision();
ContentRevision aRev = change.getAfterRevision();
if (bRev == null && aRev == null) {
LOG.warn("Both revision contents are empty");
throw new DiffRequestProducerException("Bad revisions contents");
}
if (bRev != null)
checkContentRevision(project, bRev, context, indicator);
if (aRev != null)
checkContentRevision(project, aRev, context, indicator);
String title = getRequestTitle(change);
indicator.setIndeterminate(true);
DiffContent content1 = createContent(project, bRev, context, indicator);
DiffContent content2 = createContent(project, aRev, context, indicator);
final String userLeftRevisionTitle = (String) myChangeContext.get(DiffUserDataKeysEx.VCS_DIFF_LEFT_CONTENT_TITLE);
String beforeRevisionTitle = userLeftRevisionTitle != null ? userLeftRevisionTitle : getRevisionTitle(bRev, "Base version");
final String userRightRevisionTitle = (String) myChangeContext.get(DiffUserDataKeysEx.VCS_DIFF_RIGHT_CONTENT_TITLE);
String afterRevisionTitle = userRightRevisionTitle != null ? userRightRevisionTitle : getRevisionTitle(aRev, "Your version");
SimpleDiffRequest request = new SimpleDiffRequest(title, content1, content2, beforeRevisionTitle, afterRevisionTitle);
boolean bRevCurrent = bRev instanceof CurrentContentRevision;
boolean aRevCurrent = aRev instanceof CurrentContentRevision;
if (bRevCurrent && !aRevCurrent)
request.putUserData(DiffUserDataKeys.MASTER_SIDE, Side.LEFT);
if (!bRevCurrent && aRevCurrent)
request.putUserData(DiffUserDataKeys.MASTER_SIDE, Side.RIGHT);
return request;
}
}
use of com.intellij.openapi.vcs.FilePath in project intellij-community by JetBrains.
the class MoveChangesToAnotherListAction method addAllChangesUnderPath.
private static void addAllChangesUnderPath(@NotNull ChangeListManager changeListManager, @NotNull FilePath file, @NotNull List<Change> changes, @NotNull List<VirtualFile> changedFiles) {
for (Change change : changeListManager.getChangesIn(file)) {
changes.add(change);
FilePath path = ChangesUtil.getAfterPath(change);
if (path != null && path.getVirtualFile() != null) {
changedFiles.add(path.getVirtualFile());
}
}
}
Aggregations