如何在我的开发网站页面顶部显示当前 Git 分支名称?

29

以下是我的情况:

我在Mac电脑上使用MAMP(PHP)进行本地开发。我的网站采用Git版本控制,我将我的开发服务器指向位于磁盘上版本控制下的网站根目录。

File structure:
--mysitehere/
---.git/ (.git folder is here versioning everything below)
---src/ (<-- web server root)
----index.php (need the codez here for displaying current git branch)

有没有示例代码可以查看.git文件夹并查看当前分支,并在index.php页面上输出它(以及RoR dev的ruby解决方案)?当我切换分支时,这将非常有用,并且在我刷新浏览器时,我会在页面顶部看到我所在的'master'或'your-topic-branch-name-here'

我愿意使用第三方库以从PHP中以编程方式访问git,或者从.git内部的磁盘文件中获取正确的'current-branch'变量的东西。


2
这里有一个相关的答案:https://dev59.com/5HI-5IYBdhLWcg3w9thw - Ruslan Kabalin
@Ruslan Kabalin - 是的!这证实了我的解决方案,即查看.git/目录中的HEAD文件,该文件始终包含当前分支。 - program247365
10个回答

60

对我来说,在PHP中,将以下代码放在我的网站顶部可以解决问题:

/**
 * @filename: currentgitbranch.php
 * @usage: Include this file after the '<body>' tag in your project
 * @author Kevin Ridgway 
 */
    $stringfromfile = file('.git/HEAD', FILE_USE_INCLUDE_PATH);

    $firstLine = $stringfromfile[0]; //get the string from the array

    $explodedstring = explode("/", $firstLine, 3); //seperate out by the "/" in the string

    $branchname = $explodedstring[2]; //get the one that is always the branch name

    echo "<div style='clear: both; width: 100%; font-size: 14px; font-family: Helvetica; color: #30121d; background: #bcbf77; padding: 20px; text-align: center;'>Current branch: <span style='color:#fff; font-weight: bold; text-transform: uppercase;'>" . $branchname . "</span></div>"; //show it on the page

2
如果分支名称包含“/”,则这并不完全适用:大多数Git Flow功能都包括它。您需要切割数组,然后再次将其合并:$explodedstring = array_slice($explodedstring, 2); $branchname = implode("/", $explodedstring); - Giacomo
5
作为在线程序, <?php echo implode('/', array_slice(explode('/', file_get_contents('.git/HEAD')), 2)); ?> - Florian Grell
它会破坏很多环境,例如 Git Flow 中的 bug/foo 或 feature/bar 约定。解决方法是将 explode 限制为 3 个项目,或手动获取 ref: refs/heads/ 后面的内容。 - Dereckson
如果我们要变得笨拙,$gitCurrentBranch = trim(substr(file_get_contents('.git/HEAD'), 16)); 只要.git/HEAD保持其当前格式。 - Dereckson
1
我建议将 $branchname = trim($explodedstring[2]); 这行代码加入,因为该字符串可能在末尾包含换行符。 - psad
显示剩余3条评论

14

分支、最后提交日期和哈希值

<?php 
    $gitBasePath = '.git'; // e.g in laravel: base_path().'/.git';

    $gitStr = file_get_contents($gitBasePath.'/HEAD');
    $gitBranchName = rtrim(preg_replace("/(.*?\/){2}/", '', $gitStr));                                                                                            
    $gitPathBranch = $gitBasePath.'/refs/heads/'.$gitBranchName;
    $gitHash = file_get_contents($gitPathBranch);
    $gitDate = date(DATE_ATOM, filemtime($gitPathBranch));

    echo "version date: ".$gitDate."<br>branch: ".$gitBranchName."<br> commit: ".$gitHash;                                                       
?>

示例输出:

版本日期:2018-10-31T23:52:49+01:00

分支:dev

提交:2a52054ef38ba4b76d2c14850fa81ceb25847bab

refs/heads/your_branch文件的修改日期是最后一次提交日期的(可接受的)近似值,特别适用于测试/暂存环境,我们假设我们将部署新的提交(没有旧的提交)。


8
我使用这个函数:
protected function getGitBranch()
{
    $shellOutput = [];
    exec('git branch | ' . "grep ' * '", $shellOutput);
    foreach ($shellOutput as $line) {
        if (strpos($line, '* ') !== false) {
            return trim(strtolower(str_replace('* ', '', $line)));
        }
    }
    return null;
}

2
可以更简单地使用 git branch --show-current 命令。 - ghost404

5

在PHP中有一个简单的方法:

  • 短哈希: $rev = exec('git rev-parse --short HEAD');
  • 完整哈希: $rev = exec('git rev-parse HEAD');

