Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Neumann2019-07-19 09:31:12 -0400
committerThomas Wolf2019-08-14 12:46:27 -0400
commite48ed04cd3f86f698c453ca6295621cde7501157 (patch)
tree68488496f8ac38dd69dbe855fd3780418fdb0794
parent37f68e0f7151b67592b592d07d4356811895ce3e (diff)
downloadegit-e48ed04cd3f86f698c453ca6295621cde7501157.tar.gz
egit-e48ed04cd3f86f698c453ca6295621cde7501157.tar.xz
egit-e48ed04cd3f86f698c453ca6295621cde7501157.zip
Add "show first parent only" button to the history view
This includes: - action in GitHistoryPage - allow the setting to be sticky to one repository - add getter and setter for GitHistoryPage.currentRepo -> so a repo change can be detected - add the action to the menu and toolbar - add corresponding preference to the preference page -> "Team -> Git -> History" - add a new icon for the action - based on the preference do a first-parent-only RevWalk - create some new helper methods in RepositoryUtil Bug: 549424 Change-Id: I548ef25f8c13661fadf725952bc25d2f481c7a43 Signed-off-by: Tim Neumann <Tim.Neumann@advantest.com> Also-by: Tetiana Pliekhova <tetiana.pliekhova@advantest.com> Signed-off-by: Andrey Loskutov <loskutov@gmx.de>
-rw-r--r--icons/org.eclipse.egit.ui/icons/obj16/first_parent_only.svg165
-rw-r--r--org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java46
-rw-r--r--org.eclipse.egit.ui/icons/obj16/first_parent_only.pngbin0 -> 647 bytes
-rw-r--r--org.eclipse.egit.ui/icons/obj16/first_parent_only@2x.pngbin0 -> 1307 bytes
-rw-r--r--org.eclipse.egit.ui/plugin.properties2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java2
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java9
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java259
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java4
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties3
12 files changed, 458 insertions, 38 deletions
diff --git a/icons/org.eclipse.egit.ui/icons/obj16/first_parent_only.svg b/icons/org.eclipse.egit.ui/icons/obj16/first_parent_only.svg
new file mode 100644
index 000000000..c7c439d26
--- /dev/null
+++ b/icons/org.eclipse.egit.ui/icons/obj16/first_parent_only.svg
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="16"
+ height="16"
+ id="svg2"
+ version="1.1"
+ inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+ sodipodi:docname="first_parent_only.svg">
+ <defs
+ id="defs4">
+ <linearGradient
+ id="linearGradient3861">
+ <stop
+ style="stop-color:#caf3f6;stop-opacity:1;"
+ offset="0"
+ id="stop3863" />
+ <stop
+ style="stop-color:#ffffff;stop-opacity:1;"
+ offset="1"
+ id="stop3865" />
+ </linearGradient>
+ <linearGradient
+ inkscape:collect="always"
+ xlink:href="#linearGradient3861"
+ id="linearGradient3867"
+ x1="-11"
+ y1="1054.3622"
+ x2="-11"
+ y2="1029.3622"
+ gradientUnits="userSpaceOnUse"
+ gradientTransform="matrix(0.5,0,0,0.5,13.03125,521.1811)" />
+ <linearGradient
+ id="linearGradient4844-4">
+ <stop
+ id="stop4846-8"
+ offset="0"
+ style="stop-color:#414141;stop-opacity:1;" />
+ <stop
+ id="stop4848-8"
+ offset="1"
+ style="stop-color:#535353;stop-opacity:1;" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.47199644,0,0,0.47199414,7.4742532,550.36311)"
+ gradientUnits="userSpaceOnUse"
+ y2="1038.5814"
+ x2="4.7528968"
+ y1="1051.0466"
+ x1="4.7528968"
+ id="x-bg"
+ xlink:href="#x-bg-3"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-bg-3"
+ inkscape:collect="always">
+ <stop
+ id="x-bg-stop0"
+ offset="0"
+ style="stop-color:#df2c33;stop-opacity:1" />
+ <stop
+ id="x-bg-stop1"
+ offset="1"
+ style="stop-color:#f5817d;stop-opacity:1" />
+ </linearGradient>
+ <linearGradient
+ gradientTransform="matrix(0.47199644,0,0,0.47199414,7.4742532,550.36311)"
+ gradientUnits="userSpaceOnUse"
+ y2="1037.7"
+ x2="8.6566515"
+ y1="1050.7386"
+ x1="8.6566515"
+ id="x-stroke"
+ xlink:href="#x-stroke-6"
+ inkscape:collect="always" />
+ <linearGradient
+ id="x-stroke-6"
+ inkscape:collect="always">
+ <stop
+ id="x-stroke-stop0"
+ offset="0"
+ style="stop-color:#c51325;stop-opacity:1;" />
+ <stop
+ id="x-stroke-stop1"
+ offset="1"
+ style="stop-color:#ca5d49;stop-opacity:1" />
+ </linearGradient>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="45.254834"
+ inkscape:cx="4.621357"
+ inkscape:cy="9.1963964"
+ inkscape:document-units="px"
+ inkscape:current-layer="g6616"
+ showgrid="true"
+ inkscape:window-width="1920"
+ inkscape:window-height="1082"
+ inkscape:window-x="-4"
+ inkscape:window-y="-4"
+ inkscape:window-maximized="1"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:snap-global="false">
+ <inkscape:grid
+ type="xygrid"
+ id="grid4000" />
+ </sodipodi:namedview>
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ <dc:title></dc:title>
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ style="display:inline"
+ transform="translate(0,-1036.3622)">
+ <g
+ id="g6616">
+ <path
+ style="fill:url(#linearGradient3867);fill-opacity:1;stroke:#679093;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
+ d="m 6.53125,1037.3622 0,4.5 -2,0 c -1,0 -2,1 -2,2 l 0,2 -2,0 0,1 3,3 3,-3 0,-1 -2,0 0,-1 c 0,-0.5 0.5,-1 1,-1 l 4,0 c 0.5,0 1,0.5 1,1 l 0,1 -2,0 0,1 3,3 3,-3 0,-1 -2,0 0,-2 c 0,-1 -1,-2 -2,-2 l -2,0 0,-4.5"
+ id="path3091"
+ inkscape:connector-curvature="0"
+ sodipodi:nodetypes="cccccccccccccccccccccccccc" />
+ <g
+ style="display:inline"
+ id="layer1-4"
+ inkscape:label="Layer 1"
+ transform="matrix(0.60535164,0,0,0.60535164,6.3760192,414.27492)" />
+ <path
+ sodipodi:nodetypes="sccccccccssccsccsccss"
+ inkscape:connector-curvature="0"
+ id="x-0"
+ d="m 13.808113,1040.6023 c -0.220982,-0.2209 -0.576769,-0.2209 -0.797739,0 l -1.469229,1.4694 -1.469216,-1.4694 c -0.2209502,-0.2209 -0.5767696,-0.2209 -0.7977394,0 l -0.4059426,0.4059 c -0.2209596,0.2211 -0.2209544,0.5769 1.74e-5,0.7979 l 1.4691946,1.4692 -1.4691976,1.4691 c -0.2209914,0.221 -0.2209873,0.5768 -6.2e-6,0.7978 l 0.4059652,0.4058 c 0.2209564,0.2212 0.5767434,0.2212 0.7977376,0 l 1.46922,-1.4691 1.479428,1.4794 c 0.220958,0.2212 0.576745,0.2212 0.797739,0 l 0.405941,-0.4058 c 0.220971,-0.221 0.218752,-0.5746 -1.5e-5,-0.7977 l -1.47943,-1.4795 1.469221,-1.4692 c 0.220978,-0.221 0.220972,-0.5768 1.4e-5,-0.7979 z"
+ style="display:inline;fill:url(#x-bg);fill-opacity:1;stroke:url(#x-stroke);stroke-width:0.46284017;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">
+ <title
+ id="title3202-1">x</title>
+ </path>
+ </g>
+ </g>
+</svg>
diff --git a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
index 15a3964dd..e3172fb0f 100644
--- a/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
+++ b/org.eclipse.egit.core/src/org/eclipse/egit/core/RepositoryUtil.java
@@ -557,14 +557,27 @@ public class RepositoryUtil {
}
/**
+ * Relativize the given absolute path.
+ * <p>
+ * The result is the path of {@code pathString} relative to the workspace
+ * root if the given {@code pathString} is under the workspace root,
+ * otherwise the absolute path {@code pathString}.
+ * </p>
+ * <p>
+ * This enables moving or copying the workspace, when saving this path and
+ * later resolving it relative to the workspace path.
+ * </p>
+ * <p>
+ * It is required, that the given pathString is absolute
+ * </p>
+ *
* @param pathString
- * an absolute path String
- * @return if the given {@code pathString} is under the workspace root the
- * relative path of {@code pathString} relative to the workspace
- * root, otherwise the absolute path {@code pathString}. This
- * enables moving or copying the workspace.
+ * an absolute path String. Must be absolute.
+ * @return the relativized path String
+ * @throws java.nio.file.InvalidPathException
+ * if the path string cannot be converted to a Path
*/
- private String relativizeToWorkspace(String pathString) {
+ public @NonNull String relativizeToWorkspace(@NonNull String pathString) {
java.nio.file.Path p = java.nio.file.Paths.get(pathString);
if (p.startsWith(workspacePath)) {
return workspacePath.relativize(p).toString();
@@ -574,6 +587,27 @@ public class RepositoryUtil {
}
/**
+ * Get the relativized path of the given repository.
+ * <p>
+ * If the repository is not local this method will return null.
+ * </p>
+ *
+ * @param repository
+ * The repository to get the path String of
+ * @return the relativized path String
+ * @see #relativizeToWorkspace(String)
+ */
+ @Nullable
+ public String getRelativizedRepositoryPath(
+ final @NonNull Repository repository) {
+ File dir = repository.getDirectory();
+ if (dir == null) {
+ return null;
+ }
+ return relativizeToWorkspace(dir.getAbsolutePath());
+ }
+
+ /**
* Does the collection of repository returned by
* {@link #getConfiguredRepositories()} contain the given repository?
*
diff --git a/org.eclipse.egit.ui/icons/obj16/first_parent_only.png b/org.eclipse.egit.ui/icons/obj16/first_parent_only.png
new file mode 100644
index 000000000..1ceb1ed3c
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/obj16/first_parent_only.png
Binary files differ
diff --git a/org.eclipse.egit.ui/icons/obj16/first_parent_only@2x.png b/org.eclipse.egit.ui/icons/obj16/first_parent_only@2x.png
new file mode 100644
index 000000000..746da3dc7
--- /dev/null
+++ b/org.eclipse.egit.ui/icons/obj16/first_parent_only@2x.png
Binary files differ
diff --git a/org.eclipse.egit.ui/plugin.properties b/org.eclipse.egit.ui/plugin.properties
index 22cce65cc..3130ebb80 100644
--- a/org.eclipse.egit.ui/plugin.properties
+++ b/org.eclipse.egit.ui/plugin.properties
@@ -82,7 +82,7 @@ CommittingPreferencePage_keywords = git egit committing staging stage untracked
StagingViewPreferencePage_keywords = git egit staging stage
DialogsPreferencePage_keywords = git egit confirmation dialog configuration rebase checkout detached launch branch clone lfs fetch push log home
SynchronizePreferencePage_keywords = git egit synchronize fetch commit models merge
-HistoryPreferencePage_keywords = git egit history branches tags refs notes rename revision comment date author committer diff
+HistoryPreferencePage_keywords = git egit history branches tags refs notes rename revision comment date author committer diff first parent
HistoryColumnsPreferencePage_keywords = git egit history columns id author committer date
GitActions_label=Git
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
index 9ef7e469b..79208d709 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/PluginPreferenceInitializer.java
@@ -60,6 +60,8 @@ public class PluginPreferenceInitializer extends AbstractPreferenceInitializer {
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_REV_COMMENT, true);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_TOOLTIPS, false);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES, false);
+ store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT,
+ false);
store.setDefault(UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS,
false);
store.setDefault(UIPreferences.RESOURCEHISTORY_FOLLOW_RENAMES, true);
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
index cf161b712..61b9069f6 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/UIPreferences.java
@@ -50,6 +50,8 @@ public class UIPreferences {
/** */
public final static String RESOURCEHISTORY_SHOW_ALL_BRANCHES = "resourcehistory_show_all_branches"; //$NON-NLS-1$
/** */
+ public final static String RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT = "resourcehistory_show_first_parent_only"; //$NON-NLS-1$
+ /** */
public final static String RESOURCEHISTORY_SHOW_ADDITIONAL_REFS = "resourcehistory_show_additionalrefs"; //$NON-NLS-1$
/** */
public static final String RESOURCEHISTORY_FOLLOW_RENAMES = "resourcehistory_follow_renames"; //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
index a217e0280..effd4247f 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIIcons.java
@@ -268,6 +268,9 @@ public class UIIcons {
/** Merge icon */
public final static ImageDescriptor MERGE;
+ /** First parent only icon */
+ public final static ImageDescriptor FIRST_PARENT_ONLY;
+
/** Annotated tag icon */
public final static ImageDescriptor TAG_ANNOTATED;
@@ -452,6 +455,7 @@ public class UIIcons {
REBASE_PROCESS_STEPS = map("elcl16/start.png"); //$NON-NLS-1$
OVR_ERROR = map("ovr/error.png"); //$NON-NLS-1$
MERGE = map("obj16/merge.png"); //$NON-NLS-1$
+ FIRST_PARENT_ONLY = map("obj16/first_parent_only.png"); //$NON-NLS-1$
TAG_ANNOTATED = map("obj16/annotated-tag.png"); //$NON-NLS-1$
CREATE_REPOSITORY = map("etool16/createRepository.png"); //$NON-NLS-1$
SUBMODULES = map("obj16/submodules.png"); //$NON-NLS-1$
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
index 4f7e617fd..63fdde843 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/UIText.java
@@ -475,6 +475,9 @@ public class UIText extends NLS {
public static String GitHistoryPage_showAllBranches;
/** */
+ public static String GitHistoryPage_showFirstParentOnly;
+
+ /** */
public static String GitHistoryPage_squashMenuItem;
/** */
@@ -625,6 +628,9 @@ public class UIText extends NLS {
public static String GitHistoryPage_ShowAllBranchesMenuLabel;
/** */
+ public static String GitHistoryPage_ShowFirstParentOnlyMenuLabel;
+
+ /** */
public static String GitHistoryPage_FollowRenames;
/** */
@@ -2131,6 +2137,9 @@ public class UIText extends NLS {
public static String HistoryPreferencePage_toggleAllBranches;
/** */
+ public static String HistoryPreferencePage_showFirstParentOnlyDefault;
+
+ /** */
public static String HistoryPreferencePage_toggleEmailAddresses;
/** */
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
index d9c53516d..1e33ac4c3 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryPage.java
@@ -23,8 +23,10 @@ package org.eclipse.egit.ui.internal.history;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
+import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -87,6 +89,7 @@ import org.eclipse.jface.bindings.keys.SWTKeySupport;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.preference.IPersistentPreferenceStore;
+import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.resource.JFaceResources;
@@ -189,6 +192,8 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
private static final int INITIAL_ITEM = -1;
+ private static final String P_REPOSITORY = "GitHistoryPage.Repository"; //$NON-NLS-1$
+
/** actions used in GitHistoryPage **/
private static class GitHistoryPageActions {
@@ -206,12 +211,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
@Override
public void run() {
historyPage.store.setValue(prefName, isChecked());
- if (historyPage.store.needsSaving())
- try {
- historyPage.store.save();
- } catch (IOException e) {
- Activator.handleError(e.getMessage(), e, false);
- }
+ historyPage.saveStoreIfNeeded();
}
abstract void apply(boolean value);
@@ -319,6 +319,8 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
IWorkbenchAction showAllBranchesAction;
+ IWorkbenchAction showFirstParentOnlyAction;
+
IWorkbenchAction showAdditionalRefsAction;
BooleanPrefAction followRenamesAction;
@@ -356,6 +358,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
createCompareModeAction();
createReuseCompareEditorAction();
createShowAllBranchesAction();
+ createShowFirstParentOnlyAction();
createShowAdditionalRefsAction();
createShowCommentAction();
createShowFilesAction();
@@ -374,9 +377,9 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
private void createRepositorySwitchAction() {
switchRepositoryAction = new RepositoryToolbarAction(true,
- () -> historyPage.currentRepo,
+ () -> historyPage.getCurrentRepo(),
repo -> {
- Repository current = historyPage.currentRepo;
+ Repository current = historyPage.getCurrentRepo();
if (current != null && repo.getDirectory()
.equals(current.getDirectory())) {
HistoryPageInput currentInput = historyPage
@@ -406,13 +409,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
historyPage.store.setValue(
UIPreferences.RESOURCEHISTORY_SHOW_FINDTOOLBAR,
isChecked());
- if (historyPage.store.needsSaving()) {
- try {
- historyPage.store.save();
- } catch (IOException e) {
- Activator.handleError(e.getMessage(), e, false);
- }
- }
+ historyPage.saveStoreIfNeeded();
historyPage.searchBar.setVisible(isChecked());
}
@@ -520,6 +517,100 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
actionsToDispose.add(showAllBranchesAction);
}
+ private class ShowFirstParentOnlyPrefAction extends Action
+ implements IPropertyChangeListener, IWorkbenchAction {
+
+ ShowFirstParentOnlyPrefAction() {
+ super(UIText.GitHistoryPage_ShowFirstParentOnlyMenuLabel);
+ historyPage.addPropertyChangeListener(this);
+ historyPage.store.addPropertyChangeListener(this);
+ setChecked(historyPage.isShowFirstParentOnly());
+ setImageDescriptor(UIIcons.FIRST_PARENT_ONLY);
+ setToolTipText(UIText.GitHistoryPage_showFirstParentOnly);
+ }
+
+ @Override
+ public void run() {
+ final String prefKey = UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT;
+ Repository repo = historyPage.getCurrentRepo();
+ if (repo != null) {
+ String repoSpecificKey = getRepoSpecificKey(repo, prefKey);
+ boolean newBoolean = isChecked();
+ if (newBoolean == historyPage.store.getBoolean(prefKey)) {
+ historyPage.store.setToDefault(repoSpecificKey);
+ } else {
+ String newValue = newBoolean ? IPreferenceStore.TRUE
+ : IPreferenceStore.FALSE;
+ historyPage.store.putValue(repoSpecificKey, newValue);
+ }
+
+ historyPage.saveStoreIfNeeded();
+ }
+ historyPage.refresh();
+ }
+
+ /**
+ * Applies the new boolean state to the checkbox and refreshes the
+ * historyPage if the state was changed.
+ *
+ * @param newState
+ * the new state to apply.
+ */
+ private void applyNewState(boolean newState) {
+ Control control = historyPage.getControl();
+ if (control != null && !control.isDisposed()) {
+ control.getDisplay().asyncExec(() -> {
+ if (!control.isDisposed()) {
+ setChecked(newState);
+ }
+ });
+ }
+ historyPage.refresh();
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent event) {
+ Repository repo = historyPage.getCurrentRepo();
+
+ final String prefKey = UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT;
+
+ if (repo == null) {
+ if (prefKey.equals(event.getProperty())) {
+ // global first parent preference changed and we have no
+ // current repo. Apply the new global preference
+ applyNewState(historyPage.store.getBoolean(prefKey));
+ }
+ return;
+ }
+
+ String repoSpecificKey = getRepoSpecificKey(repo, prefKey);
+
+ if (prefKey.equals(event.getProperty())) {
+ // global first parent preference changed, if this repo does
+ // not have a repo specific one apply the global one
+ if (!historyPage.store.contains(repoSpecificKey)) {
+ applyNewState(historyPage.store.getBoolean(prefKey));
+ }
+ }
+
+ if (P_REPOSITORY.equals(event.getProperty())) {
+ // The repository was switched. Apply that correct state.
+ applyNewState(historyPage.isShowFirstParentOnly());
+ }
+ }
+
+ @Override
+ public void dispose() {
+ historyPage.removePropertyChangeListener(this);
+ historyPage.store.removePropertyChangeListener(this);
+ }
+ }
+
+ private void createShowFirstParentOnlyAction() {
+ showFirstParentOnlyAction = new ShowFirstParentOnlyPrefAction();
+ actionsToDispose.add(showFirstParentOnlyAction);
+ }
+
private void createShowAdditionalRefsAction() {
showAdditionalRefsAction = new BooleanPrefAction(
UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS,
@@ -818,6 +909,8 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
private boolean currentShowAllBranches;
+ private boolean currentShowFirstParentOnly;
+
private boolean currentShowAdditionalRefs;
private boolean currentShowNotes;
@@ -860,6 +953,29 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
});
}
}
+
+ Object oldValue = event.getOldValue();
+ String pathSep = File.pathSeparator;
+
+ if (oldValue != null) {
+ String[] oldPaths = oldValue.toString().split(pathSep);
+ List<String> removedPaths = new ArrayList<>(
+ Arrays.asList(oldPaths));
+
+ Object newValue = event.getNewValue();
+ if (newValue != null) {
+ String[] newPaths = newValue.toString().split(pathSep);
+ for (String path : newPaths) {
+ removedPaths.remove(path);
+ }
+ }
+
+ for (String path : removedPaths) {
+ unsetRepoSpecificPreference(path,
+ UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT);
+ }
+ saveStoreIfNeeded();
+ }
};
/** Tracks the selection to display the correct input when linked with editors. */
@@ -1425,12 +1541,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
public void widgetDisposed(DisposeEvent e) {
final int[] w = sf.getWeights();
store.putValue(key, UIPreferences.intArrayToString(w));
- if (store.needsSaving())
- try {
- store.save();
- } catch (IOException e1) {
- Activator.handleError(e1.getMessage(), e1, false);
- }
+ saveStoreIfNeeded();
}
});
@@ -1572,6 +1683,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
mgr.add(new Separator());
mgr.add(actions.compareModeAction);
mgr.add(actions.showAllBranchesAction);
+ mgr.add(actions.showFirstParentOnlyAction);
}
private class ColumnAction extends Action implements IUpdate {
@@ -1618,6 +1730,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
UIText.GitHistoryPage_ShowSubMenuLabel);
viewMenuMgr.add(showSubMenuMgr);
showSubMenuMgr.add(actions.showAllBranchesAction);
+ showSubMenuMgr.add(actions.showFirstParentOnlyAction);
showSubMenuMgr.add(actions.showAdditionalRefsAction);
showSubMenuMgr.add(actions.showNotesAction);
showSubMenuMgr.add(actions.followRenamesAction);
@@ -1693,14 +1806,14 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
}
renameTracker.reset(null);
Job.getJobManager().cancel(JobFamilies.HISTORY_DIFF);
- currentRepo = null;
+ setCurrentRepo(null);
selectedObj = null;
super.dispose();
}
@Override
public void setFocus() {
- if (repoHasBeenRemoved(currentRepo)) {
+ if (repoHasBeenRemoved(getCurrentRepo())) {
clearHistoryPage();
graph.getControl().setFocus();
} else {
@@ -1718,7 +1831,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
}
private void clearHistoryPage() {
- currentRepo = null;
+ setCurrentRepo(null);
selectedObj = null;
name = ""; //$NON-NLS-1$
input = null;
@@ -1741,7 +1854,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
@Override
public void refresh() {
- if (repoHasBeenRemoved(currentRepo)) {
+ if (repoHasBeenRemoved(getCurrentRepo())) {
clearHistoryPage();
}
this.input = null;
@@ -2243,6 +2356,19 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
return getInputInternal();
}
+ private Repository getCurrentRepo() {
+ return currentRepo;
+ }
+
+ private void setCurrentRepo(Repository newRepo) {
+ Repository old = getCurrentRepo();
+ this.currentRepo = newRepo;
+
+ if (!Objects.equals(old, newRepo)) {
+ this.firePropertyChange(this, P_REPOSITORY, old, newRepo);
+ }
+ }
+
void setWarningTextInUIThread(final Job j) {
graph.getControl().getDisplay().asyncExec(new Runnable() {
@Override
@@ -2356,7 +2482,7 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
currentHeadId = null;
currentFetchHeadId = null;
selectedObj = null;
- currentRepo = db;
+ setCurrentRepo(db);
clearViewers();
return;
}
@@ -2366,9 +2492,9 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
.getFileList(), db);
boolean repoChanged = false;
- if (!db.equals(currentRepo)) {
+ if (!db.equals(getCurrentRepo())) {
repoChanged = true;
- currentRepo = db;
+ setCurrentRepo(db);
}
boolean objChanged = false;
@@ -2417,6 +2543,10 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
currentShowAllBranches = store
.getBoolean(UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES);
+ boolean isShowFirstParentOnly = isShowFirstParentOnly();
+ boolean firstParentOnlyChanged = currentShowFirstParentOnly != isShowFirstParentOnly;
+ currentShowFirstParentOnly = isShowFirstParentOnly;
+
boolean additionalRefsChange = currentShowAdditionalRefs != store
.getBoolean(UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS);
currentShowAdditionalRefs = store
@@ -2433,8 +2563,9 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
currentFollowRenames = getFollowRenames();
return pathChanged || headChanged || fetchHeadChanged
- || allBranchesChanged || additionalRefsChange
- || showNotesChanged || followRenamesChanged;
+ || allBranchesChanged || firstParentOnlyChanged
+ || additionalRefsChange || showNotesChanged
+ || followRenamesChanged;
}
/**
@@ -2550,11 +2681,76 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
return !o.equals(n);
}
+ private static String getRepoSpecificKey(String repositoryId,
+ String key) {
+ return key + "_" + repositoryId; //$NON-NLS-1$
+ }
+
+ private static String getRepoSpecificKey(@NonNull Repository repo,
+ String key) {
+ String pathString = Activator.getDefault().getRepositoryUtil()
+ .getRelativizedRepositoryPath(repo);
+
+ if (pathString == null) {
+ return getRepoSpecificKey(repo.toString(), key);
+ }
+
+ return getRepoSpecificKey(pathString, key);
+ }
+
+ /**
+ * Unset the repository specific preference of the given key for the
+ * repository represented by the given repository path.
+ * <p>
+ * This method does not save the preference store. Call
+ * {@link #saveStoreIfNeeded()} when appropriate.
+ * </p>
+ *
+ * @param repositoryPath
+ * Representing the repository to remove the preference for
+ * @param key
+ * The preference to remove for the given repository.
+ */
+ private void unsetRepoSpecificPreference(String repositoryPath,
+ String key) {
+ String prefString = getRepoSpecificKey(repositoryPath, key);
+ store.setToDefault(prefString);
+ }
+
+ private void saveStoreIfNeeded() {
+ if (store.needsSaving()) {
+ try {
+ store.save();
+ } catch (IOException e) {
+ Activator.handleError(e.getMessage(), e, false);
+ }
+ }
+ }
+
+ private boolean isShowFirstParentOnly() {
+ final String prefKey = UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT;
+ boolean firstParent = store.getBoolean(prefKey);
+ Repository repo = getCurrentRepo();
+
+ if (repo != null) {
+ String repoSpecificKey = getRepoSpecificKey(repo, prefKey);
+ if (store.contains(repoSpecificKey)) {
+ firstParent = store.getBoolean(repoSpecificKey);
+ }
+ }
+ return firstParent;
+ }
+
private @NonNull SWTWalk createNewWalk(Repository db, AnyObjectId headId,
AnyObjectId fetchHeadId) {
currentHeadId = headId;
currentFetchHeadId = fetchHeadId;
SWTWalk walk = new GitHistoryWalk(db, headId, selectedObj);
+
+ if (isShowFirstParentOnly()) {
+ walk.setFirstParent(true);
+ }
+
try {
if (store
.getBoolean(UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS))
@@ -2731,7 +2927,8 @@ public class GitHistoryPage extends HistoryPage implements RefsChangedListener,
if (paths == null || paths.isEmpty())
throw new IllegalArgumentException("paths must not be null nor empty"); //$NON-NLS-1$
- DiffConfig diffConfig = currentRepo.getConfig().get(DiffConfig.KEY);
+ DiffConfig diffConfig = getCurrentRepo().getConfig()
+ .get(DiffConfig.KEY);
List<TreeFilter> followFilters = new ArrayList<>(paths.size());
for (String path : paths)
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
index 8c0399645..f02c06ff5 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/preferences/HistoryPreferencePage.java
@@ -63,6 +63,10 @@ public class HistoryPreferencePage extends FieldEditorPreferencePage implements
UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES,
UIText.HistoryPreferencePage_toggleAllBranches, showGroup));
addField(new BooleanFieldEditor(
+ UIPreferences.RESOURCEHISTORY_SHOW_FIRST_PARENT_ONLY_DEFAULT,
+ UIText.HistoryPreferencePage_showFirstParentOnlyDefault,
+ showGroup));
+ addField(new BooleanFieldEditor(
UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS,
UIText.HistoryPreferencePage_toggleAdditionalRefs, showGroup));
addField(new BooleanFieldEditor(
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
index 857bcfee2..48cb05abc 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/uitext.properties
@@ -187,6 +187,7 @@ GitHistoryPage_CreateTagMenuLabel=Create &Tag...
GitHistoryPage_cherryPickMenuItem=C&herry-Pick...
GitHistoryPage_compareMode=Compare Mode
GitHistoryPage_showAllBranches=Show All Branches and Tags
+GitHistoryPage_showFirstParentOnly=Show First Parent Only
GitHistoryPage_squashMenuItem=Squash
GitHistoryPage_errorLookingUpPath=IO error looking up path {0} in {1}.
GitHistoryPage_errorParsingHead=Cannot parse HEAD in: {0}
@@ -227,6 +228,7 @@ GitHistoryPage_editMenuItem=&Edit
GitHistoryPage_SetAsBaselineMenuLabel=&Set as Baseline
GitHistoryPage_ShowAdditionalRefsMenuLabel=&Additional Refs
GitHistoryPage_ShowAllBranchesMenuLabel=All &Branches and Tags
+GitHistoryPage_ShowFirstParentOnlyMenuLabel=First &Parent Only
GitHistoryPage_FollowRenames=&Follow Renames
GitHistoryPage_FormatDiffJobName=Updating Diff
GitHistoryPage_FilterSubMenuLabel=&Filter
@@ -729,6 +731,7 @@ HistoryPage_findbar_exceeded=Results limit exceeded
HistoryPage_findbar_notFound=String not found
HistoryPage_findbar_reference=Branch/Tag
HistoryPreferencePage_toggleAllBranches=All &Branches and Tags
+HistoryPreferencePage_showFirstParentOnlyDefault=F&irst parent only by default
HistoryPreferencePage_toggleAdditionalRefs=&Additional Refs
HistoryPreferencePage_toggleEmailAddresses=&E-mail addresses in Author/Committer columns
HistoryPreferencePage_toggleShortenAtStart=&Shorten long tag and branch names at the front

Back to the top