File TODO changed (mode: 100644) (index 0f85ce8..3def182) |
16 |
16 |
[ ] Fix the "edit repo" page! |
[ ] Fix the "edit repo" page! |
17 |
17 |
[ ] With FMH rights, seems that we insert a merge request, but create branch is |
[ ] With FMH rights, seems that we insert a merge request, but create branch is |
18 |
18 |
rejected in next hook! |
rejected in next hook! |
19 |
|
[ ] Update of databse must be done from a global init function, not by admin. |
|
20 |
|
[ ] Switch all menus to templates! |
|
|
19 |
|
[ ] Update of database must be done from a global init function, not by admin. |
|
20 |
|
[ ] Switch all menus to templates. |
|
21 |
|
[ ] Switch all forms to templates. |
21 |
22 |
[ ] 'cop' variable is not good - I do not remember what it means! |
[ ] 'cop' variable is not good - I do not remember what it means! |
22 |
23 |
[ ] Why is not working to access a user page ("invalid repo")?! |
[ ] Why is not working to access a user page ("invalid repo")?! |
23 |
24 |
[ ] Delay connection to database. |
[ ] Delay connection to database. |
|
26 |
27 |
[ ] CSRF token is not used in admin page for an ordinary user! |
[ ] CSRF token is not used in admin page for an ordinary user! |
27 |
28 |
[ ] Differentiate between owner of a repository, currently logged in user and admin. |
[ ] Differentiate between owner of a repository, currently logged in user and admin. |
28 |
29 |
[ ] Warn before deleting a repo! |
[ ] Warn before deleting a repo! |
29 |
|
[ ] Update structure at any function call (after an upgrade). |
|
|
30 |
|
[ ] Update db structure at any function call (after an upgrade). |
30 |
31 |
[ ] Store by uid the repos, and make links to them. Make a function to rename |
[ ] Store by uid the repos, and make links to them. Make a function to rename |
31 |
32 |
a username. We have to keep track of renames so old links will |
a username. We have to keep track of renames so old links will |
32 |
33 |
still work. |
still work. |
33 |
34 |
[ ] Move repos to /var/lib |
[ ] Move repos to /var/lib |
|
35 |
|
[ ] Fix 'update' hook - is a little bit strange. |
|
36 |
|
[ ] Check if repo_path is valid from security pov. |
|
37 |
|
[ ] Check double slashes in URLs. |
34 |
38 |
[ ] |
[ ] |
35 |
39 |
|
|
36 |
40 |
== Normal priority == |
== Normal priority == |
|
41 |
|
[ ] When logging _SERVER variables, log only the ones prefixed by ROCKETGIT_. |
|
42 |
|
[ ] Ask password when doing any critical change of the account and send mail. |
|
43 |
|
[ ] Add commercial posibility for VPNs to be sure you can push/fetch safely. |
|
44 |
|
[ ] Add a possibiliy (link shown in push message) to delete/update/etc. the |
|
45 |
|
merge request. |
|
46 |
|
[ ] Allow a nonstandard port for web. |
37 |
47 |
[ ] Put form error messages next to the label. |
[ ] Put form error messages next to the label. |
38 |
48 |
[ ] Get rid of $rr! |
[ ] Get rid of $rr! |
39 |
49 |
[ ] favicon.ico is not in theme! |
[ ] favicon.ico is not in theme! |
File hooks/post-receive changed (mode: 100755) (index 9c4dabd..0355ab7) |
8 |
8 |
// The error code is ignored. |
// The error code is ignored. |
9 |
9 |
// Useful to send mails. |
// Useful to send mails. |
10 |
10 |
// Warn: new_ref may not point to ref because of concurrent updates. |
// Warn: new_ref may not point to ref because of concurrent updates. |
|
11 |
|
// TODO: Re-check man githooks and git-receive-pack! |
11 |
12 |
// |
// |
12 |
13 |
|
|
13 |
14 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
|
... |
... |
require_once($INC . "/util.inc.php"); |
22 |
23 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
23 |
24 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
24 |
25 |
require_once($INC . "/repo.inc.php"); |
require_once($INC . "/repo.inc.php"); |
|
26 |
|
require_once($INC . "/prof.inc.php"); |
|
27 |
|
|
|
28 |
|
rg_prof_start("post-receive"); |
25 |
29 |
|
|
26 |
30 |
rg_log_set_file($rg_log_dir . "/hook_post-receive.log"); |
rg_log_set_file($rg_log_dir . "/hook_post-receive.log"); |
27 |
31 |
|
|
28 |
|
rg_log("Start..."); |
|
|
32 |
|
$namespace = getenv("GIT_NAMESPACE"); |
|
33 |
|
$repo_path = getenv("ROCKETGIT_REPO_PATH"); |
|
34 |
|
|
|
35 |
|
rg_log("Start namespace=$namespace repo_path=$repo_path"); |
29 |
36 |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
30 |
37 |
|
|
31 |
38 |
umask(0022); |
umask(0022); |
32 |
39 |
|
|
33 |
|
|
|
34 |
40 |
$f = @fopen("php://stdin", "r"); |
$f = @fopen("php://stdin", "r"); |
35 |
41 |
if ($f === FALSE) { |
if ($f === FALSE) { |
36 |
42 |
rg_log("Error: Cannot open stdin!"); |
rg_log("Error: Cannot open stdin!"); |
|
... |
... |
while (($set = fgets($f))) { |
49 |
55 |
|
|
50 |
56 |
if (empty($refname) || empty($old_rev) || empty($new_rev)) |
if (empty($refname) || empty($old_rev) || empty($new_rev)) |
51 |
57 |
rg_git_fatal("Invalid parameters [$old_rev $new_rev $refname]!"); |
rg_git_fatal("Invalid parameters [$old_rev $new_rev $refname]!"); |
52 |
|
|
|
53 |
|
// TODO: What we should do here?! check man githooks and git-receive-pack! |
|
54 |
58 |
} |
} |
55 |
59 |
fclose($f); |
fclose($f); |
56 |
60 |
|
|
|
... |
... |
rg_log("Took " . $diff . "ms."); |
68 |
72 |
|
|
69 |
73 |
// Mark repository dirty for disk statistics and other stuff |
// Mark repository dirty for disk statistics and other stuff |
70 |
74 |
@file_put_contents($rg_path . "/dirty", ""); |
@file_put_contents($rg_path . "/dirty", ""); |
|
75 |
|
|
|
76 |
|
rg_prof_end("post-receive"); |
|
77 |
|
rg_prof_log("rg_log"); |
71 |
78 |
?> |
?> |
File hooks/pre-receive changed (mode: 100755) (index aa797ac..58bf249) |
3 |
3 |
|
|
4 |
4 |
// |
// |
5 |
5 |
// pre-receive hook |
// pre-receive hook |
6 |
|
// If one check fails, receiving is denied. |
|
7 |
|
// Executed before any ref is updated and before fast-forward checks. |
|
|
6 |
|
// Does nothing in this moment |
8 |
7 |
// |
// |
9 |
8 |
|
|
|
9 |
|
exit(0); |
|
10 |
|
|
10 |
11 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
11 |
12 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
12 |
13 |
|
|
|
... |
... |
require_once($INC . "/util.inc.php"); |
19 |
20 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
20 |
21 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
21 |
22 |
require_once($INC . "/repo.inc.php"); |
require_once($INC . "/repo.inc.php"); |
22 |
|
require_once($INC . "/mr.inc.php"); |
|
23 |
23 |
|
|
24 |
24 |
rg_log_set_file($rg_log_dir . "/hook_pre-receive.log"); |
rg_log_set_file($rg_log_dir . "/hook_pre-receive.log"); |
25 |
25 |
|
|
26 |
|
$uid = @sprintf("%u", getenv("ROCKETGIT_UID")); |
|
27 |
|
$rights = getenv("ROCKETGIT_REPO_RIGHTS"); |
|
28 |
|
$repo_id = getenv("ROCKETGIT_REPO_ID"); |
|
29 |
|
$ip = getenv("ROCKETGIT_IP"); |
|
30 |
|
$namespace = getenv("GIT_NAMESPACE"); |
|
31 |
|
|
|
32 |
|
rg_log("Start uid=$uid repo_id=$repo_id rights=[$rights] namespace=$namespace" |
|
33 |
|
. " ip=$ip..."); |
|
|
26 |
|
rg_log("Start"); |
34 |
27 |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
35 |
28 |
|
|
36 |
29 |
umask(0022); |
umask(0022); |
|
... |
... |
while (($set = fgets($f))) { |
55 |
48 |
if (empty($refname) || empty($old_rev) || empty($new_rev)) |
if (empty($refname) || empty($old_rev) || empty($new_rev)) |
56 |
49 |
rg_git_fatal("Invalid parameters [$old_rev $new_rev $refname]!"); |
rg_git_fatal("Invalid parameters [$old_rev $new_rev $refname]!"); |
57 |
50 |
|
|
58 |
|
if (rg_rights_allow($rights, "P") === FALSE) { |
|
59 |
|
if (rg_rights_allow($rights, "H") === FALSE) { |
|
60 |
|
$msg = rg_template("msg/push_not_allowed.txt", array()); |
|
61 |
|
rg_git_fatal($refname. ":\n" . $msg); |
|
62 |
|
} |
|
63 |
|
|
|
64 |
|
// anonymous push - create a merge request |
|
65 |
|
$r = rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, |
|
66 |
|
$refname, $ip); |
|
67 |
|
if ($r !== TRUE) |
|
68 |
|
rg_git_fatal($refname . ":\n" . rg_mr_error()); |
|
69 |
|
// TODO: Can we reject individual updates not all of them?! |
|
70 |
|
|
|
71 |
|
$msg = rg_template("msg/push_merge_request.txt", array()); |
|
72 |
|
rg_git_info($refname . ":\n" . $msg); |
|
73 |
|
} |
|
74 |
51 |
} |
} |
75 |
52 |
fclose($f); |
fclose($f); |
76 |
53 |
|
|
|
... |
... |
rg_log("Took " . $diff . "ms."); |
84 |
61 |
. "\nuid: " . $uid |
. "\nuid: " . $uid |
85 |
62 |
. "\npara: $refname $old_rev $new_rev" |
. "\npara: $refname $old_rev $new_rev" |
86 |
63 |
. "\nTook: " . $diff . "ms" |
. "\nTook: " . $diff . "ms" |
87 |
|
. "\t_SERVER: " . print_r($_SERVER, TRUE)); |
|
|
64 |
|
. "\n_SERVER: " . print_r($_SERVER, TRUE)); |
|
65 |
|
|
88 |
66 |
?> |
?> |
File hooks/update changed (mode: 100755) (index 695b75d..16648f3) |
4 |
4 |
// |
// |
5 |
5 |
// This is called by 'update' hook |
// This is called by 'update' hook |
6 |
6 |
// Inspired by update.sample in git package |
// Inspired by update.sample in git package |
7 |
|
// TODO: what we receive when a tag will be created? |
|
|
7 |
|
// It is executed before each ref is updated. |
|
8 |
|
// |
|
9 |
|
// TODO: what do we receive when a tag will be created? |
8 |
10 |
// |
// |
9 |
11 |
|
|
10 |
12 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
11 |
13 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
12 |
14 |
|
|
13 |
|
$_start = microtime(TRUE); |
|
14 |
|
|
|
15 |
15 |
require_once("/etc/rocketgit/config.php"); |
require_once("/etc/rocketgit/config.php"); |
16 |
16 |
|
|
17 |
17 |
$INC = $rg_scripts . "/inc"; |
$INC = $rg_scripts . "/inc"; |
|
... |
... |
require_once($INC . "/util.inc.php"); |
19 |
19 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
20 |
20 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
21 |
21 |
require_once($INC . "/repo.inc.php"); |
require_once($INC . "/repo.inc.php"); |
|
22 |
|
require_once($INC . "/prof.inc.php"); |
|
23 |
|
require_once($INC . "/mr.inc.php"); |
|
24 |
|
|
|
25 |
|
rg_prof_start("hook-update"); |
22 |
26 |
|
|
23 |
27 |
rg_log_set_file($rg_log_dir . "/hook_update.log"); |
rg_log_set_file($rg_log_dir . "/hook_update.log"); |
24 |
28 |
|
|
25 |
|
$uid = @sprintf("%u", getenv("ROCKETGIT_UID")); |
|
26 |
|
$rights = getenv("ROCKETGIT_REPO_RIGHTS"); |
|
|
29 |
|
$a = array(); |
|
30 |
|
|
|
31 |
|
$a['uid'] = @sprintf("%u", getenv("ROCKETGIT_UID")); |
|
32 |
|
$a['rights'] = getenv("ROCKETGIT_REPO_RIGHTS"); |
|
33 |
|
$a['repo_id'] = getenv("ROCKETGIT_REPO_ID"); |
|
34 |
|
$a['ip'] = getenv("ROCKETGIT_IP"); |
|
35 |
|
$a['namespace'] = getenv("GIT_NAMESPACE"); |
27 |
36 |
|
|
28 |
|
rg_log("Start uid=$uid, rights=[$rights]..."); |
|
|
37 |
|
rg_log("Start " . rg_array2string($a)); |
29 |
38 |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
rg_log("_SERVER: " . print_r($_SERVER, TRUE)); |
30 |
39 |
|
|
31 |
40 |
umask(0022); |
umask(0022); |
32 |
41 |
|
|
33 |
42 |
|
|
34 |
|
$refname = @rg_git_reference($_SERVER['argv'][1]); |
|
35 |
|
$old_rev = rg_git_rev(@$_SERVER['argv'][2]); |
|
36 |
|
$new_rev = rg_git_rev(@$_SERVER['argv'][3]); |
|
37 |
|
rg_log("refname=$refname old_rev=$old_rev new_rev=$new_rev."); |
|
|
43 |
|
$a['refname'] = @rg_git_reference($_SERVER['argv'][1]); |
|
44 |
|
$a['old_rev'] = rg_git_rev(@$_SERVER['argv'][2]); |
|
45 |
|
$a['new_rev'] = rg_git_rev(@$_SERVER['argv'][3]); |
|
46 |
|
rg_log("refname=" . $a['refname'] . " old_rev=" . $a['old_rev'] |
|
47 |
|
. " new_rev=" . $a['new_rev']); |
38 |
48 |
|
|
39 |
|
if (empty($refname) || empty($old_rev) || empty($new_rev)) |
|
40 |
|
rg_git_fatal("Invalid parameters [$refname $old_rev $new_rev]!"); |
|
|
49 |
|
if (empty($a['refname']) || empty($a['old_rev']) || empty($a['new_rev'])) |
|
50 |
|
rg_git_fatal("Invalid parameters [" . $a['refname'] |
|
51 |
|
. " " . $a['old_rev'] ." " . $a['new_rev'] . "]!"); |
41 |
52 |
|
|
42 |
|
if (strcmp($new_rev, $rg_git_zero) == 0) |
|
43 |
|
$new_rev_type = "delete"; |
|
|
53 |
|
if (strcmp($a['new_rev'], $rg_git_zero) == 0) |
|
54 |
|
$a['new_rev_type'] = "delete"; |
44 |
55 |
else |
else |
45 |
|
$new_rev_type = rg_git_type($new_rev); |
|
46 |
|
rg_log("new_rev_type=$new_rev_type."); |
|
47 |
|
|
|
48 |
|
if (strcmp($new_rev_type, "commit") == 0) { |
|
49 |
|
rg_log("It's a commit..."); |
|
50 |
|
|
|
51 |
|
if (strcmp($old_rev, $rg_git_zero) != 0) { |
|
52 |
|
rg_log("This is a reference update..."); |
|
53 |
|
|
|
54 |
|
// check non fast-forward update |
|
55 |
|
if (!rg_rights_allow($rights, "O")) { |
|
56 |
|
$merge_base = rg_git_merge_base($old_rev, $new_rev); |
|
57 |
|
if ($merge_base === FALSE) { |
|
58 |
|
rg_log("Error: " . rg_git_error()); |
|
59 |
|
rg_git_fatal("Internal error! Try again later!"); |
|
60 |
|
} |
|
61 |
|
|
|
62 |
|
if (strcmp($merge_base, $old_rev) != 0) |
|
63 |
|
rg_git_fatal("Non fast-forward is not allowed for $refname!"); |
|
64 |
|
} |
|
65 |
|
} |
|
66 |
|
|
|
67 |
|
if (strncmp($refname, "refs/tags/", 10) == 0) { |
|
68 |
|
rg_log("Un-annotated tag..."); |
|
69 |
|
if (strcmp($old_rev, $rg_git_zero) == 0) { |
|
70 |
|
if (!rg_rights_allow($rights, "Y")) |
|
71 |
|
rg_git_fatal("No rights to create an un-annotated tag!"); |
|
72 |
|
} else { //change |
|
73 |
|
if (!rg_rights_allow($rights, "U")) |
|
74 |
|
rg_git_fatal("No rights to change an un-annotated tag!"); |
|
75 |
|
} |
|
76 |
|
} else if (strncmp($refname, "refs/heads/", 11) == 0) { |
|
77 |
|
if (strcmp($old_rev, $rg_git_zero) == 0) { |
|
78 |
|
rg_log("Creating a branch..."); |
|
79 |
|
if (!rg_rights_allow($rights, "C")) |
|
80 |
|
rg_git_fatal("You have no rights to create a branch [$refname]!"); |
|
81 |
|
} else if (rg_git_rev_ok($new_rev . "^2")) { |
|
82 |
|
rg_log("Merge commit..."); |
|
83 |
|
if (!rg_rights_allow($rights, "M")) |
|
84 |
|
rg_git_fatal("You have no rights to push merge commits in [$refname]!"); |
|
85 |
|
} else { |
|
86 |
|
rg_log("Normal commit..."); |
|
87 |
|
if (!rg_rights_allow($rights, "W")) { |
|
88 |
|
if (!rg_git_whitespace_ok($old_rev, $new_rev)) |
|
89 |
|
rg_git_fatal("Bad whitespace is not allowed!"); |
|
90 |
|
} |
|
91 |
|
} |
|
92 |
|
} else { |
|
93 |
|
rg_git_fatal("Unknown refname provided!"); |
|
94 |
|
} |
|
95 |
|
|
|
96 |
|
// TODO: refs/remotes/* |
|
97 |
|
} else if (strcmp($new_rev_type, "delete") == 0) { |
|
98 |
|
rg_log("It's a delete..."); |
|
99 |
|
if (strncmp($refname, "refs/tags/", 10) == 0) { |
|
100 |
|
rg_log("Deleting an un-annotated tag..."); |
|
101 |
|
if (!rg_rights_allow($rights, "u")) |
|
102 |
|
rg_git_fatal("You have no rights to delete a tag!"); |
|
103 |
|
} else if (strncmp($refname, "refs/heads/", 11) == 0) { |
|
104 |
|
rg_log("Deleting a branch..."); |
|
105 |
|
if (!rg_rights_allow($rights, "D")) |
|
106 |
|
rg_git_fatal("You have no rights to delete a branch!"); |
|
107 |
|
} else if (strncmp($refname, "refs/remotes/", 13) == 0) { |
|
108 |
|
rg_log("Deleting a tracking branch..."); |
|
109 |
|
if (!rg_rights_allow($rights, "D")) |
|
110 |
|
rg_git_fatal("You have no rights to delete a tracking branch!"); |
|
111 |
|
} |
|
112 |
|
} else if (strcmp($new_rev_type, "tag") == 0) { |
|
113 |
|
rg_log("It's an annotated tag..."); |
|
114 |
|
if (strncmp($refname, "refs/tags/", 10) == 0) { |
|
115 |
|
rg_log("Modify tag..."); |
|
116 |
|
if (!rg_rights_allow($rights, "S")) |
|
117 |
|
rg_git_fatal("You have no rights to modify a tag!"); |
|
118 |
|
} |
|
|
56 |
|
$a['new_rev_type'] = rg_git_type($a['new_rev']); |
|
57 |
|
rg_log("new_rev_type=" . $a['new_rev_type']); |
|
58 |
|
|
|
59 |
|
if (strncmp($a['refname'], "refs/tags/", 10) == 0) { |
|
60 |
|
rg_git_update_tag($a); |
|
61 |
|
} else if (strncmp($a['refname'], "refs/heads/", 11) == 0) { |
|
62 |
|
rg_git_update_branch($a); |
|
63 |
|
} else if (strncmp($a['refname'], "refs/remotes/", 13) == 0) { |
|
64 |
|
rg_git_fatal("No action for remotes for now!"); |
119 |
65 |
} else { |
} else { |
120 |
|
rg_log("Invalid new_rev type!"); |
|
121 |
|
rg_git_fatal("Internal error!"); |
|
|
66 |
|
rg_git_fatal("Unknown refname type provided [" . $a['refname'] . "]"); |
122 |
67 |
} |
} |
123 |
68 |
|
|
124 |
|
|
|
125 |
|
$diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); |
|
126 |
|
rg_log("Took " . $diff . "ms."); |
|
127 |
|
|
|
128 |
69 |
@file_put_contents($repo_path . "/rg/hook-update", |
@file_put_contents($repo_path . "/rg/hook-update", |
129 |
70 |
"repo: " . $repo . " ($repo_path)" |
"repo: " . $repo . " ($repo_path)" |
130 |
71 |
. "\nat: " . sprintf("%u", $_start) |
. "\nat: " . sprintf("%u", $_start) |
131 |
72 |
. "\nuid: " . $uid |
. "\nuid: " . $uid |
132 |
73 |
. "\npara: $refname $old_rev $new_rev" |
. "\npara: $refname $old_rev $new_rev" |
133 |
|
. "\nTook: " . $diff . "ms" |
|
|
74 |
|
. "\nProfiling:\n" . rg_prof_text() |
134 |
75 |
. "\n_SERVER: " . print_r($_SERVER, TRUE)); |
. "\n_SERVER: " . print_r($_SERVER, TRUE)); |
|
76 |
|
|
|
77 |
|
rg_prof_end("hook-update"); |
|
78 |
|
rg_prof_log("rg_log"); |
135 |
79 |
?> |
?> |
File inc/git.inc.php changed (mode: 100644) (index abaa6aa..a1ddd11) |
... |
... |
function rg_git_set_error($str) |
11 |
11 |
{ |
{ |
12 |
12 |
global $rg_git_error; |
global $rg_git_error; |
13 |
13 |
|
|
14 |
|
rg_log("\tError: $str"); |
|
15 |
14 |
$rg_git_error = $str; |
$rg_git_error = $str; |
16 |
15 |
} |
} |
17 |
16 |
|
|
|
... |
... |
function rg_git_install_hooks($dst) |
50 |
49 |
|
|
51 |
50 |
rg_prof_start("git_install_hooks"); |
rg_prof_start("git_install_hooks"); |
52 |
51 |
|
|
53 |
|
rg_log("git_install_hooks: dst=$dst..."); |
|
|
52 |
|
rg_log("git_install_hooks: dst=$dst"); |
54 |
53 |
|
|
55 |
54 |
if (file_exists($dst . "/hooks")) { |
if (file_exists($dst . "/hooks")) { |
56 |
55 |
//rg_log("hooks folder exists..."); |
//rg_log("hooks folder exists..."); |
|
... |
... |
function rg_git_init($dst) |
84 |
83 |
{ |
{ |
85 |
84 |
rg_prof_start("git_init"); |
rg_prof_start("git_init"); |
86 |
85 |
|
|
87 |
|
rg_log("git_init: dst=$dst..."); |
|
|
86 |
|
rg_log("git_init: dst=$dst"); |
88 |
87 |
|
|
89 |
88 |
$dir = dirname($dst); |
$dir = dirname($dst); |
90 |
89 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
|
... |
... |
function rg_git_init($dst) |
99 |
98 |
$cmd = "git init --bare " . escapeshellarg($dst); |
$cmd = "git init --bare " . escapeshellarg($dst); |
100 |
99 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
101 |
100 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
102 |
|
rg_git_set_error("error on init " . $a['errmsg']); |
|
|
101 |
|
rg_git_set_error("error on init " . $a['errmsg'] . ")"); |
103 |
102 |
return FALSE; |
return FALSE; |
104 |
103 |
} |
} |
105 |
104 |
|
|
|
... |
... |
function rg_git_clone($src, $dst) |
121 |
120 |
{ |
{ |
122 |
121 |
rg_prof_start("git_clone"); |
rg_prof_start("git_clone"); |
123 |
122 |
|
|
124 |
|
rg_log("git_clone: src=$src, dst=$dst..."); |
|
|
123 |
|
rg_log("git_clone: src=$src, dst=$dst"); |
125 |
124 |
|
|
126 |
125 |
$dir = dirname($dst); |
$dir = dirname($dst); |
127 |
126 |
if (!file_exists($dir)) { |
if (!file_exists($dir)) { |
|
... |
... |
function rg_git_clone($src, $dst) |
137 |
136 |
. " " . escapeshellarg($dst); |
. " " . escapeshellarg($dst); |
138 |
137 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
139 |
138 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
140 |
|
rg_git_set_error("error on clone (" . $a['errmsg']); |
|
|
139 |
|
rg_git_set_error("error on clone (" . $a['errmsg'] . ")"); |
141 |
140 |
return FALSE; |
return FALSE; |
142 |
141 |
} |
} |
143 |
142 |
|
|
|
... |
... |
function rg_git_clone($src, $dst) |
160 |
159 |
*/ |
*/ |
161 |
160 |
function rg_git_type($obj) |
function rg_git_type($obj) |
162 |
161 |
{ |
{ |
|
162 |
|
rg_prof_start("git_type"); |
|
163 |
|
|
|
164 |
|
rg_log("git_type: obj=$obj"); |
|
165 |
|
|
163 |
166 |
$cmd = "git cat-file -t '" . $obj . "'"; |
$cmd = "git cat-file -t '" . $obj . "'"; |
164 |
167 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
165 |
168 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
166 |
|
rg_git_set_error("error on cat-file (" . $a['errmsg']); |
|
167 |
|
return FALSE; |
|
|
169 |
|
rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")"); |
|
170 |
|
$ret = FALSE; |
|
171 |
|
} else { |
|
172 |
|
$ret = trim($a['data']); |
168 |
173 |
} |
} |
169 |
174 |
|
|
170 |
|
return trim($a['data']); |
|
|
175 |
|
rg_prof_end("git_type"); |
|
176 |
|
|
|
177 |
|
return $ret; |
171 |
178 |
} |
} |
172 |
179 |
|
|
173 |
180 |
/* |
/* |
|
... |
... |
function rg_git_content($obj) |
177 |
184 |
{ |
{ |
178 |
185 |
rg_prof_start("git_content"); |
rg_prof_start("git_content"); |
179 |
186 |
|
|
|
187 |
|
rg_log("git_content: obj=$obj"); |
|
188 |
|
|
180 |
189 |
$cmd = "git cat-file -p '" . $obj . "'"; |
$cmd = "git cat-file -p '" . $obj . "'"; |
181 |
190 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
182 |
191 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
183 |
|
rg_git_set_error("error on cat-file (" . $a['errmsg']); |
|
184 |
|
return FALSE; |
|
|
192 |
|
rg_git_set_error("error on cat-file (" . $a['errmsg'] . ")"); |
|
193 |
|
$ret = FALSE; |
|
194 |
|
} else { |
|
195 |
|
$ret = $a['data']; |
185 |
196 |
} |
} |
186 |
197 |
|
|
187 |
198 |
rg_prof_end("git_content"); |
rg_prof_end("git_content"); |
188 |
199 |
|
|
189 |
|
return $a['data']; |
|
|
200 |
|
return $ret; |
190 |
201 |
} |
} |
191 |
202 |
|
|
192 |
203 |
/* |
/* |
|
... |
... |
function rg_git_rev_ok($rev) |
214 |
225 |
{ |
{ |
215 |
226 |
rg_prof_start("git_rev_ok"); |
rg_prof_start("git_rev_ok"); |
216 |
227 |
|
|
217 |
|
$cmd = "git rev-parse --verify --quiet '" . $rev . "'"; |
|
|
228 |
|
rg_log("git_rev_ok: rev=$rev"); |
|
229 |
|
|
|
230 |
|
$cmd = "git rev-parse --verify '" . $rev . "'"; |
218 |
231 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
219 |
232 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
220 |
|
rg_git_set_error("error on rev-parse (" . $a['errmsg']); |
|
221 |
|
return FALSE; |
|
|
233 |
|
rg_git_set_error("error on rev-parse (" . $a['errmsg'] . ")"); |
|
234 |
|
$ret = FALSE; |
|
235 |
|
} else { |
|
236 |
|
$ret = TRUE; |
222 |
237 |
} |
} |
223 |
238 |
|
|
224 |
239 |
rg_prof_end("git_rev_ok"); |
rg_prof_end("git_rev_ok"); |
225 |
240 |
|
|
226 |
|
return TRUE; |
|
|
241 |
|
return $ret; |
227 |
242 |
} |
} |
228 |
243 |
|
|
229 |
244 |
/* |
/* |
|
... |
... |
function rg_git_whitespace_ok($old, $new) |
234 |
249 |
{ |
{ |
235 |
250 |
rg_prof_start("git_whitespace_ok"); |
rg_prof_start("git_whitespace_ok"); |
236 |
251 |
|
|
|
252 |
|
rg_log("git_whitespace_ok: old=$old new=$new"); |
|
253 |
|
|
237 |
254 |
$cmd = "git diff --check " . $old . " " . $new; |
$cmd = "git diff --check " . $old . " " . $new; |
238 |
255 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
239 |
256 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
240 |
|
rg_git_set_error("error on diff (" . $a['errmsg']); |
|
241 |
|
return FALSE; |
|
|
257 |
|
rg_git_set_error("error on diff (" . $a['errmsg'] . ")"); |
|
258 |
|
$ret = FALSE; |
|
259 |
|
} else { |
|
260 |
|
$ret = TRUE; |
242 |
261 |
} |
} |
243 |
262 |
|
|
244 |
263 |
rg_prof_end("git_whitespace_ok"); |
rg_prof_end("git_whitespace_ok"); |
245 |
264 |
|
|
246 |
|
return TRUE; |
|
|
265 |
|
return $ret; |
247 |
266 |
} |
} |
248 |
267 |
|
|
249 |
268 |
// TODO: Unit testing |
// TODO: Unit testing |
|
... |
... |
function rg_git_merge_base($old, $new) |
251 |
270 |
{ |
{ |
252 |
271 |
rg_prof_start("git_merge_base"); |
rg_prof_start("git_merge_base"); |
253 |
272 |
|
|
|
273 |
|
rg_log("git_merge_base: old=$old new=$new"); |
|
274 |
|
|
254 |
275 |
$cmd = "git merge-base " . $old . " " . $new; |
$cmd = "git merge-base " . $old . " " . $new; |
255 |
276 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
256 |
277 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
257 |
|
rg_git_set_error("error on merge-base (" . $a['errmsg']); |
|
258 |
|
return FALSE; |
|
|
278 |
|
rg_git_set_error("error on merge-base (" . $a['errmsg'] . ")"); |
|
279 |
|
$ret = FALSE; |
|
280 |
|
} else { |
|
281 |
|
$ret = trim($a['data']); |
259 |
282 |
} |
} |
260 |
283 |
|
|
261 |
284 |
rg_prof_end("git_merge_base"); |
rg_prof_end("git_merge_base"); |
262 |
285 |
|
|
263 |
|
return trim($a['data']); |
|
|
286 |
|
return $ret; |
|
287 |
|
} |
|
288 |
|
|
|
289 |
|
// TODO: Unit testing |
|
290 |
|
/* |
|
291 |
|
* Safely update a reference - used to update main namespace from other namespace |
|
292 |
|
* If @new is empty, we assume a delete |
|
293 |
|
*/ |
|
294 |
|
function rg_git_update_ref($ref, $old, $new, $reason) |
|
295 |
|
{ |
|
296 |
|
rg_prof_start("git_update_ref"); |
|
297 |
|
|
|
298 |
|
rg_log("git_udpate_ref: ref=$ref old=$old new=$new reason=$reason"); |
|
299 |
|
|
|
300 |
|
$cmd = "git update-ref"; |
|
301 |
|
if (!empty($reason)) |
|
302 |
|
$cmd .= " -m " . escapeshellarg($reason); |
|
303 |
|
|
|
304 |
|
if (empty($new)) |
|
305 |
|
$cmd .= " -d " . escapeshellarg($ref); |
|
306 |
|
else |
|
307 |
|
$cmd .= " " . escapeshellarg($ref) . " " . escapeshellarg($new); |
|
308 |
|
|
|
309 |
|
if (!empty($old)) |
|
310 |
|
$cmd .= " " . escapeshellarg($old); |
|
311 |
|
|
|
312 |
|
$a = rg_exec($cmd); |
|
313 |
|
if ($a['ok'] != 1) { |
|
314 |
|
rg_git_set_error("error on update-ref (" . $a['errmsg'] . ")"); |
|
315 |
|
return FALSE; |
|
316 |
|
} |
|
317 |
|
|
|
318 |
|
rg_prof_end("git_update_ref"); |
|
319 |
|
|
|
320 |
|
return TRUE; |
264 |
321 |
} |
} |
265 |
322 |
|
|
266 |
323 |
/* |
/* |
|
... |
... |
function rg_git_ls_tree($tree) |
283 |
340 |
$cmd = "git ls-tree --long" . $op . $tree; |
$cmd = "git ls-tree --long" . $op . $tree; |
284 |
341 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
285 |
342 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
286 |
|
rg_git_set_error("error on ls-tree (" . $a['errmsg']); |
|
|
343 |
|
rg_git_set_error("error on ls-tree (" . $a['errmsg'] . ")"); |
287 |
344 |
return FALSE; |
return FALSE; |
288 |
345 |
} |
} |
289 |
346 |
|
|
|
... |
... |
function rg_git_log($max, $from, $to, $also_patch) |
460 |
517 |
. $from_to; |
. $from_to; |
461 |
518 |
$a = rg_exec($cmd); |
$a = rg_exec($cmd); |
462 |
519 |
if ($a['ok'] != 1) { |
if ($a['ok'] != 1) { |
463 |
|
rg_git_set_error("error on log (" . $a['errmsg']); |
|
|
520 |
|
rg_git_set_error("error on log (" . $a['errmsg'] . ")"); |
464 |
521 |
return FALSE; |
return FALSE; |
465 |
522 |
} |
} |
466 |
523 |
|
|
|
... |
... |
function rg_git_files_stats($a, $dir) |
704 |
761 |
return rg_template_table($dir, $t, $more); |
return rg_template_table($dir, $t, $more); |
705 |
762 |
} |
} |
706 |
763 |
|
|
|
764 |
|
/* |
|
765 |
|
* Helper for 'update' hook - tags (un-annotated or annotated) |
|
766 |
|
*/ |
|
767 |
|
function rg_git_update_tag($a) |
|
768 |
|
{ |
|
769 |
|
global $rg_git_zero; |
|
770 |
|
|
|
771 |
|
rg_log("git_update_tag"); |
|
772 |
|
|
|
773 |
|
if (strcmp($a['new_rev_type'], "commit") == 0) { // Un-annotated |
|
774 |
|
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { // create |
|
775 |
|
if (!rg_rights_allow($a['rights'], "Y")) |
|
776 |
|
rg_git_fatal($a['refname'] . ":\nNo rights to" |
|
777 |
|
. " create an un-annotated tag."); |
|
778 |
|
} else if (strcmp($a['new_rev'], $rg_git_zero) == 0) { // delete |
|
779 |
|
if (!rg_rights_allow($a['rights'], "U")) |
|
780 |
|
rg_git_fatal($a['refname'] . ":\nNo rights to" |
|
781 |
|
. " delete an un-annotated tag."); |
|
782 |
|
} else { // change |
|
783 |
|
if (!rg_rights_allow($a['rights'], "u")) |
|
784 |
|
rg_git_fatal($a['refname'] . ":\nNo rights to" |
|
785 |
|
. " change an un-annotated tag."); |
|
786 |
|
} |
|
787 |
|
} else if (strcmp($a['new_rev_type'], "tag") == 0) { // Annotated |
|
788 |
|
// TODO: Only change we can have here? |
|
789 |
|
if (!rg_rights_allow($a['rights'], "S")) |
|
790 |
|
rg_git_fatal($a['refname'] . ":\nNo rights to change an" |
|
791 |
|
. " annotated tag."); |
|
792 |
|
} else { |
|
793 |
|
rg_git_fatal("Strange tag!"); |
|
794 |
|
} |
|
795 |
|
} |
|
796 |
|
|
|
797 |
|
function rg_git_update_branch($a) |
|
798 |
|
{ |
|
799 |
|
global $rg_git_zero; |
|
800 |
|
|
|
801 |
|
rg_log("git_update_branch"); |
|
802 |
|
|
|
803 |
|
if (strcmp($a['new_rev'], $rg_git_zero) == 0) { // delete |
|
804 |
|
if (!rg_rights_allow($a['rights'], "D")) |
|
805 |
|
rg_git_fatal($a['refname'] . ":\nNo rights to delete" |
|
806 |
|
. " a branch."); |
|
807 |
|
return; |
|
808 |
|
} |
|
809 |
|
|
|
810 |
|
$check_fast_forward = 1; |
|
811 |
|
if (strcmp($a['old_rev'], $rg_git_zero) == 0) { // create |
|
812 |
|
if (!rg_rights_allow($a['rights'], "C")) |
|
813 |
|
rg_git_fatal($a['refname'] . ":\nYou have no rights" |
|
814 |
|
. " to create a branch."); |
|
815 |
|
$check_fast_forward = 0; |
|
816 |
|
} |
|
817 |
|
|
|
818 |
|
// Create or change |
|
819 |
|
// Check for non fast-forward update |
|
820 |
|
if (!rg_rights_allow($a['rights'], "O") && ($check_fast_forward == 1)) { |
|
821 |
|
$merge_base = rg_git_merge_base($a['old_rev'], $a['new_rev']); |
|
822 |
|
if ($merge_base === FALSE) { |
|
823 |
|
rg_log("Error in merge_base: " . rg_git_error()); |
|
824 |
|
rg_git_fatal($a['refname'] . ":\nInternal error." |
|
825 |
|
. " Please try again later."); |
|
826 |
|
} |
|
827 |
|
|
|
828 |
|
if (strcmp($a['merge_base'], $a['old_rev']) != 0) |
|
829 |
|
rg_git_fatal($a['refname'] . ":\nNon fast-forward is" |
|
830 |
|
. " not allowed."); |
|
831 |
|
} |
|
832 |
|
|
|
833 |
|
if (rg_rights_allow($a['rights'], "P") !== TRUE) { |
|
834 |
|
if (rg_rights_allow($a['rights'], "H") === FALSE) { |
|
835 |
|
$msg = rg_template("msg/push_not_allowed.txt", array()); |
|
836 |
|
rg_git_fatal($a['refname']. ":\n" . $msg); |
|
837 |
|
} |
|
838 |
|
|
|
839 |
|
// anonymous push - create a merge request |
|
840 |
|
$r = rg_mr_queue_add($a['repo_id'], $a['namespace'], |
|
841 |
|
$a['old_rev'], $a['new_rev'], $a['refname'], $a['ip']); |
|
842 |
|
if ($r !== TRUE) |
|
843 |
|
rg_git_fatal($a['refname'] . ": " . rg_mr_error()); |
|
844 |
|
$msg = rg_template("msg/push_merge_request.txt", array()); |
|
845 |
|
rg_git_info($a['refname'] . ":\n" . $msg); |
|
846 |
|
} else { |
|
847 |
|
rg_log("We are allowed to push."); |
|
848 |
|
$r = rg_git_update_ref($a['refname'], $a['old_rev'], |
|
849 |
|
$a['new_rev'], "reason"); |
|
850 |
|
if ($r !== TRUE) { |
|
851 |
|
rg_log("update_ref: " . rg_git_error()); |
|
852 |
|
rg_git_fatal($a['refname'] . ":\nCannot update ref (" |
|
853 |
|
. rg_git_error() . ")"); |
|
854 |
|
} |
|
855 |
|
|
|
856 |
|
// We can clean now the namespace - TODO |
|
857 |
|
} |
|
858 |
|
} |
|
859 |
|
|
707 |
860 |
?> |
?> |
File inc/mr.inc.php changed (mode: 100644) (index 5a49140..780f93f) |
... |
... |
function rg_mr_set_error($str) |
12 |
12 |
{ |
{ |
13 |
13 |
global $rg_mr_error; |
global $rg_mr_error; |
14 |
14 |
|
|
15 |
|
rg_log("\tError: $str"); |
|
16 |
15 |
$rg_mr_error = $str; |
$rg_mr_error = $str; |
17 |
16 |
} |
} |
18 |
17 |
|
|
|
... |
... |
function rg_mr_error() |
28 |
27 |
*/ |
*/ |
29 |
28 |
function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip) |
function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip) |
30 |
29 |
{ |
{ |
|
30 |
|
global $php_errormsg; |
31 |
31 |
global $rg_mr_queue; |
global $rg_mr_queue; |
32 |
32 |
|
|
33 |
33 |
rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace" |
rg_log("rg_mr_create: repo_id=$repo_id namespace=$namespace" |
|
... |
... |
function rg_mr_queue_add($repo_id, $namespace, $old_rev, $new_rev, $refname, $ip |
41 |
41 |
|
|
42 |
42 |
if (!file_exists($rg_mr_queue)) { |
if (!file_exists($rg_mr_queue)) { |
43 |
43 |
if (@mkdir($rg_mr_queue, 0700) === FALSE) { |
if (@mkdir($rg_mr_queue, 0700) === FALSE) { |
44 |
|
rg_mr_set_error("cannot create merge requests queue"); |
|
|
44 |
|
rg_mr_set_error("cannot create merge requests queue ($php_errormsg)"); |
45 |
45 |
return FALSE; |
return FALSE; |
46 |
46 |
} |
} |
47 |
47 |
} |
} |
48 |
48 |
|
|
49 |
49 |
if (@file_put_contents($rg_mr_queue . "/" . $f, $c) === FALSE) { |
if (@file_put_contents($rg_mr_queue . "/" . $f, $c) === FALSE) { |
50 |
|
rg_mr_set_error("internal error: cannot store merge request ($php_errormsg)"); |
|
|
50 |
|
rg_mr_set_error("cannot store merge request ($php_errormsg)"); |
51 |
51 |
return FALSE; |
return FALSE; |
52 |
52 |
} |
} |
53 |
53 |
|
|
|
... |
... |
function rg_mr_create($db, $repo_id, $namespace, $old_rev, $new_rev, $refname, $ |
72 |
72 |
. ", '$refname', '$old_rev', '$new_rev', 0, '$ip')"; |
. ", '$refname', '$old_rev', '$new_rev', 0, '$ip')"; |
73 |
73 |
$res = rg_sql_query($db, $sql); |
$res = rg_sql_query($db, $sql); |
74 |
74 |
if ($res === FALSE) { |
if ($res === FALSE) { |
75 |
|
rg_mr_set_error("Cannot insert merge request (" . rg_sql_error() . ")"); |
|
|
75 |
|
rg_mr_set_error("cannot insert merge request (" . rg_sql_error() . ")"); |
76 |
76 |
return FALSE; |
return FALSE; |
77 |
77 |
} |
} |
78 |
78 |
|
|
|
... |
... |
function rg_mr_create($db, $repo_id, $namespace, $old_rev, $new_rev, $refname, $ |
86 |
86 |
*/ |
*/ |
87 |
87 |
function rg_mr_queue_load_file($file) |
function rg_mr_queue_load_file($file) |
88 |
88 |
{ |
{ |
|
89 |
|
global $php_errormsg; |
|
90 |
|
|
89 |
91 |
$ret = array(); |
$ret = array(); |
90 |
92 |
$ret['ok'] = 0; |
$ret['ok'] = 0; |
91 |
93 |
|
|
|
... |
... |
function rg_mr_queue_load_file($file) |
110 |
112 |
*/ |
*/ |
111 |
113 |
function rg_mr_queue_process($db) |
function rg_mr_queue_process($db) |
112 |
114 |
{ |
{ |
|
115 |
|
global $php_errormsg; |
113 |
116 |
global $rg_mr_queue; |
global $rg_mr_queue; |
114 |
117 |
|
|
115 |
118 |
rg_log("mr_queue_process..."); |
rg_log("mr_queue_process..."); |
File scripts/remote.php changed (mode: 100644) (index 677badb..17e5ed4) |
3 |
3 |
error_reporting(E_ALL); |
error_reporting(E_ALL); |
4 |
4 |
ini_set("track_errors", "On"); |
ini_set("track_errors", "On"); |
5 |
5 |
|
|
6 |
|
$_start = microtime(TRUE); |
|
7 |
|
|
|
8 |
6 |
require_once("/etc/rocketgit/config.php"); |
require_once("/etc/rocketgit/config.php"); |
9 |
7 |
|
|
10 |
8 |
$INC = dirname(__FILE__) . "/../inc"; |
$INC = dirname(__FILE__) . "/../inc"; |
|
... |
... |
require_once($INC . "/util.inc.php"); |
12 |
10 |
require_once($INC . "/log.inc.php"); |
require_once($INC . "/log.inc.php"); |
13 |
11 |
require_once($INC . "/sql.inc.php"); |
require_once($INC . "/sql.inc.php"); |
14 |
12 |
require_once($INC . "/repo.inc.php"); |
require_once($INC . "/repo.inc.php"); |
|
13 |
|
require_once($INC . "/prof.inc.php"); |
|
14 |
|
|
|
15 |
|
rg_prof_start("remote.php"); |
15 |
16 |
|
|
16 |
17 |
rg_log_set_file($rg_log_dir . "/remote.log"); |
rg_log_set_file($rg_log_dir . "/remote.log"); |
17 |
18 |
|
|
18 |
19 |
function fatal($str) |
function fatal($str) |
19 |
20 |
{ |
{ |
|
21 |
|
global $php_errormsg; |
20 |
22 |
global $access_type; |
global $access_type; |
21 |
23 |
|
|
22 |
24 |
rg_log("Sending error: " . $str); |
rg_log("Sending error: " . $str); |
|
25 |
|
rg_log("php_errormsg: " . $php_errormsg); |
23 |
26 |
$str2 = "RocketGit: FATAL ERROR: " . $str . "\n"; |
$str2 = "RocketGit: FATAL ERROR: " . $str . "\n"; |
24 |
27 |
if ($access_type == 2) { // git |
if ($access_type == 2) { // git |
25 |
28 |
$str3 = "\n" . $str2; |
$str3 = "\n" . $str2; |
|
... |
... |
if (($push == 1) && rg_repo_over_limit($ri)) |
169 |
172 |
putenv("ROCKETGIT_UID=" . $uid); |
putenv("ROCKETGIT_UID=" . $uid); |
170 |
173 |
putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); |
putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); |
171 |
174 |
putenv("ROCKETGIT_REPO_RIGHTS=" . $rights); |
putenv("ROCKETGIT_REPO_RIGHTS=" . $rights); |
|
175 |
|
putenv("ROCKETGIT_REPO_PATH=" . $repo_path); |
172 |
176 |
putenv("ROCKETGIT_IP=$ip"); |
putenv("ROCKETGIT_IP=$ip"); |
173 |
177 |
if ($push == 1) { |
if ($push == 1) { |
174 |
178 |
$namespace = "rg_" . rg_id(8); |
$namespace = "rg_" . rg_id(8); |
175 |
179 |
rg_log("namespace is $namespace."); |
rg_log("namespace is $namespace."); |
176 |
180 |
putenv("GIT_NAMESPACE=" . $namespace); |
putenv("GIT_NAMESPACE=" . $namespace); |
|
181 |
|
|
|
182 |
|
// Prepare refs to not receive: |
|
183 |
|
// "No refs in common and none specified; doing nothing. |
|
184 |
|
// Perhaps you should specify a branch such as 'master'. |
|
185 |
|
// No refs in common and none specified; doing nothing. |
|
186 |
|
// Perhaps you should specify a branch such as 'master'. |
|
187 |
|
$dst = $repo_path . "/refs/namespaces/" . $namespace . "/refs/heads"; |
|
188 |
|
$ret = @mkdir($dst, 0755, TRUE); |
|
189 |
|
if ($ret === FALSE) |
|
190 |
|
fatal("Internal error (namespace dir)"); |
|
191 |
|
// copy refs |
|
192 |
|
$dir = scandir($repo_path . "/refs/heads"); |
|
193 |
|
foreach ($dir as $file) { |
|
194 |
|
if ((strcmp($file, ".") == 0) || (strcmp($file, "..") == 0)) |
|
195 |
|
continue; |
|
196 |
|
|
|
197 |
|
rg_log("Copy ref '$file'..."); |
|
198 |
|
if (@copy($repo_path . "/refs/heads/" . $file, $dst . "/" . $file) === FALSE) |
|
199 |
|
fatal("Internal error (cannot copy refs)"); |
|
200 |
|
} |
177 |
201 |
} |
} |
178 |
202 |
|
|
179 |
203 |
$run = "git-shell -c \"" . $cmd . " " . escapeshellarg($repo_path) . "\""; |
$run = "git-shell -c \"" . $cmd . " " . escapeshellarg($repo_path) . "\""; |
|
... |
... |
rg_log("Running [$run]..."); |
181 |
205 |
passthru($run, $ret); |
passthru($run, $ret); |
182 |
206 |
rg_log("[$run] returned $ret."); |
rg_log("[$run] returned $ret."); |
183 |
207 |
|
|
184 |
|
$diff = sprintf("%u", (microtime(TRUE) - $_start) * 1000); |
|
185 |
|
rg_log("Took " . $diff . "ms."); |
|
|
208 |
|
rg_prof_end("remote.php"); |
|
209 |
|
rg_prof_log("rg_log"); |
186 |
210 |
?> |
?> |
File tests/hook_update_anon.sh renamed from tests/hook_pre-receive.sh (similarity 52%) (mode: 100755) (index fee6ab6..77528cd) |
1 |
1 |
#!/bin/bash |
#!/bin/bash |
2 |
2 |
|
|
3 |
|
rm -rfv hook_pre-receive_*.git |
|
4 |
|
mkdir hook_pre-receive_dest.git |
|
|
3 |
|
# Test anonymous push |
|
4 |
|
|
|
5 |
|
rm -rf hook_update_anon_*.git |
|
6 |
|
mkdir hook_update_anon_dest.git |
5 |
7 |
( |
( |
6 |
|
cd hook_pre-receive_dest.git |
|
|
8 |
|
cd hook_update_anon_dest.git |
7 |
9 |
git init --bare |
git init --bare |
8 |
10 |
) |
) |
9 |
|
cp ../hooks/* hook_pre-receive_dest.git/hooks/ |
|
|
11 |
|
cp ../hooks/* hook_update_anon_dest.git/hooks/ |
10 |
12 |
|
|
11 |
|
git clone hook_pre-receive_dest.git hook_pre-receive_src.git |
|
|
13 |
|
git clone hook_update_anon_dest.git hook_update_anon_src.git |
12 |
14 |
|
|
13 |
|
cd hook_pre-receive_src.git |
|
|
15 |
|
cd hook_update_anon_src.git |
14 |
16 |
|
|
15 |
17 |
export ROCKETGIT_REPO_ID=2000000000 |
export ROCKETGIT_REPO_ID=2000000000 |
16 |
18 |
export ROCKETGIT_IP="IP" |
export ROCKETGIT_IP="IP" |
17 |
|
|
|
18 |
|
echo "=== Testing push without rights..." |
|
19 |
|
echo "aaa" > a |
|
20 |
|
git add a |
|
21 |
|
git commit -m "a" a |
|
22 |
|
git push origin master |
|
23 |
|
if [ "${?}" != "1" ]; then |
|
24 |
|
echo "Should not work!" |
|
25 |
|
exit 1 |
|
26 |
|
fi |
|
27 |
|
echo "=== Testing push with rights..." |
|
28 |
|
export ROCKETGIT_REPO_RIGHTS="CP" |
|
29 |
|
git push origin master |
|
30 |
|
if [ "${?}" != "0" ]; then |
|
31 |
|
echo "Should work!" |
|
32 |
|
exit 1 |
|
33 |
|
fi |
|
|
19 |
|
export GIT_NAMESPACE="abcdefgh" # we have to set it manually |
34 |
20 |
|
|
35 |
21 |
echo "=== Testing anon push without rights..." |
echo "=== Testing anon push without rights..." |
36 |
22 |
export ROCKETGIT_REPO_RIGHTS="C" |
export ROCKETGIT_REPO_RIGHTS="C" |
|
... |
... |
if [ "${?}" = "0" ]; then |
43 |
29 |
exit 1 |
exit 1 |
44 |
30 |
fi |
fi |
45 |
31 |
|
|
|
32 |
|
set -e |
46 |
33 |
echo "=== Testing anon push with rights..." |
echo "=== Testing anon push with rights..." |
47 |
34 |
export ROCKETGIT_REPO_RIGHTS="CH" |
export ROCKETGIT_REPO_RIGHTS="CH" |
48 |
|
export GIT_NAMESPACE="abcdefgh" # we have to set it manually |
|
49 |
35 |
git push origin master |
git push origin master |
50 |
36 |
if [ "${?}" != "0" ]; then |
if [ "${?}" != "0" ]; then |
51 |
37 |
echo "Should work!" |
echo "Should work!" |
52 |
38 |
exit 1 |
exit 1 |
53 |
39 |
fi |
fi |
|
40 |
|
# Test if the namespace was updated instead of main namespace |
|
41 |
|
diff ../hook_update_anon_dest.git/refs/namespaces/${GIT_NAMESPACE}/refs/heads/master \ |
|
42 |
|
.git/refs/heads/master |
|
43 |
|
if [ "${?}" != "0" ]; then |
|
44 |
|
echo "We did not update the namespace!" |
|
45 |
|
exit 1 |
|
46 |
|
fi |
|
47 |
|
|
54 |
48 |
# TODO: we should not allow force pushes on anon branches |
# TODO: we should not allow force pushes on anon branches |
55 |
49 |
|
|
56 |
50 |
cd .. |
cd .. |
57 |
51 |
|
|
58 |
|
rm -rf hook_pre-receive_*.git |
|
|
52 |
|
rm -rf hook_update_anon_*.git |
59 |
53 |
|
|
60 |
|
echo "hook_pre-receive: OK!" |
|
|
54 |
|
echo "hook_update_anon: OK!" |