如何在PS脚本中获取Git提交哈希?

时间:2017-05-14 10:30:01

标签: git powershell msbuild

我使用PowerShell脚本调用msbuild并将版本号传递给OctopusDeploy,如下所示:

msbuild "Xyz.sln" /t:Rebuild /p:Configuration=Release /p:RunOctoPack=true /p:OctopackPackageVersion=$versionNumber

...其中$ versionNumber在PS脚本中生成。我想要做的是将Git提交哈希的前16个字符添加到版本字符串的末尾,这样它最终会看起来像:

2.yyyyMMdd.HHmmss-git-6d34e44340f95c2a

我该怎么做?我可以让msbuild或Visual Studio以某种方式返回当前的git commit hash,考虑到它们现在有内置的Git支持吗?

3 个答案:

答案 0 :(得分:6)

您实际上可以直接在msbuild中执行此操作,以便它可以在VS和大多数CI系统上运行而无需任何额外步骤(例如PowerShell脚本),即使在跨平台dotnet CLI和单声道上也是如此。

您可以在项目或解决方案(>影响所有项目)目录中创建一个名为Directory.Build.targets的文件,其中包含以下内容(假设MSBuild 15 / VS 2017.如果更低,则需要手动导入或插入这个目标进入每个项目)

<Project>
  <Target Name="DetermineOctopackVersion" BeforeTargets="Build" Condition=" '$(RunOctoPack)' == 'true' ">
    <Exec Command="git rev-parse HEAD" ConsoleToMSBuild="true" StandardOutputImportance="low">
      <Output TaskParameter="ConsoleOutput" PropertyName="GitCommitHash" />
    </Exec>
    <PropertyGroup>
      <VersionDatePart>$([System.DateTime]::get_Now().ToString(yyyyMMdd.HHmmss))</VersionDatePart>
      <OctopackPackageVersion>2.$(VersionDatePart)-git-$(GitCommitHash.Substring(0,16))</OctopackPackageVersion>
    </PropertyGroup>
  </Target>
</Project>

如果您希望在每次构建时设置属性,不仅在RunOctoPacktrue时,只需删除Condition属性。

但如果您需要在PowerShell中执行此操作,则可以调用git命令并捕获其输出:

$commitHash = (git rev-parse HEAD).Substring(0,16)
$versionDatePart = [System.DateTime]::Now.ToString('yyyyMMdd.HHmmss')
$version = "1.$versionDatePart-git-$commitHash"

如果你真的想避免调用git(虽然没有正确的构建系统设置没有git安装......)你也可以在PS或MSBuild中使用[System.IO.File]::ReadAllText(".git\refs\heads\master")来读取git目录(在分离状态下,.git\HEAD将包含散列,当使用分支时,它将包含要查找散列的文件的位置。)

答案 1 :(得分:1)

由于您希望避免按here调用git.exe,并且您希望在PowerShell中进行提交处理,因此您可以将C#解决方案转换为PowerShell,如下所示。

[System.Reflection.Assembly]::LoadFrom("C:\\Program Files (x86)\\Microsoft Visual Studio 14.0\\Common7\\IDE\\CommonExtensions\\Microsoft\\TeamFoundation\\Team Explorer\\LibGit2Sharp.dll") | Out-Null

$repo = [LibGit2Sharp.Repository]::new("C:\MyRepo")
$repo.Commits | Select-Object -First 1

这将返回包含类似

的数据的LibGit2Sharp提交对象
Message      : Further harden mutex closing process

MessageShort : Further harden mutex closing process
Encoding     : UTF-8
Author       : 
Committer    : 
Tree         : {.gitattributes, .gitignore, Build, Doc...}
Parents      : {fe26fc1a476f18bfa8a70c315fdbd96f1434d29c}
Notes        : {}
Id           : 1ba7bce90444a323fa9079cb06e5921afd0c3cd8
Sha          : 1ba7bce90444a323fa9079cb06e5921afd0c3cd8
Repository   : LibGit2Sharp.Repository

您需要使用32位(x86)PowerShell.exe调用此方法。

答案 2 :(得分:0)

我最后做的只是在我的Powershell脚本(文件NGitNGit.dllSharpen.dll)旁边的捆绑ICSharpCode.SharpZipLib.dll然后使用这样的代码来生成带有后缀为git hash的版本号:

[System.Reflection.Assembly]::LoadFrom("Ngit.dll") | Out-Null
[System.Reflection.Assembly]::LoadFrom("Sharpen.dll") | Out-Null
[System.Reflection.Assembly]::LoadFrom("ICSharpCode.SharpZipLib.dll") | Out-Null

# *** Git repo base path (should contain .sln file) ***
$repoPath = "C:\Path\To\Repo"

# *** OctopusDeploy API key for publishing ***
$octoApiKey = "API-[PublishKey]"

#######################################################

# *** Get and process current Git commit hash ***
$sharpenRepoPath = New-Object -TypeName Sharpen.FilePath -ArgumentList "$($repoPath)\.git"
$repoBuilder = New-Object -TypeName NGit.RepositoryBuilder
$repo = $repoBuilder.SetGitDir($sharpenRepoPath).Build()
$headHash = $repo.Resolve("HEAD").Name.Substring(0,12)

# *** Version when pushing to OctopusDeploy NuGet ***
$versionNumber = "2." + [datetime]::now.tostring("yyyyMMdd.HHmmss") + "-git-" + $headHash

# *** Pause before publish ****
Write-Host "About to publish to OctopusDeploy NuGet with version number:"
Write-Host "    $($versionNumber)"
cmd /c pause

# *** OctopusDeploy build and push ***
msbuild "$repoPath\MySolution.sln" /t:Rebuild /p:Configuration=Release /p:RunOctoPack=true /p:OctopackPackageVersion=$versionNumber /p:OctoPackPublishPackageToHttp=https://my.nuget.server/nuget/packages /p:OctoPackPublishApiKey=$octoApiKey