How can I extract Git commit hash from VS/msbuild?

The scenario is:

Developers are running a PowerShell script from their machines to publish various Nuget packages to OctopusDeploy via MSBuild. We’d like to make the current git commit’s hash (the base of the Git repo is the same as the .sln directory) part of the generated version number. To do this we presumably need to extract the current commit’s hash and plug it into the version number string we then pass into MSBuild as a parameter.

  • Viewing Unpushed Git Commits
  • How to re-merge a file in the git?
  • Git: Subtree Merge into a Deeply Nested Subdirectory?
  • 'git' cannot be made visible because all of its children are in unavailable action sets
  • Is Git's stashing mechanism essentially creating commit and then cherry-picking it?
  • Restoring lost commits in git
  • So the question is, how can we get this from MSBuild or Visual Studio? There’s no guarantee that a developer will have Git commandline installed, but they will have at least VS2015 installed and that has Git support built-in so you’d think there would be some way to get the latest Git commit’s hash from this? You could see the hash if you went into the Visual Studio GUI and looked in the source control section.

    Is there some commandline tool that comes bundled with Visual Studio 2015 or later that will return the current Git commit’s hash?

  • Where to find Qt's commits?
  • Can I create more than 1 fork in GitHub?
  • Gerrit email notification for push to master branch
  • Unable to update my Local Git repo based on SVN
  • Files deleted or modified between git revisions are automatically getting deleted from instances
  • How to specify overlapping rules in git-svn
  • One Solution collect form web for “How can I extract Git commit hash from VS/msbuild?”

    Your requirement to not depend on git.exe makes this complicated.
    However if you want to use the library that Visual Studio uses, LibGit2Sharp and have Visual Studio integration you can do something crazy like this.

    Add a new target to your project file. I’m assuming you are using C# so add it to your csproj after

    <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />

      <UsingTask TaskName="HelloGit" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.Core.dll">
          <Sha1 ParameterType="System.String" Required="False" Output="True" />
          <Repository ParameterType="System.String" Required="True" Output="False" />
          <Reference Include="System.Xml, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
          <Reference Include="C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer\LibGit2Sharp.dll" />
          <Using Namespace="System" />
          <Using Namespace="System.IO" />
          <Code Type="Class" Language="cs">
      <Target Name="RunTask" AfterTargets="BeforeBuild">
        <HelloGit Repository="$(MSBuildProjectDirectory)">
          <Output TaskParameter="Sha1" PropertyName="CommitId" />
        <Warning Text="Your commit is: $(CommitId)" />

    What this does is look in the current project directory for “HelloGit.cs”. The contents of which look like this…

    You could do this with an inline code task (e.g. embedded C# inside XML) but since the task is quite long I wanted to edit it in VS Code as a separate file.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Text;
    using LibGit2Sharp;
    using Microsoft.Build.Framework;
    using Microsoft.Build.Utilities;
    namespace GitIntrospection {
        public class HelloGit : Task {
            public override bool Execute() {
                AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => {
                    if (args.Name.Contains("LibGit2Sharp")) {
                        return Assembly.LoadFrom("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer\\LibGit2Sharp.dll");
                    return null;
                return !Log.HasLoggedErrors;
            // [MethodImpl(MethodImplOptions.NoOptimization | MethodImplOptions.NoInlining)]
            private void GetCommit() {
                Repository repository = new Repository(Repository);
                this.Sha1 = repository.Commits.First().Id.Sha;
            public string Sha1 { get; set; }
            public string Repository { get; set; }

    Now when you build your project the latest commit will be extracted and logged as a warning. This works both inside Visual Studio and inside MS Build.

    Works on the command line
    Works on the command line

    Works inside Visual Studio
    Works inside Visual Studio

    The results even seem to agree with git.exe… that’s handy
    The results even seem to agree with git.exe... that's handy

    Alternative 1
    You could just use git.exe and an <Exec> task!

    Alternative 2
    You could use PowerShell to load the LibGit2Sharp assembly and call the same methods.

    Git Baby is a git and github fan, let's start git clone.