use of com.intellij.openapi.vcs.changes.ContentRevision 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.changes.ContentRevision in project intellij-community by JetBrains.
the class OpenRepositoryVersionAction method openRepositoryVersion.
private static void openRepositoryVersion(@NotNull Project project, @NotNull Change[] changes) {
for (Change change : changes) {
ContentRevision revision = change.getAfterRevision();
if (revision == null || revision.getFile().isDirectory())
continue;
VirtualFile vFile = ContentRevisionVirtualFile.create(revision);
Navigatable navigatable = new OpenFileDescriptor(project, vFile);
navigatable.navigate(true);
}
}
use of com.intellij.openapi.vcs.changes.ContentRevision in project intellij-community by JetBrains.
the class VcsUtil method isRenameChange.
/**
* @param change "Change" description.
* @return Return true if the "Change" object is created for "Rename" operation:
* in this case name of files for "before" and "after" revisions must not
* coniside.
*/
public static boolean isRenameChange(Change change) {
boolean isRenamed = false;
ContentRevision before = change.getBeforeRevision();
ContentRevision after = change.getAfterRevision();
if (before != null && after != null) {
String prevFile = getCanonicalLocalPath(before.getFile().getPath());
String newFile = getCanonicalLocalPath(after.getFile().getPath());
isRenamed = !prevFile.equals(newFile);
}
return isRenamed;
}
use of com.intellij.openapi.vcs.changes.ContentRevision in project intellij-community by JetBrains.
the class SelectFilesToAddTextsToPatchPanel method getBig.
public static Set<Change> getBig(List<Change> changes) {
final Set<Change> exclude = new HashSet<>();
for (Change change : changes) {
// try to estimate size via VF: we assume that base content hasn't been changed much
VirtualFile virtualFile = getVfFromChange(change);
if (virtualFile != null) {
if (isBig(virtualFile)) {
exclude.add(change);
}
continue;
}
// otherwise, to avoid regression we have to process context length
ContentRevision beforeRevision = change.getBeforeRevision();
if (beforeRevision != null) {
try {
String content = beforeRevision.getContent();
if (content == null) {
final FilePath file = beforeRevision.getFile();
LOG.info("null content for " + (file.getPath()) + ", is dir: " + (file.isDirectory()));
continue;
}
if (content.length() > VcsConfiguration.ourMaximumFileForBaseRevisionSize) {
exclude.add(change);
}
} catch (VcsException e) {
LOG.info(e);
}
}
}
return exclude;
}
use of com.intellij.openapi.vcs.changes.ContentRevision in project intellij-community by JetBrains.
the class CvsChangeList method getChanges.
public Collection<Change> getChanges() {
if (myChanges == null) {
myChanges = new ArrayList<>();
for (RevisionWrapper wrapper : myRevisions) {
final Revision revision = wrapper.getRevision();
final String state = revision.getState();
String path = wrapper.getFile();
final File localFile;
if (myRootFile != null) {
final String directorySuffix = myRootFile.isDirectory() ? "/" : "";
if (StringUtil.startsWithConcatenation(path, myRootPath, directorySuffix)) {
path = path.substring(myRootPath.length() + directorySuffix.length());
localFile = new File(myRootFile.getPresentableUrl(), path);
} else {
localFile = new File(wrapper.getFile());
}
} else {
localFile = new File(wrapper.getFile());
}
final boolean added = isAdded(revision);
final ContentRevision beforeRevision = added ? null : new CvsContentRevision(new File(wrapper.getFile()), localFile, new SimpleRevision(new CvsRevisionNumber(revision.getNumber()).getPrevNumber().asString()), myEnvironment, myProject);
final ContentRevision afterRevision = (!added && DEAD_STATE.equals(state)) ? null : new CvsContentRevision(new File(wrapper.getFile()), localFile, new SimpleRevision(revision.getNumber()), myEnvironment, myProject);
myChanges.add(new Change(beforeRevision, afterRevision));
}
}
return myChanges;
}
Aggregations