Чтение сообщения коммита Git из PHP - PullRequest
23 голосов
/ 01 февраля 2012

Я ищу способ прочитать сообщение Git commit с помощью PHP. Я подозреваю, что мне нужно использовать Git Hook, но я никогда не работал с ними раньше, поэтому мне нужно push в правильном направлении. В частности, я хотел бы реализовать следующий процесс:

  • PHP-скрипт выполняется автоматически после каждого коммита
  • Сценарий фиксирует имя пользователя Git, время фиксации и содержимое фиксации

Если это вообще возможно, я бы хотел придерживаться чистого PHP. Если есть учебники или ссылки, на которые вы могли бы указать, это очень помогло бы.

Ответы [ 4 ]

23 голосов
/ 08 февраля 2012

Чтобы получить хеш коммита, вы можете использовать

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, будет просто оберткой вокруг того, что вы будете делать с git на cli - Т.е. любое "как я могу сделать x с git из php" просто exec('the git answer', $output)

7 голосов
/ 06 февраля 2012

Что касается использования PHP для извлечения правильного коммита:

Indefero

Существует проект под названием Indefero , который является инструментом PHP forge, который имеет Разъем SCM для git .Вы можете легко использовать их класс 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];
}

VersionControl_Git от PEAR

В PEAR также есть библиотека с именем VersionControl_Git , которая будет полезна в этомСитуация и задокументированы .

4 голосов
/ 06 февраля 2012

Как упомянул @Pawel, вы захотите поработать с ловушками на этом:

На localhost вы можете перейти к /.git/hooks и переименовать post-commit.sample для post-commit и затем поместите внутрь #! / usr / bin / php Есть и другие крючки, которые могут быть более подходит для вас.

Git будет искать хук post-commit после вашей фиксации и автоматически запускать что-либо внутри.

То, что вы здесь захотите сделать, зависит от задачи, но я бы предложил curl сценарий - здесь все становится интереснее.

Чтобы извлечь информацию, которую вы ищете, вы захотите использовать git log -1 - это должно отозвать последний коммит.

Точнее, вы захотите создать свой коммит, используя переключатель --pretty=format, который может выводить последний коммит с необходимой вам информацией. Проверьте эту строку:

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

Это вернуло бы большинство вещей, которые вы ищете. Посетите страницу git-log , чтобы увидеть все переменные %, которые можно использовать с --pretty=format:. После того, как вы создали желаемую строку, вы можете либо POST передать их через cURL в PHP-скрипт, либо запустить PHP-скрипт и использовать shell_exec(git log -1 --pretty=format:'%h - %cn (%ce) - %s (%ci)') для работы со встроенным сообщением коммита.

1 голос
/ 28 июля 2016

Я копался в том же вопросе и нашел способ сделать это быстрее и проще.

Чтобы получить только сообщение о коммите, вы можете использовать

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

Очевидно, HEAD можно заменить любым хэшем коммита.

Будет выведено что-то вроде

commit 4152601a42270440ad52680ac7c66ba87a506174
Improved migrations and models relations

Вторая строка - это то, что вам нужно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...