4

We have a gitolite server with our customers custom apps.

Every app has a submodule "repository/core" which refers to our base app.

We would now like to create a dashboard which shows all our customers apps and at which revision there core is at.

gitolite stores everything in bare repositories on disk and the dashboard app has direct access to the repos / or using ssh keys if that's easier.

My question is how would I from a bare repository find out what revision a submodule is at, and who committed it?

NoDataDumpNoContribution
  • 10,591
  • 9
  • 64
  • 104
Leon Radley
  • 7,596
  • 5
  • 35
  • 54

3 Answers3

5

I just had to implement this for a CI server. The tricky part is remaining with a bare checkout.

My solution was as follows:

1) git show HEAD:.gitmodules can be used to get a list of paths which are submodules.

2) for each path =, the third field of this can be used to determine the SHA the submodule is at:

git ls-tree -z -d HEAD -- <submodule path>

pwaller
  • 601
  • 6
  • 10
2

JGit has a SubmoduleStatusCommand that lists all known submodules. Note that this command works only on non-bare repositories.

Git git = Git.open( new File( "/path/to/repo/.git" ) );
Map<String,SubmoduleStatus> submodules = git.submoduleStatus().call();
SubmoduleStatus status = submodules.get( "repository/core" );
ObjectId headId = status.getHeadId();

As you can see, the command returns a map of submodules-names along with their respective SubmoduleStatus which includes the SHA-1 of the HEAD commit.

There is also an article about JGit's submodule API that I wrote some time ago that has some more details.

For a bare repository you would have to read the the submodule's HEAD ID directly from the repository's object database like so:

try( RevWalk revWalk = new RevWalk( repository ) ) {
  RevCommit headCommit = revWalk.parseCommit( repository.resolve( Constants.HEAD ) );
}
try( TreeWalk treeWalk = TreeWalk.forPath( repository, "repository/core", headCommit.getTree() ) ) {
  ObjectId blobId = treeWalk.getObjectId( 0 );
  ObjectLoader objectLoader = repository.open( blobId, Constants.OBJ_BLOB );
  try( InputStream inputStream = objectLoader.openStream() ) {
    // read contents from the input stream
  }
}
Rüdiger Herrmann
  • 20,512
  • 11
  • 62
  • 79
  • I'm new to jGit, what type does "git" have in your example, and where do I get it from? – Leon Radley Sep 24 '14 at 14:32
  • I'm getting NoWorkTreeException: Bare Repository has neither a working tree, nor an index since I'm running this on a bare repository. is there a workaround? – Leon Radley Sep 24 '14 at 14:38
  • Git is a factory class that can be used to create commands(analogous to native Git's porcelain commands). A Git instance is bound to the repository for which it was created. One way to create such a Git instance is via Git.open( File ). See also the now extended answer. – Rüdiger Herrmann Sep 24 '14 at 14:41
  • To work around the `NoWorkTreeException` you could maintain a non-bare clone of the bare repository and run the `SubmoduleStatusCommand ` thereon. Or you resort to the approach of @AlBlue and read the `.gitmodules` directly from the repository's object database. IIRC the submodule's HEAD ID is stored in a file named after the submodules name (repository/core in your case). – Rüdiger Herrmann Sep 25 '14 at 10:00
  • I already know the name of the submodule. So I wouldn't have to read the .gitmodules. But I would really appreciate a code example of how to read the HEAD ID from the object database. – Leon Radley Sep 25 '14 at 10:28
  • @LeonRadley I've updated the answer with a snippet that reads a file from the repository. – Rüdiger Herrmann Sep 25 '14 at 16:14
1

You can list the .gitmodules to find out which paths are deemed to be modules, and then go through them and find out what the <module>.git/HEAD/ reference is pointing to (probably a symbolic reference, like ref: refs/heads/master, which you'd then have to chain to find the value of refs/heads/master). That will then give you the most recent commit hash of that module.

AlBlue
  • 23,254
  • 14
  • 71
  • 91