/** FusionForge Git plugin
*
* Copyright 2009, Roland Mas
+ * Copyright 2009, Mehdi Dogguy <mehdi@debian.org>
*
* This file is part of FusionForge.
*
$this->hooks[] = 'scm_browser_page' ;
$this->hooks[] = 'scm_gather_stats' ;
$this->hooks[] = 'scm_generate_snapshots' ;
-
+
require_once $gfconfig.'plugins/scmgit/config.php' ;
-
+
$this->default_git_server = $default_git_server ;
if (isset ($git_root)) {
$this->git_root = $git_root;
} else {
$this->git_root = $GLOBALS['sys_chroot'].'/scmrepos/git' ;
}
-
+
$this->register () ;
}
-
+
function getDefaultServer() {
return $this->default_git_server ;
}
+ function printShortStats ($params) {
+ $project = $this->checkParams ($params) ;
+ if (!$project) {
+ return false ;
+ }
+
+ if ($project->usesPlugin($this->name)) {
+ $result = db_query_params('SELECT sum(commits) AS commits, sum(adds) AS adds FROM stats_cvs_group WHERE group_id=$1',
+ array ($project->getID())) ;
+ $commit_num = db_result($result,0,'commits');
+ $add_num = db_result($result,0,'adds');
+ if (!$commit_num) {
+ $commit_num=0;
+ }
+ if (!$add_num) {
+ $add_num=0;
+ }
+ echo ' (Git: '.sprintf(_('<strong>%1$s</strong> commits, <strong>%2$s</strong> adds'), number_format($commit_num, 0), number_format($add_num, 0)).")";
+ }
+ }
+
function getBlurb () {
- return _('<p>This GIT plugin is not completed yet.</p>') ;
+ return _('<p>Documentation for Git is available <a href="http://git-scm.com/">here</a>.</p>') ;
}
function getInstructionsForAnon ($project) {
$b = _('<p><b>Anonymous Git Access</b></p><p>This project\'s Git repository can be checked out through anonymous access with the following command.</p>');
$b .= '<p>' ;
- $b .= '<tt>git clone '.util_make_url ('/anonscm/git/'.$project->getUnixName().'/').'</tt><br />';
+ $b .= '<tt>git clone '.util_make_url ('/anonscm/git/'.$project->getUnixName().'/'.$project->getUnixName().'.git').'</tt><br />';
$b .= '</p>';
return $b ;
}
function getInstructionsForRW ($project) {
- $b = _('<p><b>Developer GIT Access via SSH</b></p><p>Only project developers can access the GIT tree via this method. SSH must be installed on your client machine. Substitute <i>developername</i> with the proper values. Enter your site password when prompted.</p>');
- $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $project->getSCMBox() . ':'. $this->git_root .'/'. $project->getUnixName().'</tt></p>' ;
+ if (session_loggedin()) {
+ $u =& user_get_object(user_getid()) ;
+ $d = $u->getUnixName() ;
+ $b = _('<p><b>Developer GIT Access via SSH</b></p><p>Only project developers can access the GIT tree via this method. SSH must be installed on your client machine. Enter your site password when prompted.</p>');
+ $b .= '<p><tt>git clone git+ssh://'.$d.'@' . $project->getSCMBox() . $this->git_root .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
+ } else {
+ $b = _('<p><b>Developer GIT Access via SSH</b></p><p>Only project developers can access the GIT tree via this method. SSH must be installed on your client machine. Substitute <i>developername</i> with the proper value. Enter your site password when prompted.</p>');
+ $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $project->getSCMBox() . $this->git_root .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
+ }
return $b ;
}
if ($project->usesPlugin ($this->name)) {
if ($this->browserDisplayable ($project)) {
- print '<iframe src="'.util_make_url ("/plugins/scmgit/cgi-bin/gitweb.cgi?p=".$project->getUnixName()).'" frameborder="no" width=100% height=700></iframe>' ;
+ print '<iframe src="'.util_make_url ("/plugins/scmgit/cgi-bin/gitweb.cgi?p=".$project->getUnixName().'/'.$project->getUnixName().'.git').'" frameborder="no" width=100% height=700></iframe>' ;
}
}
}
// '<td width="25%" align="right"><strong>'.$total['commits'].'</strong></td>';
// $b .= '</tr>';
// $b .= $HTML->listTableBottom();
-// $b .= '<hr size="1" />';
// }
// return $b ;
}
$project_name = $project->getUnixName() ;
- $repo = $this->git_root . '/' . $project_name ;
+ $root = $this->git_root . '/' . $project_name ;
+ $repo = $root . '/' . $project_name . '.git' ;
$unix_group = 'scm_' . $project_name ;
system ("mkdir -p $repo") ;
if (!is_file ("$repo/HEAD") && !is_dir("$repo/objects") && !is_dir("$repo/refs")) {
- system ("GIT_DIR=\"$repo\" git --bare init") ;
+ system ("GIT_DIR=\"$repo\" git init --bare --shared=group") ;
+ system ("GIT_DIR=\"$repo\" git update-server-info") ;
+ if (is_file ("$repo/hooks/post-update.sample")) {
+ rename ("$repo/hooks/post-update.sample",
+ "$repo/hooks/post-update") ;
+ }
+ if (!is_file ("$repo/hooks/post-update")) {
+ $f = fopen ("$repo/hooks/post-update") ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
+ }
+ if (is_file ("$repo/hooks/post-update")) {
+ system ("chmod +x $repo/hooks/post-update") ;
+ }
system ("echo \"Git repository for $project_name\" > $repo/description") ;
+ system ("find $repo -type d | xargs chmod g+s") ;
}
- system ("chgrp -R $unix_group $repo") ;
+ system ("chgrp -R $unix_group $root") ;
+ system ("chmod g+s $root") ;
if ($project->enableAnonSCM()) {
- system ("chmod -R g+wXs,o+rX-w $repo") ;
+ system ("chmod -R g+wX,o+rX-w $root") ;
} else {
- system ("chmod -R g+wXs,o-rwx $repo") ;
+ system ("chmod -R g+wX,o-rwx $root") ;
}
}
$rootdir = $this->git_root;
fwrite($config_f, "\$projectroot = '$rootdir';\n");
fwrite($config_f, "\$projects_list = '$config_dir/gitweb.list';\n");
- fwrite($config_f, "@git_base_url_list = ('". util_make_url ('/anonscm/git/') . "');\n");
+ fwrite($config_f, "@git_base_url_list = ('". util_make_url ('/anonscm/git') . "');\n");
fwrite($config_f, "\$logo = '". util_make_url ('/plugins/scmgit/gitweb/git-logo.png') . "';\n");
fwrite($config_f, "\$favicon = '". util_make_url ('/plugins/scmgit/gitweb/git-favicon.png')."';\n");
fwrite($config_f, "\$stylesheet = '". util_make_url ('/plugins/scmgit/gitweb/gitweb.css')."';\n");
$f = fopen ($fname.'.new', 'w') ;
foreach ($list as $project) {
- fwrite ($f, $project->getUnixName() . "\n");
+ $repos = $this->getRepositories($rootdir . "/" . $project->getUnixName());
+ foreach ($repos as $repo) {
+ $reldir = substr($repo, strlen($rootdir) + 1);
+ fwrite ($f, $reldir . "\n");
+ }
}
fclose ($f) ;
chmod ($fname.'.new', 0644) ;
rename ($fname.'.new', $fname) ;
}
+ function getRepositories($path) {
+ if (! is_dir($path))
+ return;
+ $list = Array();
+ $entries = scandir($path);
+ foreach ($entries as $entry) {
+ $fullname = $path . "/" . $entry;
+ if (($entry == ".") or ($entry == ".."))
+ continue;
+ if (is_dir($fullname)) {
+ if (is_link($fullname))
+ continue;
+ $result = $this->getRepositories($fullname);
+ $list = array_merge($list, $result);
+ } else if ($entry == "HEAD") {
+ $list[] = $path;
+ }
+ }
+ return $list;
+ }
+
function generateSnapshots ($params) {
- global $sys_scm_tarballs_path ;
+ global $sys_scm_tarballs_path, $sys_scm_snapshots_path ;
$project = $this->checkParams ($params) ;
if (!$project) {
return false;
}
+ // TODO: ideally we generate one snapshot per git repository
$toprepo = $this->git_root ;
- $repo = $toprepo . '/' . $project->getUnixName() ;
+ $repo = $toprepo . '/' . $project->getUnixName() . '/' . $project->getUnixName() . '.git' ;
if (!is_dir ($repo)) {
unlink ($tarball) ;
return false ;
}
- system ("git archive --format=tar --prefix=$group_name-scm-$today/ HEAD | gzip > $tmp/snapshot.tar.gz");
+ system ("GIT_DIR=\"$repo\" git archive --format=tar --prefix=$group_name-scm-$today/ HEAD | gzip > $tmp/snapshot.tar.gz");
chmod ("$tmp/snapshot.tar.gz", 0644) ;
copy ("$tmp/snapshot.tar.gz", $snapshot) ;
unlink ("$tmp/snapshot.tar.gz") ;
$adds = 0 ;
$updates = 0 ;
- $repo = $this->git_root . '/' . $project->getUnixName() ;
- if (!is_dir ($repo) || !is_file ("$repo/refs")) {
+ $repo = $this->git_root . '/' . $project->getUnixName() . '/' . $project->getUnixName() . '.git';
+ if (!is_dir ($repo) || !is_dir ("$repo/refs")) {
// echo "No repository\n" ;
db_rollback () ;
return false ;
}
-
- $pipe = popen ("GIT_DIR=$repo git log --since='1 day ago' "
- ."--all --pretty='%n%an <%ae>' --name-status", 'r' ) ;
+
+ $pipe = popen ("GIT_DIR=\"$repo\" git log --since=@$start_time --until=@$end_time --all --pretty='format:%n%an <%ae>' --name-status", 'r' ) ;
// cleaning stats_cvs_* table for the current day
$res = db_query_params ('DELETE FROM stats_cvs_group WHERE month=$1 AND day=$2 AND group_id=$3',
db_rollback () ;
return false ;
}
-
+
$last_user = "";
while (!feof($pipe) && $data = fgets ($pipe)) {
$line = trim($data);
$last_user = $matches['name'];
} else {
// Short-commit stats line
- preg_match("/(?<mode>[AM])[ ]+(?<file>.+)$/", $line, $matches);
+ preg_match("/^(?<mode>[AM])\s+(?<file>.+)$/", $line, $matches);
if ($last_user == "") continue;
if ($matches['mode'] == 'A') {
$usr_adds[$last_user]++;
}
}
}
-
+
// inserting group results in stats_cvs_groups
- if (!db_query_params ('INSERT INTO stats_cvs_group (month,day,group_id,checkouts,commits,adds) VALUES ($1,$2,$3,$4,$5,$6)',
- array ($month_string,
- $day,
- $project->getID(),
- 0,
- $updates,
- $adds))) {
- echo "Error while inserting into stats_cvs_group\n" ;
- db_rollback () ;
- return false ;
+ if ($updates > 0 || $adds > 0) {
+ if (!db_query_params ('INSERT INTO stats_cvs_group (month,day,group_id,checkouts,commits,adds) VALUES ($1,$2,$3,$4,$5,$6)',
+ array ($month_string,
+ $day,
+ $project->getID(),
+ 0,
+ $updates,
+ $adds))) {
+ echo "Error while inserting into stats_cvs_group\n" ;
+ db_rollback () ;
+ return false ;
+ }
}
// building the user list
continue;
}
- if (!db_query_params ('INSERT INTO stats_cvs_user (month,day,group_id,user_id,commits,adds) VALUES ($1,$2,$3,$4,$5,$6)',
- array ($month_string,
- $day,
- $project->getID(),
- $user_id,
- $usr_updates[$user] ? $usr_updates[$user] : 0,
- $usr_adds[$user] ? $usr_adds[$user] : 0))) {
- echo "Error while inserting into stats_cvs_user\n" ;
- db_rollback () ;
- return false ;
+ $uu = $usr_updates[$user] ? $usr_updates[$user] : 0 ;
+ $ua = $usr_adds[$user] ? $usr_adds[$user] : 0 ;
+ if ($uu > 0 || $ua > 0) {
+ if (!db_query_params ('INSERT INTO stats_cvs_user (month,day,group_id,user_id,commits,adds) VALUES ($1,$2,$3,$4,$5,$6)',
+ array ($month_string,
+ $day,
+ $project->getID(),
+ $user_id,
+ $uu,
+ $ua))) {
+ echo "Error while inserting into stats_cvs_user\n" ;
+ db_rollback () ;
+ return false ;
+ }
}
}
}