Getting Git Commits with the VSO REST API

(Guest post by Drew Robson - our SSW TimePRO product lead)

​​​​​​​​With Visual Studio Online now supporting Git, ​​​​more developers are changing their source control repositories. What happens if an application you developed relies on the TFS Client Object Model to get information out of source control (e.g. changeset comments) and the developers start using Git?​

That's where the new Visual Studio Online REST APIs come in. You can get a list of commits from your VSO Git repository with only a HTTP request.​ Let’s look at how to do this with C# and Visual Studio 2013. The below example gets all the commits for a particular user.

(This is based on Get started with the REST APIs and VSO Integration Reference)

You will need a method to execute the HTTP GET request.

private async Task<string> Get(HttpClient client, string url)
{
    var result = string.Empty;

    using (HttpResponseMessage response = client.GetAsync(url).Result)
    {
        response.EnsureSuccessStatusCode();
        result = await response.Content.ReadAsStringAsync();
    }

    return result;
}

And a method to set up the authentication and urls.

public async Task<IEnumerable<Commit>> GetGitCommits(string username, DateTime from, DateTime to)
{
    var result = new List<Commit>();

    using (var client = new HttpClient())
    {
        if(_settings.AuthType == AuthType.Basic.ToString())
        {
            var version = "api-version=1.0-preview.1";

            // Set up auth
            var parameters = Convert.ToBase64String(ASCIIEncoding.ASCII.GetBytes(string.Format("{0}:{1}", _settings.Username, _settings.Password)));
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", parameters);

            // Get Git repositories
            var url = string.Format("{0}/{1}/_apis/git/repositories?",
                _settings.Url,
                _settings.CollectionName);
            var response = await Get(client, url + version);
            var repositories = JsonConvert.DeserializeObject<RepositoryCollection<Repository>>(response);

            // Get Git commits
            foreach (var r in repositories.Value)
            {
                url = string.Format("{0}/{1}/_apis/git/{2}/repositories/{2}/commits?committer={3}&fromdate={4}&todate={5}&",
                    _settings.Url,
                    _settings.CollectionName,
                    r.name,
                    username,
                    from.ToString("u"),
                    to.ToString("u"));

                response = await Get(client, url + version);
                var collection = JsonConvert.DeserializeObject<CommitCollection<Commit>>(response);
                if (collection != null
                    && collection.count > 0)
                {
                    result.AddRange(collection.Value);
                }
            }
        }
    }

    return result;
}

What about the classes RepositoryCollection, Repository, CommitCollection and Commit? These are the class representations of the JSON responses. See the SSW Rule Do you know how to easily get classes from a JSON response? to generate them.

Damian Brady

I'm an Australian developer, speaker, and author specialising in DevOps, developer process, and software architecture. I love Octopus Deploy, Visual Studio Team Services, and reducing process waste.