mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
[vcs-log] add an option to show only affected files in the changes browser
This commit is contained in:
@@ -85,6 +85,7 @@
|
||||
<action class="com.intellij.vcs.log.ui.actions.ShowDetailsAction" id="Vcs.Log.ShowDetailsAction"/>
|
||||
<action class="com.intellij.vcs.log.ui.actions.ShowDiffPreviewAction" id="Vcs.Log.ShowDiffPreview"/>
|
||||
<action class="com.intellij.vcs.log.ui.actions.ShowChangesFromParentsAction" id="Vcs.Log.ShowChangesFromParents"/>
|
||||
<action class="com.intellij.vcs.log.ui.actions.ShowOnlyAffectedChangesAction" id="Vcs.Log.ShowOnlyAffectedChanges"/>
|
||||
<action class="com.intellij.vcs.log.ui.actions.ShowRootsColumnAction" id="Vcs.Log.ShowRootsColumnAction"/>
|
||||
<action class="com.intellij.vcs.log.ui.actions.FocusTextFilterAction" id="Vcs.Log.FocusTextFilter">
|
||||
<keyboard-shortcut first-keystroke="control L" keymap="$default"/>
|
||||
@@ -154,6 +155,7 @@
|
||||
</group>
|
||||
<group id="Vcs.Log.ChangesBrowser.Toolbar">
|
||||
<reference id="Vcs.RepositoryChangesBrowserToolbar"/>
|
||||
<reference id="Vcs.Log.ShowOnlyAffectedChanges"/>
|
||||
<separator/>
|
||||
<reference id="ChangesView.GroupBy"/>
|
||||
<separator/>
|
||||
|
||||
@@ -58,7 +58,7 @@ public class FileHistoryUtil {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
static boolean affectsFile(@NotNull Change change, @NotNull FilePath file, boolean isDeleted) {
|
||||
public static boolean affectsFile(@NotNull Change change, @NotNull FilePath file, boolean isDeleted) {
|
||||
ContentRevision revision = isDeleted ? change.getBeforeRevision() : change.getAfterRevision();
|
||||
if (revision == null) return false;
|
||||
return file.equals(revision.getFile());
|
||||
|
||||
+2
-4
@@ -8,10 +8,7 @@ import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.*;
|
||||
import com.intellij.vcs.log.data.VcsLogData;
|
||||
import com.intellij.vcs.log.impl.HashImpl;
|
||||
import com.intellij.vcs.log.impl.VcsLogContentUtil;
|
||||
import com.intellij.vcs.log.impl.VcsLogManager;
|
||||
import com.intellij.vcs.log.impl.VcsProjectLog;
|
||||
import com.intellij.vcs.log.impl.*;
|
||||
import com.intellij.vcs.log.ui.AbstractVcsLogUi;
|
||||
import com.intellij.vcs.log.ui.VcsLogUiImpl;
|
||||
import com.intellij.vcs.log.util.VcsLogUtil;
|
||||
@@ -94,6 +91,7 @@ public class VcsLogFileHistoryProviderImpl implements VcsLogFileHistoryProvider
|
||||
if (firstTime) {
|
||||
VcsLogFilterCollection filters = createFilters(path, hash, root);
|
||||
ui = VcsProjectLog.getInstance(project).getTabsManager().openAnotherLogTab(logManager, filters);
|
||||
ui.getProperties().set(MainVcsLogUiProperties.SHOW_ONLY_AFFECTED_CHANGES, true);
|
||||
}
|
||||
consumer.accept(ui, firstTime);
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ public interface MainVcsLogUiProperties extends VcsLogUiProperties {
|
||||
VcsLogUiProperty<Boolean> TEXT_FILTER_MATCH_CASE = new VcsLogUiProperty<>("TextFilter.MatchCase");
|
||||
VcsLogUiProperty<Boolean> TEXT_FILTER_REGEX = new VcsLogUiProperty<>("TextFilter.Regex");
|
||||
VcsLogUiProperty<Boolean> SHOW_CHANGES_FROM_PARENTS = new VcsLogUiProperty<>("Changes.ShowChangesFromParents");
|
||||
VcsLogUiProperty<Boolean> SHOW_ONLY_AFFECTED_CHANGES = new VcsLogUiProperty<>("Changes.ShowOnlyAffected");
|
||||
|
||||
void addRecentlyFilteredGroup(@NotNull String filterName, @NotNull Collection<String> values);
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ public abstract class VcsLogUiPropertiesImpl<S extends VcsLogUiPropertiesImpl.St
|
||||
MainVcsLogUiProperties.SHOW_LONG_EDGES,
|
||||
MainVcsLogUiProperties.BEK_SORT_TYPE,
|
||||
CommonUiProperties.SHOW_ROOT_NAMES,
|
||||
MainVcsLogUiProperties.SHOW_ONLY_AFFECTED_CHANGES,
|
||||
MainVcsLogUiProperties.TEXT_FILTER_MATCH_CASE,
|
||||
MainVcsLogUiProperties.TEXT_FILTER_REGEX,
|
||||
CommonUiProperties.COLUMN_ORDER);
|
||||
@@ -48,6 +49,7 @@ public abstract class VcsLogUiPropertiesImpl<S extends VcsLogUiPropertiesImpl.St
|
||||
public boolean LONG_EDGES_VISIBLE = false;
|
||||
public int BEK_SORT_TYPE = 0;
|
||||
public boolean SHOW_ROOT_NAMES = false;
|
||||
public boolean SHOW_ONLY_AFFECTED_CHANGES = false;
|
||||
@Deprecated
|
||||
public Deque<UserGroup> RECENTLY_FILTERED_USER_GROUPS = new ArrayDeque<>();
|
||||
@Deprecated
|
||||
@@ -80,6 +82,9 @@ public abstract class VcsLogUiPropertiesImpl<S extends VcsLogUiPropertiesImpl.St
|
||||
else if (CommonUiProperties.SHOW_ROOT_NAMES.equals(property)) {
|
||||
return (T)Boolean.valueOf(getState().SHOW_ROOT_NAMES);
|
||||
}
|
||||
else if (SHOW_ONLY_AFFECTED_CHANGES.equals(property)) {
|
||||
return (T)Boolean.valueOf(getState().SHOW_ONLY_AFFECTED_CHANGES);
|
||||
}
|
||||
else if (BEK_SORT_TYPE.equals(property)) {
|
||||
return (T)PermanentGraph.SortType.values()[getState().BEK_SORT_TYPE];
|
||||
}
|
||||
@@ -124,6 +129,9 @@ public abstract class VcsLogUiPropertiesImpl<S extends VcsLogUiPropertiesImpl.St
|
||||
else if (CommonUiProperties.SHOW_ROOT_NAMES.equals(property)) {
|
||||
getState().SHOW_ROOT_NAMES = (Boolean)value;
|
||||
}
|
||||
else if (SHOW_ONLY_AFFECTED_CHANGES.equals(property)) {
|
||||
getState().SHOW_ONLY_AFFECTED_CHANGES = (Boolean)value;
|
||||
}
|
||||
else if (BEK_SORT_TYPE.equals(property)) {
|
||||
getState().BEK_SORT_TYPE = ((PermanentGraph.SortType)value).ordinal();
|
||||
}
|
||||
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.vcs.log.ui.actions;
|
||||
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.util.registry.Registry;
|
||||
import com.intellij.vcs.log.impl.MainVcsLogUiProperties;
|
||||
import com.intellij.vcs.log.impl.VcsLogUiProperties;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ShowOnlyAffectedChangesAction extends BooleanPropertyToggleAction {
|
||||
|
||||
public ShowOnlyAffectedChangesAction() {
|
||||
super("Show Only Affected Changes", "Show only changes that affect files that were selected in the \"Paths\" menu",
|
||||
AllIcons.Nodes.Folder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VcsLogUiProperties.VcsLogUiProperty<Boolean> getProperty() {
|
||||
return MainVcsLogUiProperties.SHOW_ONLY_AFFECTED_CHANGES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(@NotNull AnActionEvent e) {
|
||||
if (!Registry.is("vcs.folder.history.in.log")) {
|
||||
e.getPresentation().setEnabledAndVisible(false);
|
||||
} else {
|
||||
super.update(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -169,6 +169,8 @@ public class MainFrame extends JPanel implements DataProvider, Disposable {
|
||||
public void updateDataPack(@NotNull VisiblePack dataPack, boolean permGraphChanged) {
|
||||
myFilterUi.updateDataPack(dataPack);
|
||||
myGraphTable.updateDataPack(dataPack, permGraphChanged);
|
||||
VcsLogStructureFilter structureFilter = dataPack.getFilters().get(VcsLogFilterCollection.STRUCTURE_FILTER);
|
||||
myChangesBrowser.setAffectedPaths(structureFilter != null ? structureFilter.getFiles() : null);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.openapi.vcs.history.VcsRevisionNumber;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import com.intellij.ui.SideBorder;
|
||||
import com.intellij.ui.SimpleTextAttributes;
|
||||
import com.intellij.ui.components.panels.Wrapper;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
@@ -30,6 +31,7 @@ import com.intellij.vcs.log.VcsShortCommitDetails;
|
||||
import com.intellij.vcs.log.data.LoadingDetails;
|
||||
import com.intellij.vcs.log.data.index.IndexedDetails;
|
||||
import com.intellij.vcs.log.history.FileHistoryKt;
|
||||
import com.intellij.vcs.log.history.FileHistoryUtil;
|
||||
import com.intellij.vcs.log.impl.MainVcsLogUiProperties;
|
||||
import com.intellij.vcs.log.impl.MergedChange;
|
||||
import com.intellij.vcs.log.impl.MergedChangeDiffRequestProvider;
|
||||
@@ -51,6 +53,7 @@ import static com.intellij.diff.util.DiffUserDataKeysEx.*;
|
||||
import static com.intellij.util.ObjectUtils.notNull;
|
||||
import static com.intellij.util.containers.ContainerUtil.getFirstItem;
|
||||
import static com.intellij.vcs.log.impl.MainVcsLogUiProperties.SHOW_CHANGES_FROM_PARENTS;
|
||||
import static com.intellij.vcs.log.impl.MainVcsLogUiProperties.SHOW_ONLY_AFFECTED_CHANGES;
|
||||
|
||||
/**
|
||||
* Change browser for commits in the Log. For merge commits, can display changes to commits parents in separate groups.
|
||||
@@ -66,6 +69,7 @@ public class VcsLogChangesBrowser extends ChangesBrowserBase implements Disposab
|
||||
@NotNull private final Set<VirtualFile> myRoots = ContainerUtil.newHashSet();
|
||||
@NotNull private final List<Change> myChanges = ContainerUtil.newArrayList();
|
||||
@NotNull private final Map<CommitId, Set<Change>> myChangesToParents = ContainerUtil.newHashMap();
|
||||
@Nullable private Collection<FilePath> myAffectedPaths;
|
||||
@NotNull private final Wrapper myToolbarWrapper;
|
||||
@Nullable private Runnable myModelUpdateListener;
|
||||
|
||||
@@ -81,7 +85,7 @@ public class VcsLogChangesBrowser extends ChangesBrowserBase implements Disposab
|
||||
myListener = new VcsLogUiProperties.PropertiesChangeListener() {
|
||||
@Override
|
||||
public <T> void onPropertyChanged(@NotNull VcsLogUiProperties.VcsLogUiProperty<T> property) {
|
||||
if (SHOW_CHANGES_FROM_PARENTS.equals(property)) {
|
||||
if (SHOW_CHANGES_FROM_PARENTS.equals(property) || SHOW_ONLY_AFFECTED_CHANGES.equals(property)) {
|
||||
myViewer.rebuildTree();
|
||||
}
|
||||
}
|
||||
@@ -150,6 +154,11 @@ public class VcsLogChangesBrowser extends ChangesBrowserBase implements Disposab
|
||||
if (myModelUpdateListener != null) myModelUpdateListener.run();
|
||||
}
|
||||
|
||||
public void setAffectedPaths(@Nullable Collection<FilePath> paths) {
|
||||
myAffectedPaths = paths;
|
||||
myViewer.rebuildTree();
|
||||
}
|
||||
|
||||
public void setSelectedDetails(@NotNull List<? extends VcsFullCommitDetails> detailsList) {
|
||||
myChanges.clear();
|
||||
myChangesToParents.clear();
|
||||
@@ -192,15 +201,21 @@ public class VcsLogChangesBrowser extends ChangesBrowserBase implements Disposab
|
||||
@NotNull
|
||||
@Override
|
||||
protected DefaultTreeModel buildTreeModel() {
|
||||
MyTreeModelBuilder builder = new MyTreeModelBuilder();
|
||||
builder.setChanges(myChanges, null);
|
||||
Collection<Change> changes = collectAffectedChanges(myChanges);
|
||||
Map<CommitId, Collection<Change>> changesToParents = ContainerUtil.newHashMap();
|
||||
for (Map.Entry<CommitId, Set<Change>> entry : myChangesToParents.entrySet()) {
|
||||
changesToParents.put(entry.getKey(), collectAffectedChanges(entry.getValue()));
|
||||
}
|
||||
|
||||
if (isShowChangesFromParents() && !myChangesToParents.isEmpty()) {
|
||||
if (myChanges.isEmpty()) {
|
||||
MyTreeModelBuilder builder = new MyTreeModelBuilder();
|
||||
builder.setChanges(changes, null);
|
||||
|
||||
if (isShowChangesFromParents() && !changesToParents.isEmpty()) {
|
||||
if (changes.isEmpty()) {
|
||||
builder.addEmptyTextNode("No merged conflicts");
|
||||
}
|
||||
for (CommitId commitId : myChangesToParents.keySet()) {
|
||||
Collection<Change> changesFromParent = myChangesToParents.get(commitId);
|
||||
for (CommitId commitId : changesToParents.keySet()) {
|
||||
Collection<Change> changesFromParent = changesToParents.get(commitId);
|
||||
if (!changesFromParent.isEmpty()) {
|
||||
builder.addChangesFromParentNode(changesFromParent, commitId);
|
||||
}
|
||||
@@ -210,11 +225,30 @@ public class VcsLogChangesBrowser extends ChangesBrowserBase implements Disposab
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private Collection<Change> collectAffectedChanges(@NotNull Collection<Change> changes) {
|
||||
if (!isShowOnlyAffected() || myAffectedPaths == null) return changes;
|
||||
return ContainerUtil.filter(changes, change -> ContainerUtil.or(myAffectedPaths, filePath -> {
|
||||
if (filePath.isDirectory()) {
|
||||
return FileHistoryUtil.affectsDirectory(change, filePath);
|
||||
}
|
||||
else {
|
||||
return FileHistoryUtil.affectsFile(change, filePath, false) ||
|
||||
FileHistoryUtil.affectsFile(change, filePath, true);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private boolean isShowChangesFromParents() {
|
||||
return myUiProperties.exists(SHOW_CHANGES_FROM_PARENTS) &&
|
||||
myUiProperties.get(SHOW_CHANGES_FROM_PARENTS);
|
||||
}
|
||||
|
||||
private boolean isShowOnlyAffected() {
|
||||
return myUiProperties.exists(SHOW_ONLY_AFFECTED_CHANGES) &&
|
||||
myUiProperties.get(SHOW_ONLY_AFFECTED_CHANGES);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Change> getDirectChanges() {
|
||||
return myChanges;
|
||||
|
||||
Reference in New Issue
Block a user