不在存储库中时如何在终端中获取“git log”或使用 shell 脚本

Posted

技术标签:

【中文标题】不在存储库中时如何在终端中获取“git log”或使用 shell 脚本【英文标题】:How do I get 'git log' in the terminal or using a shell script when not in a repository 【发布时间】:2017-03-18 18:37:02 【问题描述】:

我有 Teamcity 构建代理,我需要从存储库中提取 git log。问题是,当我的 shell 脚本运行时,它不在 git 存储库中,所以 git log 不能开箱即用。

有谁知道如何做到这一点。

我搜索了文档,但似乎找不到任何方法。

到目前为止的问题解决

    当 Teamcity 从 Github 将项目“克隆”到代理时,它实际上并没有克隆整个项目。所以working directory 不是存储库。

    在运行我需要的 shell 脚本时,我没有 SSH 访问 github 的权限

提前致谢。

解决方案

请参阅下面接受的答案。

【问题讨论】:

How do I run a program with a different working directory from current, from Linux shell?的可能重复 git pull while not in a git directory的可能重复 这能回答你的问题吗? Using git commands in a TeamCity Build Step 【参考方案1】:

使用git 命令的-C 标志。它允许您指定 git 目录。

git -C 'git-working-dir' log

【讨论】:

但这只有在构建代理上有 git 目录时才有效,对吗? - 我想从 github.com 获得它 @CodeMonkey 正确,这仅适用于本地目录 AFAIK。您可以使用git:// 协议从 GitHub 克隆目录;如果您想推送更新,则只需要 SSH 访问权限。 是的,克隆情况是有道理的。这对我来说可能是一个解决方法。编辑:但由于它不公开,我将需要设置 SSH .. 工作。【参考方案2】:

我的解决方案,最终如下:

    注册 SSH 凭据以访问 TC 代理上的 Github。

    git clone ssh://git@github.com/account-name/repo.git /var/tmp/projectname_tmp

    cd 到目录/var/tmp/projectname_tmp

    git log >> output.file

对于奖励积分,您可以像这样从给定日期提取:

    git log --since='2016-11-01 03:00' >> output.log

【讨论】:

【参考方案3】:

您无需克隆 repo 即可获取日志。 TeamCity 已经有一个触发构建的文件和提交消息的列表。您可以在脚本步骤中简单地查询 TeamCity API 并获取日志。这是我用来执行此操作的两个 Powershell 函数。

TeamCityGetChangeLog,需要服务器 url、用户名、密码和构建 ID(您可以从 TeamCity 参数中传入)。

# Gets the change log for the specified build ID
function TeamCityGetChangeLog([string] $serverUrl, [string] $username, [string] $password, [int] $buildId)
    $changelog = ''

    # If the build is running inside TeamCity
    if ($env:TEAMCITY_VERSION) 
        $buildUrl = "$serverUrl/httpAuth/app/rest/changes?build=id:$($buildId)"
        $authToken = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($username + ":" + $password))

        # Get all the changes
        $request = [System.Net.WebRequest]::Create($buildUrl)
        $request.Headers.Add("Authorization", "Basic $authToken");
        $xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

        # Get all commit messages for each of them
        $changelog = Microsoft.PowerShell.Utility\Select-Xml $xml -XPath `
            "/changes/change" | Foreach 
                TeamCityGetCommitMessage $serverUrl $username $password $_.Node.id
            
    

    return $changelog

这依赖于 TeamCityGetCommitMessage,它也需要更改集 ID。

# Get the commit messages, and files changed for the specified change id
# Ignores empty lines, lines containing "#ignore", "merge branch"" or "TeamCity"
function TeamCityGetCommitMessage([string]$serverUrl, [string]$username, [string]$password, [int]$changeId)

    $getFilesChanged = $false;
    $request = [System.Net.WebRequest]::Create("$serverUrl/httpAuth/app/rest/changes/id:$changeId")
    $authToken = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes($username + ":" + $password))
    $request.Headers.Add("Authorization", "Basic $authToken");

    $xml = [xml](new-object System.IO.StreamReader $request.GetResponse().GetResponseStream()).ReadToEnd()

    Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/change" |
        where  ($_.Node["comment"].InnerText.Length -ne 0) `
        -and (-Not $_.Node["comment"].InnerText.Contains('#ignore')) `
        -and (-Not $_.Node["comment"].InnerText.StartsWith("Merge branch")) `
        -and (-Not $_.Node["comment"].InnerText.StartsWith("TeamCity change")) |
        foreach 
            $getFilesChanged = $true
            $username = (&If($_.Node["user"] -ne $null) $_.Node["user"].name.Trim() Else  $_.Node.Attributes["username"].Value )
            "<br /><strong>$($username + " on " + ([System.DateTime]::ParseExact($_.Node.Attributes["date"].Value, "yyyyMMddTHHmmsszzzz", [System.Globalization.CultureInfo]::InvariantCulture)))</strong><br /><br />"

            "$($_.Node["comment"].InnerText.Trim().Replace("`n", "`n<br />"))"
        

    if ($getFilesChanged) 
        "<br /><br /><strong>Files Changed</strong><br /><br />"
        Microsoft.PowerShell.Utility\Select-Xml $xml -XPath "/change/files" |
        where  ($_.Node["file"].Length -ne 0) |
        foreach  Select-Xml $_.Node -XPath 'file' |
            foreach  "$($_.Node.Attributes["file"].Value)<br />" 
        
    

【讨论】:

谢谢博彦。尽管这实际上不是我的问题的答案(shell 和终端(隐含 linux)),但对其他人来说仍然是一个很好的资源。

以上是关于不在存储库中时如何在终端中获取“git log”或使用 shell 脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何根据作者的时间戳制作 git log 顺序?

如何使用 JGit 获取提交的文件列表

Git - 如何从存储库(devops)中删除文件而不在本地克隆它

git log/show 等替换终端屏幕

如何在我的无处不在的容器中获取所有可用的持久存储?

当代码仓库不在 git 中时,如何在 AWS 网络服务器中部署代码?