Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryWalk.java')
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryWalk.java145
1 files changed, 145 insertions, 0 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryWalk.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryWalk.java
new file mode 100644
index 0000000000..ec5fd7c7d5
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/history/GitHistoryWalk.java
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright (C) 2018, Thomas Wolf <thomas.wolf@paranor.ch>
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *******************************************************************************/
+package org.eclipse.egit.ui.internal.history;
+
+import java.io.IOException;
+import java.text.MessageFormat;
+
+import org.eclipse.egit.ui.Activator;
+import org.eclipse.egit.ui.UIPreferences;
+import org.eclipse.egit.ui.internal.UIText;
+import org.eclipse.jface.preference.IPreferenceStore;
+import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.MissingObjectException;
+import org.eclipse.jgit.lib.AnyObjectId;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.RefDatabase;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevObject;
+
+/**
+ * An {@link SWTWalk} that sets its start points on the first call to next()
+ * depending on the git history preferences. The point of doing so is to be sure
+ * that potentially expensive operations are done in the GerenrateHistoryJob and
+ * not in the UI thread.
+ */
+class GitHistoryWalk extends SWTWalk {
+
+ private boolean initialized = false;
+
+ private final AnyObjectId headId;
+
+ GitHistoryWalk(Repository repository, AnyObjectId headId) {
+ super(repository);
+ this.headId = headId;
+ }
+
+ @Override
+ public RevCommit next() throws MissingObjectException,
+ IncorrectObjectTypeException, IOException {
+ if (!initialized) {
+ initialize();
+ }
+ return super.next();
+ }
+
+ @Override
+ protected void reset(int retainFlags) {
+ super.reset(retainFlags);
+ initialized = false;
+ }
+
+ /**
+ * Set the walk's start points as defined by the git history preferences.
+ *
+ * @throws IOException
+ * on errors
+ */
+ private void initialize() throws IOException {
+ IPreferenceStore store = Activator.getDefault().getPreferenceStore();
+ RefDatabase db = getRepository().getRefDatabase();
+ try {
+ if (store.getBoolean(
+ UIPreferences.RESOURCEHISTORY_SHOW_ALL_BRANCHES)) {
+ markStartAllRefs(db, Constants.R_HEADS);
+ markStartAllRefs(db, Constants.R_REMOTES);
+ markStartAllRefs(db, Constants.R_TAGS);
+ }
+ if (store.getBoolean(
+ UIPreferences.RESOURCEHISTORY_SHOW_ADDITIONAL_REFS)) {
+ markStartAdditionalRefs(db);
+ }
+ if (store.getBoolean(UIPreferences.RESOURCEHISTORY_SHOW_NOTES)) {
+ markStartAllRefs(db, Constants.R_NOTES);
+ } else {
+ markUninteresting(db, Constants.R_NOTES);
+ }
+ markStart(parseCommit(headId));
+ } catch (IOException e) {
+ throw new IOException(MessageFormat.format(
+ UIText.GitHistoryPage_errorSettingStartPoints,
+ Activator.getDefault().getRepositoryUtil()
+ .getRepositoryName(getRepository())),
+ e);
+ }
+ initialized = true;
+ }
+
+ private void markStartAllRefs(RefDatabase db, String prefix)
+ throws IOException, IncorrectObjectTypeException {
+ for (Ref ref : db.getRefsByPrefix(prefix)) {
+ if (!ref.isSymbolic()) {
+ markStartRef(ref);
+ }
+ }
+ }
+
+ private void markStartAdditionalRefs(RefDatabase db)
+ throws IOException, IncorrectObjectTypeException {
+ for (Ref ref : db.getAdditionalRefs()) {
+ markStartRef(ref);
+ }
+ }
+
+ private void markStartRef(Ref ref)
+ throws IOException, IncorrectObjectTypeException {
+ try {
+ RevObject refTarget = parseAny(ref.getLeaf().getObjectId());
+ RevObject peeled = peel(refTarget);
+ if (peeled instanceof RevCommit) {
+ markStart((RevCommit) peeled);
+ }
+ } catch (MissingObjectException e) {
+ // If there is a ref which points to Nirvana then we should simply
+ // ignore this ref. We should not let a corrupt ref cause that the
+ // history view is not filled at all.
+ }
+ }
+
+ private void markUninteresting(RefDatabase db, String prefix)
+ throws IOException, IncorrectObjectTypeException {
+ for (Ref ref : db.getRefsByPrefix(prefix)) {
+ if (!ref.isSymbolic()) {
+ try {
+ RevObject refTarget = parseAny(ref.getLeaf().getObjectId());
+ if (refTarget instanceof RevCommit) {
+ markUninteresting((RevCommit) refTarget);
+ }
+ } catch (MissingObjectException e) {
+ // See above.
+ }
+ }
+ }
+ }
+
+}

Back to the top