if ($rows > 0) {
$b .= '<h2>';
$b .= _('Developer\'s repository');
- $b .= '</h2>';
+ $b .= '</h2>'."\n";
$b .= '<p>';
$b .= ngettext('One of this project\'s members also has a personal Git repository that can be checked out anonymously.',
'Some of this project\'s members also have personal Git repositories that can be checked out anonymously.',
function getInstructionsForRW($project) {
if (session_loggedin()) {
- $u =& user_get_object(user_getid());
+ $u = user_get_object(user_getid());
$d = $u->getUnixName();
if (forge_get_config('use_ssh', 'scmgit')) {
$b = '<h2>';
- $b .= _('Developer GIT Access via SSH');
+ $b .= _('Developer Git Access via SSH');
$b .= '</h2>';
$b .= '<p>';
- $b .= _('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.');
+ $b .= _('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.');
$b .= '</p>';
- $b .= '<p><tt>git clone git+ssh://'.$d.'@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
+ $b .= '<p><tt>git clone git+ssh://'.$d.'@' . $this->getBoxForProject($project) . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
} elseif (forge_get_config('use_dav', 'scmgit')) {
$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
$b = '<h2>';
- $b .= _('Developer GIT Access via HTTP');
+ $b .= _('Developer Git Access via HTTP');
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the GIT tree via this method. Enter your site password when prompted.');
+ $b .= _('Only project developers can access the Git tree via this method. Enter your site password when prompted.');
$b .= '</p>';
$b .= '<p><tt>git clone '.$protocol.'://'.$d.'@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
} else {
} else {
if (forge_get_config('use_ssh', 'scmgit')) {
$b = '<h2>';
- $b .= _('Developer GIT Access via SSH');
+ $b .= _('Developer Git Access via SSH');
$b .= '</h2>';
$b .= '<p>';
- $b .= _('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.');
+ $b .= _('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.');
$b .= '</p>';
- $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
+ $b .= '<p><tt>git clone git+ssh://<i>'._('developername').'</i>@' . $this->getBoxForProject($project) . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
} elseif (forge_get_config('use_dav', 'scmgit')) {
$protocol = forge_get_config('use_ssl', 'scmgit')? 'https' : 'http';
$b = '<h2>';
- $b .= _('Developer GIT Access via HTTP');
+ $b .= _('Developer Git Access via HTTP');
$b .= '</h2>';
$b .= '<p>';
- $b .= _('Only project developers can access the GIT tree via this method. Enter your site password when prompted.');
+ $b .= _('Only project developers can access the Git tree via this method. Enter your site password when prompted.');
$b .= '</p>';
$b .= '<p><tt>git clone '.$protocol.'://<i>'._('developername').'</i>@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/'. $project->getUnixName() .'.git</tt></p>' ;
}
$b .= '<p>';
$b .= _('You have a personal repository for this project, accessible through SSH with the following method. Enter your site password when prompted.');
$b .= '</p>';
- $b .= '<p><tt>git clone git+ssh://'.$u->getUnixName().'@' . $this->getBoxForProject($project) . '/'. forge_get_config('scm_root', 'scmgit') .'/'. $project->getUnixName() .'/users/'. $u->getUnixName() .'.git</tt></p>' ;
+ $b .= '<p><tt>git clone git+ssh://'.$u->getUnixName().'@' . $this->getBoxForProject($project) . '/'. forge_get_config('repos_path', 'scmgit') .'/'. $project->getUnixName() .'/users/'. $u->getUnixName() .'.git</tt></p>' ;
} else {
$glist = $u->getGroups();
foreach ($glist as $g) {
}
function printBrowserPage($params) {
- global $HTML;
-
$project = $this->checkParams($params);
if (!$project) {
return false;
return $b ;
}
+ static function createUserRepo($params) {
+ $project = $params['project'];
+ $project_name = $project->getUnixName();
+ $user_name = $params['user_name'];
+ $unix_group = $params['unix_group'];
+ $main_repo = $params['main_repo'];
+ $root = $params['root'];
+
+ $repodir = $root . '/users/' . $user_name . '.git' ;
+ chgrp($repodir, $unix_group);
+ if ($project->enableAnonSCM()) {
+ chmod ($repodir, 02755);
+ } else {
+ chmod ($repodir, 02750);
+ }
+ if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
+ system ("git clone --bare $main_repo $repodir") ;
+ system ("GIT_DIR=\"$repodir\" git update-server-info") ;
+ if (is_file ("$repodir/hooks/post-update.sample")) {
+ rename ("$repodir/hooks/post-update.sample",
+ "$repodir/hooks/post-update") ;
+ }
+ if (!is_file ("$repodir/hooks/post-update")) {
+ $f = fopen ("$repodir/hooks/post-update","x+") ;
+ fwrite ($f, "exec git-update-server-info\n") ;
+ fclose ($f) ;
+ }
+ if (is_file ("$repodir/hooks/post-update")) {
+ system ("chmod +x $repodir/hooks/post-update") ;
+ }
+ system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
+ }
+ }
+
function createOrUpdateRepo($params) {
- $project = $this->checkParams($params);
+ $project = $this->checkParams ($params) ;
if (!$project) {
return false ;
}
system ("mkdir -p $root");
$output = '';
+ if (forge_get_config('use_ssh','scmgit')) {
+ $unix_group = 'scm_' . $project_name ;
+ } else {
+ $unix_group = forge_get_config('apache_group');
+ }
+
$main_repo = $root . '/' . $project_name . '.git' ;
- if (!is_file ("$main_repo/HEAD") && !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs")) {
- exec ("GIT_DIR=\"$main_repo\" git init --bare --shared=group", $result) ;
- $output .= join("<br />", $result);
- $result = '';
- exec ("GIT_DIR=\"$main_repo\" git update-server-info", $result) ;
- $output .= join("<br />", $result);
- if (is_file ("$main_repo/hooks/post-update.sample")) {
- rename ("$main_repo/hooks/post-update.sample",
- "$main_repo/hooks/post-update") ;
+ if (!is_dir($main_repo) || (!is_file("$main_repo/HEAD") &&
+ !is_dir("$main_repo/objects") && !is_dir("$main_repo/refs"))) {
+ $tmp_repo = util_mkdtemp('.git', $project_name);
+ if ($tmp_repo == false) {
+ return false;
}
- if (!is_file ("$main_repo/hooks/post-update")) {
- $f = fopen ("$main_repo/hooks/post-update") ;
+ $result = system ("GIT_DIR=\"$tmp_repo\" git init --bare --shared=group") ;
+ $output .= join("<br />", array($result));
+ $result = system ("GIT_DIR=\"$tmp_repo\" git update-server-info") ;
+ $output .= join("<br />", array($result));
+ if (is_file ("$tmp_repo/hooks/post-update.sample")) {
+ rename ("$tmp_repo/hooks/post-update.sample",
+ "$tmp_repo/hooks/post-update") ;
+ }
+ if (!is_file ("$tmp_repo/hooks/post-update")) {
+ $f = fopen ("$tmp_repo/hooks/post-update") ;
fwrite ($f, "exec git-update-server-info\n") ;
fclose ($f) ;
}
- if (is_file ("$main_repo/hooks/post-update")) {
- system ("chmod +x $main_repo/hooks/post-update") ;
+ if (is_file ("$tmp_repo/hooks/post-update")) {
+ system ("chmod +x $tmp_repo/hooks/post-update") ;
+ }
+ system ("echo \"Git repository for $project_name\" > $tmp_repo/description") ;
+ system ("find $tmp_repo -type d | xargs chmod g+s") ;
+ system ("chgrp -R $unix_group $tmp_repo") ;
+ system ("chmod -R g+wX,o+rX-w $tmp_repo") ;
+ if ($project->enableAnonSCM()) {
+ system ("chmod g+wX,o+rX-w $root") ;
+ } else {
+ system ("chmod g+wX,o-rwx $root") ;
+ system ("chmod g+wX,o-rwx $tmp_repo") ;
+ }
+ $ret = true;
+ /*
+ * $main_repo can already exist, for example if it’s
+ * not a directory or doesn’t contain a HEAD file or
+ * an objects or refs subdirectory… move it out of
+ * the way in these cases
+ */
+ system("if test -e $main_repo || test -h $main_repo; then d=\$(mktemp -d $main_repo.scmgit-moved.XXXXXXXXXX) && mv -f $main_repo \$d/; fi");
+ /* here’s still a TOCTOU but we check $ret below */
+ system("mv $tmp_repo $main_repo", $ret);
+ if ($ret != 0) {
+ return false;
}
- system ("echo \"Git repository for $project_name\" > $main_repo/description") ;
- system ("find $main_repo -type d | xargs chmod g+s") ;
}
if (forge_get_config('use_ssh','scmgit')) {
- $unix_group = 'scm_' . $project_name ;
- system ("chgrp -R $unix_group $root") ;
- system ("chmod g+s $root") ;
if ($project->enableAnonSCM()) {
system ("chmod g+wX,o+rX-w $root") ;
- system ("chmod -R g+wX,o+rX-w $main_repo") ;
+ system ("chmod g+rwX,o+rX-w $main_repo") ;
} else {
system ("chmod g+wX,o-rwx $root") ;
- system ("chmod -R g+wX,o-rwx $main_repo") ;
+ system ("chmod g+rwX,o-rwx $main_repo") ;
}
} else {
$unix_user = forge_get_config('apache_user');
- $unix_group = forge_get_config('apache_group');
- system ("chown -R $unix_user:$unix_group $main_repo") ;
- system ("chmod -R g-rwx,o-rwx $main_repo") ;
+ system ("chown $unix_user:$unix_group $main_repo") ;
+ system ("chmod g-rwx,o-rwx $main_repo") ;
}
$result = db_query_params ('SELECT u.user_name FROM plugin_scmgit_personal_repos p, users u WHERE p.group_id=$1 AND u.user_id=p.user_id AND u.unix_status=$2',
system ("mkdir -p $root/users") ;
$user_name = db_result($result,$i,'user_name');
$repodir = $root . '/users/' . $user_name . '.git' ;
-
- if (!is_file ("$repodir/HEAD") && !is_dir("$repodir/objects") && !is_dir("$repodir/refs")) {
- system ("git clone --bare $main_repo $repodir") ;
- system ("GIT_DIR=\"$repodir\" git update-server-info") ;
- if (is_file ("$repodir/hooks/post-update.sample")) {
- rename ("$repodir/hooks/post-update.sample",
- "$repodir/hooks/post-update") ;
- }
- if (!is_file ("$repodir/hooks/post-update")) {
- $f = fopen ("$repodir/hooks/post-update") ;
- fwrite ($f, "exec git-update-server-info\n") ;
- fclose ($f) ;
- }
- if (is_file ("$repodir/hooks/post-update")) {
- system ("chmod +x $repodir/hooks/post-update") ;
- }
- system("echo \"Git repository for user $user_name in project $project_name\" > $repodir/description");
- system ("chown -R $user_name:$unix_group $repodir") ;
+
+ if (!is_dir($repodir) && mkdir ($repodir, 0700)) {
+ chown ($repodir, $user_name) ;
+
+ $params = array();
+ $params['project'] = $project;
+ $params['user_name'] = $user_name;
+ $params['unix_group'] = $unix_group;
+ $params['root'] = $root;
+ $params['main_repo'] = $main_repo;
+
+ util_sudo_effective_user($user_name,
+ array("GitPlugin","createUserRepo"),
+ $params);
}
}
if (is_dir ("$root/users")) {
if ($project->enableAnonSCM()) {
- system ("chmod -R g+rX-w,o+rX-w $root/users") ;
+ system ("chmod g+rX-w,o+rX-w $root/users") ;
} else {
- system ("chmod -R g+rX-w,o-rwx $root/users") ;
+ system ("chmod g+rX-w,o-rwx $root/users") ;
}
}
$params['output'] = $output;
}
$config_dir = forge_get_config('config_path').'/plugins/scmgit';
+ if (!is_dir($config_dir)) {
+ mkdir($config_dir, 0755, true);
+ }
$fname = $config_dir . '/gitweb.conf' ;
$config_f = fopen($fname.'.new', 'w') ;
$rootdir = forge_get_config('repos_path', 'scmgit');
fwrite($config_f, "\$logo = '". util_make_url('/plugins/scmgit/git-logo.png') . "';\n");
fwrite($config_f, "\$favicon = '". util_make_url('/plugins/scmgit/git-favicon.png')."';\n");
fwrite($config_f, "\$stylesheet = '". util_make_url('/plugins/scmgit/gitweb.css')."';\n");
+ fwrite($config_f, "\$javascript = '". util_make_url('/plugins/scmgit/gitweb.js')."';\n");
fwrite($config_f, "\$prevent_xss = 'true';\n");
fclose($config_f);
chmod ($fname.'.new', 0644) ;
}
function gatherStats ($params) {
- global $last_user, $usr_adds, $usr_deletes,
- $usr_updates, $updates, $adds;
-
$project = $this->checkParams ($params) ;
if (!$project) {
return false ;
}
if ($params['mode'] == 'day') {
- db_begin();
-
$year = $params ['year'] ;
$month = $params ['month'] ;
$day = $params ['day'] ;
$repo = forge_get_config('repos_path', 'scmgit') . '/' . $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=@$start_time --until=@$end_time --all --pretty='format:%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 2>/dev/null", 'r' ) ;
+
+ db_begin();
// 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',
}
}
- $uu = $usr_updates[$user] ? $usr_updates[$user] : 0 ;
- $ua = $usr_adds[$user] ? $usr_adds[$user] : 0 ;
+ $uu = isset ($usr_updates[$user]) ? $usr_updates[$user] : 0 ;
+ $ua = isset ($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,
return false ;
}
+ // Skip empty repo (no HEAD present in repository)
+ $ref = trim(`GIT_DIR=$repo git symbolic-ref HEAD`);
+ if (!file_exists($repo.'/'.$ref)) {
+ return false;
+ }
+
$tmp = trim (`mktemp -d`) ;
if ($tmp == '') {
return false ;