1
只要你的本地机器配置允许你执行git,这个可以工作。我个人遇到过这方面的问题,所以转而采用program247365的答案来解决它。 - Jacob Ewing

3

扩展program247365的答案,我编写了一个帮助类,对于使用Git Flow的人也很有用。

class GitBranch
{
    /**
     * @var string
     */
    private $branch;

    const MASTER = 'master';
    const DEVELOP = 'develop';

    const HOTFIX = 'hotfix';
    const FEATURE = 'feature';

    /**
     * @param \SplFileObject $gitHeadFile
     */
    public function __construct(\SplFileObject $gitHeadFile)
    {
        $ref = explode("/", $gitHeadFile->current(), 3);

        $this->branch = rtrim($ref[2]);
    }

    /**
     * @param string $dir
     *
     * @return static
     */
    public static function createFromGitRootDir($dir)
    {
        try {
            $gitHeadFile = new \SplFileObject($dir.'/.git/HEAD', 'r');
        } catch (\RuntimeException $e) {
            throw new \RuntimeException(sprintf('Directory "%s" is not a Git repository.', $dir));
        }

        return new static($gitHeadFile);
    }

    /**
     * @return string
     */
    public function getName()
    {
        return $this->branch;
    }

    /**
     * @return boolean
     */
    public function isBasedOnMaster()
    {
        return $this->getFlowType() === self::HOTFIX || $this->getFlowType() === self::MASTER;
    }

    /**
     * @return boolean
     */
    public function isBasedOnDevelop()
    {
        return $this->getFlowType() === self::FEATURE || $this->getFlowType() === self::DEVELOP;
    }

    /**
     * @return string
     */
    private function getFlowType()
    {
        $name = explode('/', $this->branch);

        return $name[0];
    }
}

您可以像这样使用它:
echo GitBranch::createFromGitRootDir(__DIR__)->getName();

2
这很不错,但分支名称不应该由固定常量假定。有些人使用不同的分支名称,最好能够将它们传递到构造函数中或使用静态配置方法,这样代码就不需要在每个项目或存储库结构的基础上进行重写了。 - mopsyd
@mopsyd 是的,但这样他们将不会实现Git Flow标准。这里的代码假设进行了严格的实现。也许为这些方法创建接口可以解决那些使用自己约定的问题。 - Adam Elsodaney
Git flow标准并不适用于每个人的使用情况。我个人喜欢它,但是有许多项目不适合使用它,例如那些从单分支SVN仓库移植过来的项目。除非它们之间存在某种紧密耦合关系(通常只在非常特定的情况下才需要),否则强制执行对其他人代码的看法是不合适的。 - mopsyd
这太棒了。也有添加标签的方法吗? - Eray T

1

PHP中的Git库(GLIP)是一个用于与Git存储库交互的PHP库。它不需要在您的服务器上安装Git,并且可以在GitHub上找到。


似乎您必须在访问 glip 的内容之前传递一个分支名称。它似乎不适用于我想要的,因为它没有显示分支的方法,它只希望您直接通过名称访问它们。话虽如此,在任何 .git/ 存储库目录中,都有一个名为“HEAD”的文件,其中包含当前分支名称。我可能最终会直接解析该文件,并在完成后在此处发布我的答案。 - program247365

0

如果你在仓库的任何子目录中,可以使用快速且简单的选项:

$dir = __DIR__;
exec( "cd '$dir'; git br", $lines );
$branch = '';
foreach ( $lines as $line ) {
    if ( strpos( $line, '*' ) === 0 ) {
        $branch = ltrim( $line, '* ' );
        break;
    }
}

1
我猜 git br 是你对 git branch 的别名? - Nanne

0

读取.git/HEAD文件的给定解决方案导致我的管道失败。

受此问题启发:如何以编程方式确定当前检出的Git分支

您可以使用以下方法获取git分支名称:

$gitBranchName = trim(shell_exec("git rev-parse --abbrev-ref HEAD"));


0
要点:https://gist.github.com/reiaguilera/82d164c7211e299d63ac
<?php
// forked from lukeoliff/QuickGit.php

class QuickGit {
  private $version;

  function __construct() {
    exec('git describe --always',$version_mini_hash);
    exec('git rev-list HEAD | wc -l',$version_number);
    exec('git log -1',$line);
    $this->version['short'] = "v1.".trim($version_number[0]).".".$version_mini_hash[0];
    $this->version['full'] = "v1.".trim($version_number[0]).".$version_mini_hash[0] (".str_replace('commit ','',$line[0]).")";
  }

  public function output() {
    return $this->version;
  }

  public function show() {
    echo $this->version;
  }
}

-1
为什么不这样做?这可能只会出现在一个模板文件中,只有开发人员才能看到。

当前 git 分支: <?php echo `git branch --show-current`; ?>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接