Skip to content

Instantly share code, notes, and snippets.

@geeknam
Created May 8, 2011 16:43
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 14 You must be signed in to fork a gist
  • Save geeknam/961488 to your computer and use it in GitHub Desktop.
Save geeknam/961488 to your computer and use it in GitHub Desktop.
Parse git log with PHP to an array
<?php
// Author: Ngo Minh Nam
$dir = "/path/to/your/repo/";
$output = array();
chdir($dir);
exec("git log",$output);
$history = array();
foreach($output as $line){
if(strpos($line, 'commit')===0){
if(!empty($commit)){
array_push($history, $commit);
unset($commit);
}
$commit['hash'] = substr($line, strlen('commit'));
}
else if(strpos($line, 'Author')===0){
$commit['author'] = substr($line, strlen('Author:'));
}
else if(strpos($line, 'Date')===0){
$commit['date'] = substr($line, strlen('Date:'));
}
else{
$commit['message'] .= $line;
}
}
print_r($history);
?>
@datagutt
Copy link

Doesnt show the last entry

@geeknam
Copy link
Author

geeknam commented Nov 26, 2011

Well, it works perfectly on mine. Just tested it again. It shows all 600+ commits of my project :)

@datagutt
Copy link

I also get some php notices, you should remove those. Me trying to stop them might have changed something :)

@fredpe
Copy link

fredpe commented Oct 2, 2012

Thanks! Just two small things in order to get rid of warnings and to fix the bug that the last commit gets skipped:

  1. Replace

    $commit['message']  .= $line;

    with

    if(isset($commit['message']))
        $commit['message'] .= $line;
    else
        $commit['message'] = $line;
  2. Add

    if(!empty($commit)) {
        array_push($history, $commit);
    }

    right after the foreach loop ends in order to ensure the last commit gets added aswell.

For my case I further added trim(...) wherever content gets assigned to the current $commit array in order to remove unnecessary spaces.

@fwartner
Copy link

How do i get the LAST commit of my repository? I mean it works for me.. But i really just want the last one.. :)

@latheesan-k
Copy link

@jankal
Copy link

jankal commented Mar 20, 2016

@mcsilver
Copy link

This is probably a newb question and not exactly on topic: For Apache, I found I had to add the www-data user to the git group in order for the php page to read the repo (my bare repo has git:git for ownership). Having done that, there doesn't seem to be a security problem, like with someone accessing the repo files themselves via URL, because Apache's DocumentRoot is elsewhere and it therefore prevents that kind of access but I wanted to ask the group whether any part of what I described is a no-no or can be improved.

@yawnolly
Copy link

yawnolly commented Oct 27, 2016

if you do a str_replace to remove any "\n"s in your commit message than the code looks alot cleaner.

function parseLog($log) {
    $history = array();
    foreach($log as $key => $line) {
        if(strpos($line, 'commit') === 0 || $key + 1 == count($lines)){
            $commit['hash'] = substr($line, strlen('commit') + 1);
        } else if(strpos($line, 'Author') === 0){
            $commit['author'] = substr($line, strlen('Author:') + 1);
        } else if(strpos($line, 'Date') === 0){
            $commit['date'] = substr($line, strlen('Date:') + 3);
        } elseif (strpos($line, 'Merge') === 0) {
            $commit['merge'] = substr($line, strlen('Merge:') + 1);
            $commit['merge'] = explode(' ', $commit['merge']);
        } else if(!empty($line)){
            $commit['message'] = substr($line, 4);
            array_push($history, $commit);  
            unset($commit);            
        }
    }
    return $history;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment