Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Aniszczyk2010-05-20 15:21:19 +0000
committerCode Review2010-05-20 15:21:19 +0000
commit3b3eb627c638c96408319420fd7eddb66d733b20 (patch)
tree52b32cd4cf4b6f18969d6208a08bc58f56939938
parent752999b62b7ec2041e69d88cf3f43f5bc35d13a3 (diff)
parent0dd8734e72664d0d76b1fee70ac5ed79eaaf9b69 (diff)
downloadegit-3b3eb627c638c96408319420fd7eddb66d733b20.tar.gz
egit-3b3eb627c638c96408319420fd7eddb66d733b20.tar.xz
egit-3b3eb627c638c96408319420fd7eddb66d733b20.zip
Merge "Git Label Decorations of "detached" HEAD"
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java11
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/RepositoryUtil.java219
-rw-r--r--org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java19
3 files changed, 241 insertions, 8 deletions
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java
index 19d4dcf641..4dd3cd8399 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/Activator.java
@@ -69,6 +69,8 @@ public class Activator extends AbstractUIPlugin {
*/
public static final String DECORATORS_CHANGED = "org.eclipse.egit.ui.DECORATORS_CHANGED"; //$NON-NLS-1$
+ private RepositoryUtil repositoryUtil;
+
/**
* @return the {@link Activator} singleton.
*/
@@ -159,6 +161,7 @@ public class Activator extends AbstractUIPlugin {
public void start(final BundleContext context) throws Exception {
super.start(context);
+ repositoryUtil = new RepositoryUtil();
if (isDebugging()) {
ServiceTracker debugTracker = new ServiceTracker(context,
@@ -401,6 +404,8 @@ public class Activator extends AbstractUIPlugin {
GitTraceLocation.getTrace().trace(
GitTraceLocation.UI.getLocation(), "Jobs terminated"); //$NON-NLS-1$
+ repositoryUtil.dispose();
+ repositoryUtil = null;
super.stop(context);
plugin = null;
}
@@ -433,4 +438,10 @@ public class Activator extends AbstractUIPlugin {
return new Status(IStatus.ERROR, getPluginId(), message, throwable);
}
+ /**
+ * @return the {@link RepositoryUtil} instance
+ */
+ public RepositoryUtil getRepositoryUtil() {
+ return repositoryUtil;
+ }
}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/RepositoryUtil.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/RepositoryUtil.java
new file mode 100644
index 0000000000..8d3326dba5
--- /dev/null
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/RepositoryUtil.java
@@ -0,0 +1,219 @@
+/*******************************************************************************
+ * Copyright (c) 2010 SAP AG.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Mathias Kinzler (SAP AG) - initial implementation
+ *******************************************************************************/
+package org.eclipse.egit.ui;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Ref;
+import org.eclipse.jgit.lib.Repository;
+import org.eclipse.jgit.lib.Tag;
+
+/**
+ * Utility class for handling Repositories in the UI.
+ */
+public class RepositoryUtil {
+
+ private final Map<String, Map<String, String>> commitMappingCache = new HashMap<String, Map<String, String>>();
+
+ private final Map<String, String> repositoryNameCache = new HashMap<String, String>();
+
+ /**
+ * Clients should obtain an instance from {@link Activator}
+ */
+ RepositoryUtil() {
+ // nothing
+ }
+
+ /**
+ * Used by {@link Activator}
+ */
+ void dispose() {
+ commitMappingCache.clear();
+ repositoryNameCache.clear();
+ }
+
+ /**
+ * Tries to map a commit to a symbolic reference.
+ * <p>
+ * This value will be cached for the given commit ID unless refresh is
+ * specified. The return value will be the full name, e.g.
+ * "refs/remotes/someBranch", "refs/tags/v.1.0"
+ * <p>
+ * Since this mapping is not unique, the following precedence rules are
+ * used:
+ * <ul>
+ * <li>Tags take precedence over branches</li>
+ * <li>Local branches take preference over remote branches</li>
+ * <li>Newer references take precedence over older ones where time stamps
+ * are available</li>
+ * <li>If there are still ambiguities, the reference name with the highest
+ * lexicographic value will be returned</li>
+ * </ul>
+ *
+ * @param repository
+ * the {@link Repository}
+ * @param commitId
+ * a commit
+ * @param refresh
+ * if true, the cache will be invalidated
+ * @return the symbolic reference, or <code>null</code> if no such reference
+ * can be found
+ */
+ public String mapCommitToRef(Repository repository, String commitId,
+ boolean refresh) {
+
+ synchronized (commitMappingCache) {
+
+ if (!ObjectId.isId(commitId)) {
+ return null;
+ }
+
+ Map<String, String> cacheEntry = commitMappingCache.get(repository
+ .getDirectory().toString());
+ if (!refresh && cacheEntry != null
+ && cacheEntry.containsKey(commitId)) {
+ // this may be null in fact
+ return cacheEntry.get(commitId);
+ }
+ if (cacheEntry == null) {
+ cacheEntry = new HashMap<String, String>();
+ commitMappingCache.put(repository.getDirectory().getPath(),
+ cacheEntry);
+ } else {
+ cacheEntry.clear();
+ }
+
+ Map<String, Date> tagMap = new HashMap<String, Date>();
+ try {
+ Map<String, Ref> tags = repository.getRefDatabase().getRefs(
+ Constants.R_TAGS);
+ for (Ref tagRef : tags.values()) {
+ Tag tag = repository.mapTag(tagRef.getName());
+ if (tag.getObjId().name().equals(commitId)) {
+ Date timestamp;
+ if (tag.getTagger() != null) {
+ timestamp = tag.getTagger().getWhen();
+ } else {
+ timestamp = null;
+ }
+ tagMap.put(tagRef.getName(), timestamp);
+ }
+ }
+ } catch (IOException e) {
+ // ignore here
+ }
+
+ String cacheValue = null;
+
+ if (!tagMap.isEmpty()) {
+ // we try to obtain the "latest" tag
+ Date compareDate = new Date(0);
+ for (Map.Entry<String, Date> tagEntry : tagMap.entrySet()) {
+ if (tagEntry.getValue() != null
+ && tagEntry.getValue().after(compareDate)) {
+ compareDate = tagEntry.getValue();
+ cacheValue = tagEntry.getKey();
+ }
+ }
+ // if we don't have time stamps, we sort
+ if (cacheValue == null) {
+ String compareString = ""; //$NON-NLS-1$
+ for (String tagName : tagMap.keySet()) {
+ if (tagName.compareTo(compareString) >= 0) {
+ cacheValue = tagName;
+ compareString = tagName;
+ }
+ }
+ }
+ }
+
+ if (cacheValue == null) {
+ // we didnt't find a tag, so let's look for local branches
+ Set<String> branchNames = new TreeSet<String>();
+ // put this into a sorted set
+ try {
+ Map<String, Ref> remoteBranches = repository
+ .getRefDatabase().getRefs(Constants.R_HEADS);
+ for (Ref branch : remoteBranches.values()) {
+ if (branch.getObjectId().name().equals(commitId)) {
+ branchNames.add(branch.getName());
+ }
+ }
+ } catch (IOException e) {
+ // ignore here
+ }
+ if (!branchNames.isEmpty()) {
+ // get the last (sorted) entry
+ cacheValue = branchNames.toArray(new String[branchNames
+ .size()])[branchNames.size() - 1];
+ }
+ }
+
+ if (cacheValue == null) {
+ // last try: remote branches
+ Set<String> branchNames = new TreeSet<String>();
+ // put this into a sorted set
+ try {
+ Map<String, Ref> remoteBranches = repository
+ .getRefDatabase().getRefs(Constants.R_REMOTES);
+ for (Ref branch : remoteBranches.values()) {
+ if (branch.getObjectId().name().equals(commitId)) {
+ branchNames.add(branch.getName());
+ }
+ }
+ if (!branchNames.isEmpty()) {
+ // get the last (sorted) entry
+ cacheValue = branchNames.toArray(new String[branchNames
+ .size()])[branchNames.size() - 1];
+ }
+ } catch (IOException e) {
+ // ignore here
+ }
+ }
+ cacheEntry.put(commitId, cacheValue);
+ return cacheValue;
+ }
+ }
+
+ /**
+ * Return a cached UI "name" for a Repository
+ * <p>
+ * This uses the name of the parent of the repository's directory.
+ *
+ * @param repository
+ * @return the name
+ */
+ public String getRepositoryName(Repository repository) {
+ synchronized (repositoryNameCache) {
+ File gitDir = repository.getDirectory();
+ if (gitDir != null) {
+ String name = repositoryNameCache.get(gitDir.getPath()
+ .toString());
+ if (name != null) {
+ return name;
+ }
+ name = gitDir.getParentFile().getName();
+ repositoryNameCache.put(gitDir.getPath().toString(), name);
+ return name;
+ }
+ }
+ return ""; //$NON-NLS-1$
+ }
+
+}
diff --git a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
index d480a730e8..f6fe2b087c 100644
--- a/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
+++ b/org.eclipse.egit.ui/src/org/eclipse/egit/ui/internal/decorators/DecoratableResourceAdapter.java
@@ -91,13 +91,8 @@ class DecoratableResourceAdapter implements IDecoratableResource {
headId = repository.resolve(Constants.HEAD);
store = Activator.getDefault().getPreferenceStore();
+ repositoryName = Activator.getDefault().getRepositoryUtil().getRepositoryName(repository);
- File gitDir = repository.getDirectory();
- if (gitDir != null)
- repositoryName = repository.getDirectory().getParentFile()
- .getName();
- else
- repositoryName = ""; //$NON-NLS-1$
branch = getShortBranch();
TreeWalk treeWalk = createThreeWayTreeWalk();
@@ -120,8 +115,16 @@ class DecoratableResourceAdapter implements IDecoratableResource {
private String getShortBranch() throws IOException {
Ref head = repository.getRef(Constants.HEAD);
- if (head != null && !head.isSymbolic())
- return repository.getFullBranch().substring(0, 7) + "..."; //$NON-NLS-1$
+ if (head != null && !head.isSymbolic()) {
+ String refString = Activator.getDefault().getRepositoryUtil()
+ .mapCommitToRef(repository, repository.getFullBranch(),
+ false);
+ if (refString != null) {
+ return repository.getFullBranch().substring(0, 7)
+ + "... (" + refString + ")"; //$NON-NLS-1$ //$NON-NLS-2$
+ } else
+ return repository.getFullBranch().substring(0, 7) + "..."; //$NON-NLS-1$
+ }
return repository.getBranch();
}

Back to the top