{"thread":{"id":"12800","subject":"[EGIT PATCH 2/4] Infrastructure to retrieve commit related information.","startedAt":"2008-03-21T22:07:46Z","lastAt":"2008-03-21T22:07:46Z","messageCount":1,"participants":["Roger C. Soares"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"72624","messageId":"1206137266-4055-1-git-send-email-rogersoares@intelinet.com.br","threadId":"12800","inReplyTo":null,"subject":"[EGIT PATCH 2/4] Infrastructure to retrieve commit related information.","fromName":"Roger C. Soares","fromEmail":"rogersoares@intelinet.com.br","sentAt":"2008-03-21T22:07:46Z","receivedAt":"2008-03-21T22:07:46Z","isPatch":true,"sender":{"key":"rogersoares@intelinet.com.br","avatar":null},"body":"Infrastructure to retrieve all the branches that contain a commit,\nthe children of a commit, tags and branches referencing a commit.\n\nIt was added in the core package so it is easier to reuse it.\n\nSigned-off-by: Roger C. Soares <rogersoares@intelinet.com.br>\n---\n org.spearce.egit.core/META-INF/MANIFEST.MF         |    6 +-\n .../org/spearce/egit/core/util/CommitMetaInfo.java |   59 ++++++\n .../org/spearce/egit/core/util/RepositoryUtil.java |  217 ++++++++++++++++++++\n 3 files changed, 279 insertions(+), 3 deletions(-)\n create mode 100644 org.spearce.egit.core/src/org/spearce/egit/core/util/CommitMetaInfo.java\n create mode 100644 org.spearce.egit.core/src/org/spearce/egit/core/util/RepositoryUtil.java\n\ndiff --git a/org.spearce.egit.core/META-INF/MANIFEST.MF b/org.spearce.egit.core/META-INF/MANIFEST.MF\nindex 48ddb91..6dfc2f7 100644\n--- a/org.spearce.egit.core/META-INF/MANIFEST.MF\n+++ b/org.spearce.egit.core/META-INF/MANIFEST.MF\n@@ -11,10 +11,10 @@ Require-Bundle: org.eclipse.core.runtime,\n  org.eclipse.core.resources,\n  org.spearce.jgit,\n  org.eclipse.core.filesystem\n-Export-Package: org.spearce.egit.core.internal.mapping;x-friends:=\"org.spearce.egit.ui\",\n- org.spearce.egit.core,\n+Export-Package: org.spearce.egit.core,\n  org.spearce.egit.core.internal.mapping,\n  org.spearce.egit.core.op,\n- org.spearce.egit.core.project\n+ org.spearce.egit.core.project,\n+ org.spearce.egit.core.util\n Eclipse-LazyStart: true\n Bundle-RequiredExecutionEnvironment: J2SE-1.5\ndiff --git a/org.spearce.egit.core/src/org/spearce/egit/core/util/CommitMetaInfo.java b/org.spearce.egit.core/src/org/spearce/egit/core/util/CommitMetaInfo.java\nnew file mode 100644\nindex 0000000..48de3fb\n--- /dev/null\n+++ b/org.spearce.egit.core/src/org/spearce/egit/core/util/CommitMetaInfo.java\n@@ -0,0 +1,59 @@\n+/*\n+ *  Copyright (C) 2008  Roger C. Soares\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU Lesser General Public\n+ *  License, version 2.1, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  Lesser General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.egit.core.util;\n+\n+import java.util.Set;\n+\n+import org.spearce.jgit.lib.Commit;\n+\n+/**\n+ * This class stores information that are not part of a commit and requires a\n+ * walk through out the repository to be discovered.\n+ */\n+public class CommitMetaInfo {\n+\n+\tprivate Set<String> branchNamesContainingCommit;\n+\n+\tprivate Set<Commit> childrenCommits;\n+\n+\tCommitMetaInfo(Set<String> branchNamesContainingCommit,\n+\t\t\tSet<Commit> childrenCommits) {\n+\t\tthis.branchNamesContainingCommit = branchNamesContainingCommit;\n+\t\tthis.childrenCommits = childrenCommits;\n+\t}\n+\n+\t/**\n+\t * Returns all the branches that contain the commit.\n+\t * \n+\t * @return Set<String> a <code>Set</code> containing the branch names,\n+\t *         sorted in ascending string order or null\n+\t */\n+\tpublic Set<String> getBranchNamesContainingCommit() {\n+\t\treturn branchNamesContainingCommit;\n+\t}\n+\n+\t/**\n+\t * Returns the children commits.\n+\t * \n+\t * @return Set<Commit> a <code>Set</code> containing the children commits\n+\t *         or null.\n+\t */\n+\tpublic Set<Commit> getChildrenCommits() {\n+\t\treturn childrenCommits;\n+\t}\n+\n+}\ndiff --git a/org.spearce.egit.core/src/org/spearce/egit/core/util/RepositoryUtil.java b/org.spearce.egit.core/src/org/spearce/egit/core/util/RepositoryUtil.java\nnew file mode 100644\nindex 0000000..9a08868\n--- /dev/null\n+++ b/org.spearce.egit.core/src/org/spearce/egit/core/util/RepositoryUtil.java\n@@ -0,0 +1,217 @@\n+/*\n+ *  Copyright (C) 2008  Roger C. Soares\n+ *\n+ *  This library is free software; you can redistribute it and/or\n+ *  modify it under the terms of the GNU Lesser General Public\n+ *  License, version 2.1, as published by the Free Software Foundation.\n+ *\n+ *  This library is distributed in the hope that it will be useful,\n+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n+ *  Lesser General Public License for more details.\n+ *\n+ *  You should have received a copy of the GNU Lesser General Public\n+ *  License along with this library; if not, write to the Free Software\n+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301\n+ */\n+package org.spearce.egit.core.util;\n+\n+import java.io.IOException;\n+import java.util.ArrayList;\n+import java.util.HashMap;\n+import java.util.HashSet;\n+import java.util.List;\n+import java.util.Map;\n+import java.util.Set;\n+import java.util.TreeSet;\n+import java.util.concurrent.CancellationException;\n+\n+import org.eclipse.core.runtime.IProgressMonitor;\n+import org.spearce.jgit.lib.Commit;\n+import org.spearce.jgit.lib.ObjectId;\n+import org.spearce.jgit.lib.Repository;\n+import org.spearce.jgit.lib.Tag;\n+\n+/**\n+ * This class provides convenience methods to retrieve Git repository data in a\n+ * digested form.\n+ */\n+public class RepositoryUtil {\n+\n+\tprivate Repository repository;\n+\n+\tprivate Map<ObjectId, Set<String>> sha1ToTagsMap = new HashMap<ObjectId, Set<String>>();\n+\n+\tprivate Map<ObjectId, Set<String>> headCommitToBranchesMap = new HashMap<ObjectId, Set<String>>();\n+\n+\t/**\n+\t * Constructs a <code>RepositoryUtil</code> for the\n+\t * <code>repository</code>.\n+\t * \n+\t * @param repository\n+\t *            the Git repository from where data will be retrieved.\n+\t * @throws IOException\n+\t */\n+\tpublic RepositoryUtil(Repository repository) throws IOException {\n+\t\tthis.repository = repository;\n+\n+\t\trefresh();\n+\t}\n+\n+\t/**\n+\t * Retrieves a <code>Set</code> with all the tags referencing\n+\t * <code>commit<code>.\n+\t * \n+\t * @param commit to be checked for references\n+\t * @return Set<String> the tag names referencing the commit sorted in ascending string order or null\n+\t */\n+\tpublic Set<String> getTagNamesForCommit(Commit commit) {\n+\t\treturn sha1ToTagsMap.get(commit.getCommitId());\n+\t}\n+\n+\t/**\n+\t * Retrieves a <code>Set</code> with all the branch names referencing\n+\t * <code>commit<code>.\n+\t * \n+\t * @param commit\n+\t * @return Set<String> the branch names referencing the commit sorted in ascending string order or null\n+\t */\n+\tpublic Set<String> getBranchNamesForCommit(Commit commit) {\n+\t\treturn headCommitToBranchesMap.get(commit.getCommitId());\n+\t}\n+\n+\t/**\n+\t * Walks through all branches in the repository searching information\n+\t * related to <code>commit</code>. This information is stored in the\n+\t * <code>CommitMetaInfo</code>.\n+\t * \n+\t * @param commit\n+\t *            to be checked for references\n+\t * @param monitor\n+\t *            the monitor from where cancellation is checked or null\n+\t * @return CommitMetaInfo\n+\t * @throws IOException\n+\t * @throws CancellationException\n+\t *             if <code>monitor.isCanceled()</code> returns true during\n+\t *             the execution of this method\n+\t */\n+\tpublic CommitMetaInfo getCommitMetaInfo(Commit commit,\n+\t\t\tIProgressMonitor monitor) throws IOException, CancellationException {\n+\t\tSet<Commit> childrenSet = new HashSet<Commit>();\n+\t\tMap<String, String> allBranches = new HashMap<String, String>();\n+\t\tObjectId commitId = commit.getCommitId();\n+\t\tSet<String> branchNameSet = headCommitToBranchesMap.get(commitId);\n+\t\tif (branchNameSet != null) {\n+\t\t\tfor (String branchName : branchNameSet) {\n+\t\t\t\tallBranches.put(branchName, branchName);\n+\t\t\t}\n+\t\t}\n+\n+\t\t// Verifies all branches for the commit we want\n+\t\tList<ObjectId> commitsToWalk = new ArrayList<ObjectId>();\n+\t\tcommitsToWalk.addAll(headCommitToBranchesMap.keySet());\n+\t\tMap<String, String> tempBranches = new HashMap<String, String>();\n+\t\tMap<ObjectId, Map<String, String>> savedTempBranches = new HashMap<ObjectId, Map<String, String>>();\n+\t\twhile (commitsToWalk.size() > 0) {\n+\t\t\tObjectId branchHead = commitsToWalk.remove(0);\n+\t\t\tCommit headCommit = repository.mapCommit(branchHead);\n+\t\t\tMap<String, String> tb = savedTempBranches.get(branchHead);\n+\t\t\tif (tb == null) {\n+\t\t\t\ttempBranches.clear();\n+\t\t\t\ttb = tempBranches;\n+\t\t\t}\n+\t\t\tlookforMetaInfo(commitId, headCommit, allBranches, childrenSet, tb,\n+\t\t\t\t\tcommitsToWalk, savedTempBranches, monitor);\n+\t\t}\n+\n+\t\tSet<String> keySet = null;\n+\t\tif (allBranches.size() > 0) {\n+\t\t\tkeySet = new TreeSet<String>();\n+\t\t\tkeySet.addAll(allBranches.keySet());\n+\t\t}\n+\t\tif (childrenSet.size() == 0) {\n+\t\t\tchildrenSet = null;\n+\t\t}\n+\n+\t\tCommitMetaInfo metaInfo = new CommitMetaInfo(keySet, childrenSet);\n+\t\treturn metaInfo;\n+\t}\n+\n+\tprivate void lookforMetaInfo(ObjectId targetCommitId, Commit headCommit,\n+\t\t\tMap<String, String> allBranches, Set<Commit> childrenSet,\n+\t\t\tMap<String, String> tempBranches, List<ObjectId> commitsToWalk,\n+\t\t\tMap<ObjectId, Map<String, String>> savedTempBranches,\n+\t\t\tIProgressMonitor monitor) throws IOException, CancellationException {\n+\t\tCommit child = null;\n+\t\tCommit commit = headCommit;\n+\t\tObjectId commitId = commit.getCommitId();\n+\t\twhile (!commitId.equals(targetCommitId)) {\n+\t\t\tchild = commit;\n+\t\t\tSet<String> branchNameSet = headCommitToBranchesMap.get(commit\n+\t\t\t\t\t.getCommitId());\n+\t\t\tif (branchNameSet != null) {\n+\t\t\t\tfor (String branchName : branchNameSet) {\n+\t\t\t\t\ttempBranches.put(branchName, branchName);\n+\t\t\t\t}\n+\t\t\t}\n+\t\t\tObjectId[] pIds = commit.getParentIds();\n+\t\t\tif (pIds != null && pIds.length > 0) {\n+\t\t\t\tcommit = repository.mapCommit(pIds[0]);\n+\t\t\t\tcommitId = commit.getCommitId();\n+\t\t\t\tint parentCount = pIds.length;\n+\t\t\t\tif (parentCount > 1) {\n+\t\t\t\t\tfor (int i = 1; i < parentCount; i++) {\n+\t\t\t\t\t\tcommitsToWalk.add(pIds[i]);\n+\t\t\t\t\t\tMap<String, String> tb = savedTempBranches.get(pIds[i]);\n+\t\t\t\t\t\tif (tb == null) {\n+\t\t\t\t\t\t\ttb = new HashMap<String, String>();\n+\t\t\t\t\t\t\tsavedTempBranches.put(pIds[i], tb);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\ttb.putAll(tempBranches);\n+\t\t\t\t\t\tif (pIds[i].equals(targetCommitId)) {\n+\t\t\t\t\t\t\tchildrenSet.add(child);\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t}\n+\t\t\t} else {\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\tif (monitor != null && monitor.isCanceled()) {\n+\t\t\t\tthrow new CancellationException(\"getCommitMetaInfo cancelled\");\n+\t\t\t}\n+\t\t}\n+\t\tif (commitId.equals(targetCommitId)) {\n+\t\t\tallBranches.putAll(tempBranches);\n+\t\t\tif (child != null) {\n+\t\t\t\tchildrenSet.add(child);\n+\t\t\t}\n+\t\t}\n+\t}\n+\n+\tprivate void refresh() throws IOException {\n+\t\t// Refresh tags\n+\t\tsha1ToTagsMap.clear();\n+\t\tfor (String tagName : repository.getTags()) {\n+\t\t\tTag tag = repository.mapTag(tagName);\n+\t\t\tSet<String> tagSet = sha1ToTagsMap.get(tag.getObjId());\n+\t\t\tif (tagSet == null) {\n+\t\t\t\ttagSet = new TreeSet<String>();\n+\t\t\t\tsha1ToTagsMap.put(tag.getObjId(), tagSet);\n+\t\t\t}\n+\t\t\ttagSet.add(tag.getTag());\n+\t\t}\n+\n+\t\t// Refresh branches\n+\t\theadCommitToBranchesMap.clear();\n+\t\tfor (String branchName : repository.getBranches()) {\n+\t\t\tObjectId commitId = repository.resolve(branchName);\n+\t\t\tSet<String> branchSet = headCommitToBranchesMap.get(commitId);\n+\t\t\tif (branchSet == null) {\n+\t\t\t\tbranchSet = new TreeSet<String>();\n+\t\t\t\theadCommitToBranchesMap.put(commitId, branchSet);\n+\t\t\t}\n+\t\t\tbranchSet.add(branchName);\n+\t\t}\n+\t}\n+\n+}\n-- \n1.5.4.1\n"}]}