Is there any way to see the current target SHA of a GitHub repository submodule via Octokit[.net] (without cloning it locally)?
I've been able to track down all the submodules by retrieving the .gitmodules file from the "parent" repo, but that file doesn't maintain where the submodule is pointing with in that submodule repo.
After finding someone getting this information by indexing into a commit by the submodule path using LibGit2Sharp, I gave that a similar try in Octokit.
var submodulePathContents = await repositoriesClient.Content.GetAllContents(parentRepoId, "path/to/submodule");
While stepping through this code in the debugger, I see this in Locals/Autos, so it definitely knew I was pointing it to a submodule path.
System.Collections.Generic.IReadOnlyList.this[int].get Name: mono-tools Path: path/to/submodule Type:Submodule Octokit.RepositoryContent
Unfortunately, when I get the actual content from that list, submodulePathContents[0].Content is just null.
The GitHub web interface definitely surfaces this information when you navigate to a submodule's parent directory, so it makes me think I've just tried the wrong approach.

Is there some other magic way in the Octokit APIs that I've missed to get this submodule target hash?
As described in the question, if you get the contents at the submodule path found in .gitmodules, you will get a piece of content of type "Submodule". This has null content.
If, however, you get the contents of the parent directory for that same submodule path, you will get a piece of content of type "File", with the path of your submodule (e.g., path/to/submodule above). This files hash is the target SHA on the submodule's own repository.
To get the SHA of a submodule, you need to get the contents of its parent directory and then index to the file representing the submodule. While going directly to the path gets you something of type "Submodule", getting the parent contents will get you bunch of "File" type things (and "Dir", if you have sibling subdirectories there). Oddly, this parent content list excludes the "Submodule" type you get when you point directly at the submodule path.
In the example above, just go one level up in the path.
var submodulePathContents = await repositoriesClient.Content.GetAllContents(parentRepoId, "path/to"); // no longer "path/to/submodule"
From there, grab the content item with the path you wanted in the first place (e.g., "path/to/submodule"), which will have a Sha field containing the submodule's target SHA on the submodule repository.
using System.Linq;
…
var submoduleTargetSha = submodulePathContents.First(content => content.Path == submodulePath).Sha;
Here's an example entry from the monodevelop repo's primary submodule directory.
Name: mono-tools Path: main/external/mono-tools Type:File Octokit.RepositoryContent
Content null string
DownloadUrl null System.Uri
EncodedContent null string
Encoding null string
GitUrl {https://api.github.com/repos/mono/mono-tools/git/trees/d858f5f27fa8b10d734ccce7ffba631b995093e5} System.Uri
HtmlUrl {https://github.com/mono/mono-tools/tree/d858f5f27fa8b10d734ccce7ffba631b995093e5} System.Uri
Name "mono-tools" string
Path "main/external/mono-tools" string
Sha "d858f5f27fa8b10d734ccce7ffba631b995093e5" string
Size 0 int
SubmoduleGitUrl null System.Uri
Target null string
Type File Octokit.ContentType
Url {https://api.github.com/repos/mono/monodevelop/contents/main/external/mono-tools?ref=master} System.Uri
And that hash lines up with the web UI.

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With