From eb870fc034460c2bab69039b21049d332a002ca1 Mon Sep 17 00:00:00 2001 From: James Moger <james.moger@gitblit.com> Date: Fri, 10 Aug 2012 17:46:11 -0400 Subject: [PATCH] Submodules support --- src/com/gitblit/utils/JGitUtils.java | 80 ++++++++++++++++++++++++++++++++++----- 1 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/com/gitblit/utils/JGitUtils.java b/src/com/gitblit/utils/JGitUtils.java index 90e6a76..5eb83ed 100644 --- a/src/com/gitblit/utils/JGitUtils.java +++ b/src/com/gitblit/utils/JGitUtils.java @@ -45,7 +45,9 @@ import org.eclipse.jgit.errors.IncorrectObjectTypeException; import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.errors.StopWalkException; +import org.eclipse.jgit.lib.BlobBasedConfig; import org.eclipse.jgit.lib.CommitBuilder; +import org.eclipse.jgit.lib.Config; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.ObjectId; @@ -87,6 +89,7 @@ import com.gitblit.models.PathModel; import com.gitblit.models.PathModel.PathChangeModel; import com.gitblit.models.RefModel; +import com.gitblit.models.SubmoduleModel; /** * Collection of static methods for retrieving information from a repository. @@ -732,7 +735,8 @@ tw.addTree(commit.getTree()); while (tw.next()) { list.add(new PathChangeModel(tw.getPathString(), tw.getPathString(), 0, tw - .getRawMode(0), commit.getId().getName(), ChangeType.ADD)); + .getRawMode(0), tw.getObjectId(0).getName(), commit.getId().getName(), + ChangeType.ADD)); } tw.release(); } else { @@ -745,15 +749,15 @@ for (DiffEntry diff : diffs) { if (diff.getChangeType().equals(ChangeType.DELETE)) { list.add(new PathChangeModel(diff.getOldPath(), diff.getOldPath(), 0, diff - .getNewMode().getBits(), commit.getId().getName(), diff + .getNewMode().getBits(), null, commit.getId().getName(), diff .getChangeType())); } else if (diff.getChangeType().equals(ChangeType.RENAME)) { list.add(new PathChangeModel(diff.getOldPath(), diff.getNewPath(), 0, diff - .getNewMode().getBits(), commit.getId().getName(), diff + .getNewMode().getBits(), null, commit.getId().getName(), diff .getChangeType())); } else { list.add(new PathChangeModel(diff.getNewPath(), diff.getNewPath(), 0, diff - .getNewMode().getBits(), commit.getId().getName(), diff + .getNewMode().getBits(), null, commit.getId().getName(), diff .getChangeType())); } } @@ -846,15 +850,16 @@ } else { name = tw.getPathString().substring(basePath.length() + 1); } + ObjectId objectId = tw.getObjectId(0); try { - if (!tw.isSubtree()) { - size = tw.getObjectReader().getObjectSize(tw.getObjectId(0), Constants.OBJ_BLOB); + if (!tw.isSubtree() && (tw.getFileMode(0) != FileMode.GITLINK)) { + size = tw.getObjectReader().getObjectSize(objectId, Constants.OBJ_BLOB); } } catch (Throwable t) { error(t, null, "failed to retrieve blob size for " + tw.getPathString()); } return new PathModel(name, tw.getPathString(), size, tw.getFileMode(0).getBits(), - commit.getName()); + objectId.getName(), commit.getName()); } /** @@ -871,13 +876,10 @@ } else if (FileMode.EXECUTABLE_FILE.equals(mode)) { return "-rwxr-xr-x"; } else if (FileMode.SYMLINK.equals(mode)) { - // FIXME symlink permissions return "symlink"; } else if (FileMode.GITLINK.equals(mode)) { - // FIXME gitlink permissions - return "gitlink"; + return "submodule"; } - // FIXME missing permissions return "missing"; } @@ -1533,6 +1535,62 @@ } return branch; } + + /** + * Returns the list of submodules for this repository. + * + * @param repository + * @param commit + * @return list of submodules + */ + public static List<SubmoduleModel> getSubmodules(Repository repository, String commitId) { + RevCommit commit = getCommit(repository, commitId); + return getSubmodules(repository, commit.getTree()); + } + + /** + * Returns the list of submodules for this repository. + * + * @param repository + * @param commit + * @return list of submodules + */ + public static List<SubmoduleModel> getSubmodules(Repository repository, RevTree tree) { + List<SubmoduleModel> list = new ArrayList<SubmoduleModel>(); + byte [] blob = getByteContent(repository, tree, ".gitmodules"); + if (blob == null) { + return list; + } + try { + BlobBasedConfig config = new BlobBasedConfig(repository.getConfig(), blob); + for (String module : config.getSubsections("submodule")) { + String path = config.getString("submodule", module, "path"); + String url = config.getString("submodule", module, "url"); + list.add(new SubmoduleModel(module, path, url)); + } + } catch (ConfigInvalidException e) { + LOGGER.error("Failed to load .gitmodules file for " + repository.getDirectory(), e); + } + return list; + } + + /** + * Returns the submodule definition for the specified path at the specified + * commit. If no module is defined for the path, null is returned. + * + * @param repository + * @param commit + * @param path + * @return a submodule definition or null if there is no submodule + */ + public static SubmoduleModel getSubmoduleModel(Repository repository, String commitId, String path) { + for (SubmoduleModel model : getSubmodules(repository, commitId)) { + if (model.path.equals(path)) { + return model; + } + } + return null; + } /** * Returns the list of notes entered about the commit from the refs/notes -- Gitblit v1.9.1