]> source.dussan.org Git - gitblit.git/commitdiff
Improve history display of a submodule link
authorJames Moger <james.moger@gitblit.com>
Sun, 13 Jan 2013 23:09:58 +0000 (18:09 -0500)
committerJames Moger <james.moger@gitblit.com>
Sun, 13 Jan 2013 23:09:58 +0000 (18:09 -0500)
docs/04_releases.mkd
src/com/gitblit/utils/JGitUtils.java
src/com/gitblit/wicket/panels/HistoryPanel.java

index ee31b69261a9060de6f66d783dfd66dd7f16fe87..fa088b2a2e9346a4dd2d4c2a5c34df23108d5520 100644 (file)
@@ -30,6 +30,7 @@ The push log is not currently visible in the ui, but the data will be collected
 \r
 #### changes\r
 \r
+- Improve history display of a submodule link\r
 - Updated Korean translation (github/ds5apn)\r
 - Updated checkstyle definition (github/mystygage)\r
 \r
index 815f8b5acc8527c5b39c9f76bcb19e543fbafe44..1f2ae943be017b67e250950bce591e7ab479b913 100644 (file)
@@ -1616,6 +1616,32 @@ public class JGitUtils {
                }\r
                return null;\r
        }\r
+       \r
+       public static String getSubmoduleCommitId(Repository repository, String path, RevCommit commit) {\r
+               String commitId = null;\r
+               RevWalk rw = new RevWalk(repository);\r
+               TreeWalk tw = new TreeWalk(repository);\r
+               tw.setFilter(PathFilterGroup.createFromStrings(Collections.singleton(path)));\r
+               try {\r
+                       tw.reset(commit.getTree());\r
+                       while (tw.next()) {\r
+                               if (tw.isSubtree() && !path.equals(tw.getPathString())) {\r
+                                       tw.enterSubtree();\r
+                                       continue;\r
+                               }\r
+                               if (FileMode.GITLINK == tw.getFileMode(0)) {\r
+                                       commitId = tw.getObjectId(0).getName();\r
+                                       break;\r
+                               }\r
+                       }\r
+               } catch (Throwable t) {\r
+                       error(t, repository, "{0} can't find {1} in commit {2}", path, commit.name());\r
+               } finally {\r
+                       rw.dispose();\r
+                       tw.release();\r
+               }\r
+               return commitId;\r
+       }\r
 \r
        /**\r
         * Returns the list of notes entered about the commit from the refs/notes\r
index 0f586031129b78972dfcea4406e15e163eb35883..e5878635ed706b5ce694aec33bb7b006cebf095d 100644 (file)
  */\r
 package com.gitblit.wicket.panels;\r
 \r
+import java.util.ArrayList;\r
 import java.util.Collections;\r
 import java.util.Date;\r
+import java.util.HashMap;\r
+import java.util.LinkedHashSet;\r
 import java.util.List;\r
 import java.util.Map;\r
+import java.util.Set;\r
 \r
 import org.apache.wicket.markup.html.basic.Label;\r
 import org.apache.wicket.markup.html.link.BookmarkablePageLink;\r
@@ -38,6 +42,7 @@ import com.gitblit.Constants;
 import com.gitblit.GitBlit;\r
 import com.gitblit.Keys;\r
 import com.gitblit.models.PathModel;\r
+import com.gitblit.models.SubmoduleModel;\r
 import com.gitblit.models.PathModel.PathChangeModel;\r
 import com.gitblit.models.RefModel;\r
 import com.gitblit.utils.JGitUtils;\r
@@ -69,6 +74,11 @@ public class HistoryPanel extends BasePanel {
                RevCommit commit = JGitUtils.getCommit(r, objectId);\r
                List<PathChangeModel> paths = JGitUtils.getFilesInCommit(r, commit);\r
 \r
+               Map<String, SubmoduleModel> submodules = new HashMap<String, SubmoduleModel>();\r
+               for (SubmoduleModel model : JGitUtils.getSubmodules(r, commit.getTree())) {\r
+                       submodules.put(model.path, model);\r
+               }\r
+\r
                PathModel matchingPath = null;\r
                for (PathModel p : paths) {\r
                        if (p.path.equals(path)) {\r
@@ -99,7 +109,20 @@ public class HistoryPanel extends BasePanel {
                }\r
                \r
                final boolean isTree = matchingPath == null ? true : matchingPath.isTree();\r
+               final boolean isSubmodule = matchingPath == null ? true : matchingPath.isSubmodule();\r
 \r
+               // submodule\r
+               SubmoduleModel submodule = getSubmodule(submodules, repositoryName, matchingPath.path);\r
+               final String submodulePath;\r
+               final boolean hasSubmodule; \r
+               if (submodule != null) {\r
+                       submodulePath = submodule.gitblitPath;\r
+                       hasSubmodule = submodule.hasSubmodule;\r
+               } else {\r
+                       submodulePath = "";\r
+                       hasSubmodule = false;\r
+               }\r
+               \r
                final Map<ObjectId, List<RefModel>> allRefs = JGitUtils.getAllRefs(r, showRemoteRefs);\r
                List<RevCommit> commits;\r
                if (pageResults) {\r
@@ -175,6 +198,23 @@ public class HistoryPanel extends BasePanel {
                                        WicketUtils.setHtmlTooltip(commitHash, entry.getName());                                        \r
                                        item.add(commitHash);\r
                                        \r
+                                       Fragment links = new Fragment("historyLinks", "treeLinks", this);\r
+                                       links.add(new BookmarkablePageLink<Void>("commitdiff", CommitDiffPage.class,\r
+                                                       WicketUtils.newObjectParameter(repositoryName, entry.getName())));\r
+                                       item.add(links);\r
+                               } else if (isSubmodule) {\r
+                                       // submodule\r
+                                       item.add(new Label("hashLabel", submodulePath + "@"));\r
+                                       Repository repository = GitBlit.self().getRepository(repositoryName);\r
+                                       String submoduleId = JGitUtils.getSubmoduleCommitId(repository, path, entry);\r
+                                       repository.close();\r
+                                       LinkPanel commitHash = new LinkPanel("hashLink", null, submoduleId.substring(0, hashLen),\r
+                                                       TreePage.class, WicketUtils.newObjectParameter(\r
+                                                                       submodulePath, submoduleId));\r
+                                       WicketUtils.setCssClass(commitHash, "shortsha1");\r
+                                       WicketUtils.setHtmlTooltip(commitHash, submoduleId);                                    \r
+                                       item.add(commitHash.setEnabled(hasSubmodule));\r
+                                       \r
                                        Fragment links = new Fragment("historyLinks", "treeLinks", this);\r
                                        links.add(new BookmarkablePageLink<Void>("commitdiff", CommitDiffPage.class,\r
                                                        WicketUtils.newObjectParameter(repositoryName, entry.getName())));\r
@@ -230,4 +270,66 @@ public class HistoryPanel extends BasePanel {
        public boolean hasMore() {\r
                return hasMore;\r
        }\r
+       \r
+       protected SubmoduleModel getSubmodule(Map<String, SubmoduleModel> submodules, String repositoryName, String path) {\r
+               SubmoduleModel model = submodules.get(path);\r
+               if (model == null) {\r
+                       // undefined submodule?!\r
+                       model = new SubmoduleModel(path.substring(path.lastIndexOf('/') + 1), path, path);\r
+                       model.hasSubmodule = false;\r
+                       model.gitblitPath = model.name;\r
+                       return model;\r
+               } else {\r
+                       // extract the repository name from the clone url\r
+                       List<String> patterns = GitBlit.getStrings(Keys.git.submoduleUrlPatterns);\r
+                       String submoduleName = StringUtils.extractRepositoryPath(model.url, patterns.toArray(new String[0]));\r
+                       \r
+                       // determine the current path for constructing paths relative\r
+                       // to the current repository\r
+                       String currentPath = "";\r
+                       if (repositoryName.indexOf('/') > -1) {\r
+                               currentPath = repositoryName.substring(0, repositoryName.lastIndexOf('/') + 1);\r
+                       }\r
+\r
+                       // try to locate the submodule repository\r
+                       // prefer bare to non-bare names\r
+                       List<String> candidates = new ArrayList<String>();\r
+\r
+                       // relative\r
+                       candidates.add(currentPath + StringUtils.stripDotGit(submoduleName));\r
+                       candidates.add(candidates.get(candidates.size() - 1) + ".git");\r
+\r
+                       // relative, no subfolder\r
+                       if (submoduleName.lastIndexOf('/') > -1) {\r
+                               String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);\r
+                               candidates.add(currentPath + StringUtils.stripDotGit(name));\r
+                               candidates.add(currentPath + candidates.get(candidates.size() - 1) + ".git");\r
+                       }\r
+\r
+                       // absolute\r
+                       candidates.add(StringUtils.stripDotGit(submoduleName));\r
+                       candidates.add(candidates.get(candidates.size() - 1) + ".git");\r
+\r
+                       // absolute, no subfolder\r
+                       if (submoduleName.lastIndexOf('/') > -1) {\r
+                               String name = submoduleName.substring(submoduleName.lastIndexOf('/') + 1);\r
+                               candidates.add(StringUtils.stripDotGit(name));\r
+                               candidates.add(candidates.get(candidates.size() - 1) + ".git");\r
+                       }\r
+\r
+                       // create a unique, ordered set of candidate paths\r
+                       Set<String> paths = new LinkedHashSet<String>(candidates);\r
+                       for (String candidate : paths) {\r
+                               if (GitBlit.self().hasRepository(candidate)) {\r
+                                       model.hasSubmodule = true;\r
+                                       model.gitblitPath = candidate;\r
+                                       return model;\r
+                               }\r
+                       }\r
+                       \r
+                       // we do not have a copy of the submodule, but we need a path\r
+                       model.gitblitPath = candidates.get(0);\r
+                       return model;\r
+               }               \r
+       }\r
 }\r