Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

@datagutt datagutt commented Nov 26, 2011

Doesnt show the last entry

@geeknam

This comment has been minimized.

Copy link
Owner Author

@geeknam geeknam commented Nov 26, 2011

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

@datagutt

This comment has been minimized.

Copy link

@datagutt datagutt commented Nov 26, 2011

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

@fredpe

This comment has been minimized.

Copy link

@fredpe 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

This comment has been minimized.

Copy link

@fwartner fwartner commented Nov 21, 2014

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

This comment has been minimized.

Copy link

@latheesan-k latheesan-k commented Dec 1, 2014

@jankal

This comment has been minimized.

Copy link

@jankal jankal commented Mar 20, 2016

@mcsilver

This comment has been minimized.

Copy link

@mcsilver mcsilver commented Oct 16, 2016

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

This comment has been minimized.

Copy link

@yawnolly 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