从PHP读取Git提交消息


Reading a Git commit message from PHP

我正在寻找一种用PHP读取Git提交消息的方法。我怀疑我需要使用Git钩子,但我以前从未使用过它们,所以我需要朝着正确的方向推动。具体来说,我想实现以下过程:

  • 每次提交后都会自动执行PHP脚本
  • 脚本捕获Git用户名、提交时间和提交内容

如果可能的话,我愿意坚持使用纯PHP。如果你可以指出一些教程或参考资料,那将是一个巨大的帮助。

要获得提交哈希,可以使用

git rev-parse --verify HEAD 2> /dev/null

来自php:

exec('git rev-parse --verify HEAD 2> /dev/null', $output);
$hash = $output[0];

您可以使用获取提交消息、作者和时间(不过,如果作为提交后挂钩的一部分运行,时间将只是"现在")

exec("git show $hash", $output);

如果不明显的话,无论你用php做什么,都只是包装你在cli上用git做的事情。也就是说,任何"我如何用php中的git做x"都只是exec('the git answer', $output)

就使用PHP提取正确的提交而言:

Indefero

有一个名为Indefero的项目,它是一个PHP锻造工具,有一个用于git的SCM连接器。您可以很容易地将他们的git类用作自己的API。您可以只获取git类和SCM类。

例如,我从下面的类中提取了两个方法,我认为它们与您最相关,这样您就可以看到它们是如何工作的。

获取变更日志列表:getChangeLog()

/**
 * Get latest changes.
 *
 * @param string Commit ('HEAD').
 * @param int Number of changes (10).
 * @return array Changes.
 */
public function getChangeLog($commit='HEAD', $n=10)
{
    if ($n === null) $n = '';
    else $n = ' -'.$n;
    $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log%s --date=iso --pretty=format:''%s'' %s',
                   escapeshellarg($this->repo), $n, $this->mediumtree_fmt,
                   escapeshellarg($commit));
    $out = array();
    $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
    self::exec('IDF_Scm_Git::getChangeLog', $cmd, $out);
    return self::parseLog($out);
}

获取特定提交:getCommit()

/**
 * Get commit details.
 *
 * @param string Commit
 * @param bool Get commit diff (false)
 * @return array Changes
 */
public function getCommit($commit, $getdiff=false)
{
    if ($getdiff) {
        $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' show --date=iso --pretty=format:%s %s',
                       escapeshellarg($this->repo),
                       "'".$this->mediumtree_fmt."'",
                       escapeshellarg($commit));
    } else {
        $cmd = sprintf('GIT_DIR=%s '.Pluf::f('git_path', 'git').' log -1 --date=iso --pretty=format:%s %s',
                       escapeshellarg($this->repo),
                       "'".$this->mediumtree_fmt."'",
                       escapeshellarg($commit));
    }
    $out = array();
    $cmd = Pluf::f('idf_exec_cmd_prefix', '').$cmd;
    self::exec('IDF_Scm_Git::getCommit', $cmd, $out, $ret);
    if ($ret != 0 or count($out) == 0) {
        return false;
    }
    if ($getdiff) {
        $log = array();
        $change = array();
        $inchange = false;
        foreach ($out as $line) {
            if (!$inchange and 0 === strpos($line, 'diff --git a')) {
                $inchange = true;
            }
            if ($inchange) {
                $change[] = $line;
            } else {
                $log[] = $line;
            }
        }
        $out = self::parseLog($log);
        $out[0]->diff = implode("'n", $change);
    } else {
        $out = self::parseLog($out);
        $out[0]->diff = '';
    }
    $out[0]->branch = implode(', ', $this->inBranches($commit, null));
    return $out[0];
}

来自PEAR的VersionControl_Git

PEAR中还有一个名为VersionControl_Git的库,在这种情况下会很有帮助,并且有文档记录。

正如@Pawel所提到的,您将希望在以下方面使用钩子:

在localhost上,您可以导航到/.git/hooks并重命名post-commit.sample发布commit,然后放入#/usr/bin/php还有其他挂钩可能更适合您。

Git将在您提交后查找post-commit挂钩,并自动运行其中的任何内容。

你想在这里做什么取决于任务,但我建议curl修改脚本——这是事情变得有趣的地方。

为了提取您要查找的信息,您需要使用git log -1——它应该会收回最近的提交。

更具体地说,您需要使用--pretty=format切换来构建提交,它可以输出带有所需信息的最新提交。查看此字符串:

git log -1 --pretty=format:'%h - %cn (%ce) - %s (%ci)'

这将返回您正在查找的大部分内容。查看git日志页面,查看可以与--pretty=format:一起使用的所有不同的%变量。一旦您生成了想要的字符串,就可以通过cURL将它们POST发送到PHP脚本,或者运行PHP脚本并使用shell_exec(git log -1 --pretty=format:'%h - %cn (%ce) - %s (%ci)')内联处理提交消息。

我深入研究了同一个问题,找到了一种更快、更容易的方法。

要获得提交消息,您可以使用

git rev-list --format=%B --max-count=1 HEAD

显然,HEAD可以用任何提交散列来代替。

它会输出类似的东西

commit 4152601a42270440ad52680ac7c66ba87a506174
Improved migrations and models relations

第二行是你需要的。