List of commits:
Subject Hash Author Date (UTC)
Simplify event processing by passing full 'ui'; fixed 'confirmed' filed usage cbb6f8877db547d55b7b86e0fe5c41519d6c8b65 Catalin(ux) M. BOIE 2016-07-14 05:08:51
Fixed the unit tests (minor) 0e9cfc3911aba7119bb57140ecfa51ad6e3983bf Catalin(ux) M. BOIE 2016-07-14 05:05:37
Fixed e-mail confirmation logic. dd5b4be2e8e49aa612ddf7557e8ef0b1e0268822 Catalin(ux) M. BOIE 2016-07-11 21:09:19
Do more tests and resync some with the reality db9bb136ff176006cbb8f8848309b8adbf98d630 Catalin(ux) M. BOIE 2016-07-11 04:07:38
Improved user cache to not have null elements in JSON d6b75a2cc4830cfb8dfb92e911f1e5a41c2023bc Catalin(ux) M. BOIE 2016-07-11 04:06:25
Allow rights to have numbers and _ in name 4f5c38389bc98e2dcb60d36359917c33820e5779 Catalin(ux) M. BOIE 2016-07-11 04:05:40
Allow strange chars in cache names 00b05d99d3d3cf0229249718d2482af40f063972 Catalin(ux) M. BOIE 2016-07-11 04:04:08
Small improvements to builder and worker 08f9bc668f7f192af61868bebd644bea64b6aedd Catalin(ux) M. BOIE 2016-07-11 04:01:47
SELinux improvements to support the builder a2b52360b43be53786ee5d68c9fcb2db14f29c0c Catalin(ux) M. BOIE 2016-07-11 04:00:57
Document docker on Download web section 5d4ece50d6b4dc3d4902afd9264a45834ceb3592 Catalin(ux) M. BOIE 2016-07-11 03:54:31
Doc: restore context for rc.local eb5fa1cab84737e3440cfbca147d50859b8f9a53 Catalin(ux) M. BOIE 2016-07-07 04:09:23
Fixed small bug preventing e-mail to show in report 26d884b3a332f3c3b241c194912b9653749a9427 Catalin(ux) M. BOIE 2016-07-07 03:37:23
Do not clobber the cron file 5c68384676d9b8087255dda3b62e3588fc50e6c7 Catalin(ux) M. BOIE 2016-07-06 22:03:58
When using rg_json_encode, no quotes needed. c4b7693a81e593918f8c06408f16b4884a92773b Catalin(ux) M. BOIE 2016-07-06 05:21:00
Remove summary from tables because violates HTML5 specs. :( 11865f18e979f3849dbb265e5c5350f4a638088b Catalin(ux) M. BOIE 2016-07-06 05:00:11
Bump version to 0.55 58652b8250a867c0f4e9e3a9c76737443f242b36 Catalin(ux) M. BOIE 2016-07-06 04:48:24
Big commit of a lot of unrelated changes. Shame on me! e503666df79ef1553d0bb7ffd1d12a6b62748b1c Catalin(ux) M. BOIE 2016-07-06 04:44:43
Do not free resources if query fails. 57baca81e9087a00a8e2e1807c932de2fb9769c4 Catalin(ux) M. BOIE 2016-06-26 11:47:09
Packaging changes: prepared for Debian build c32cb09dc84615f4984ce5f8fac4064accbeeb28 Catalin(ux) M. BOIE 2016-06-12 05:59:14
webhooks - rename Name to Type 7d774d4818950b3d3916e834b0dde3081b90960e Catalin(ux) M. BOIE 2016-05-08 11:36:45
Commit cbb6f8877db547d55b7b86e0fe5c41519d6c8b65 - Simplify event processing by passing full 'ui'; fixed 'confirmed' filed usage
Author: Catalin(ux) M. BOIE
Author date (UTC): 2016-07-14 05:08
Committer name: Catalin(ux) M. BOIE
Committer date (UTC): 2016-07-14 05:08
Parent(s): 0e9cfc3911aba7119bb57140ecfa51ad6e3983bf
Signing key:
Tree: 6044673b63959b215c57771ac561a281a82ac113
File Lines added Lines deleted
hooks/update 15 2
inc/admin.inc.php 3 2
inc/apikeys.inc.php 12 11
inc/bug.inc.php 27 40
inc/events.inc.php 2 1
inc/git.inc.php 5 11
inc/keys.inc.php 9 11
inc/mail.inc.php 60 46
inc/mr.inc.php 4 4
inc/repo.inc.php 8 9
inc/user.inc.php 50 26
inc/user/home-page.php 1 1
inc/user/repo-page.php 1 3
root/themes/default/doc/api.html 1 1
scripts/remote.php 0 2
File hooks/update changed (mode: 100755) (index 072d11c..ee8f6d9)
... ... require_once($INC . "/init.inc.php");
24 24 require_once($INC . "/util.inc.php"); require_once($INC . "/util.inc.php");
25 25 require_once($INC . "/log.inc.php"); require_once($INC . "/log.inc.php");
26 26 require_once($INC . "/sql.inc.php"); require_once($INC . "/sql.inc.php");
27 require_once($INC . "/user.inc.php");
27 28 require_once($INC . "/repo.inc.php"); require_once($INC . "/repo.inc.php");
28 29 require_once($INC . "/prof.inc.php"); require_once($INC . "/prof.inc.php");
29 30 require_once($INC . "/mr.inc.php"); require_once($INC . "/mr.inc.php");
 
... ... rg_sql_app("rg-hook-update");
36 37 $db = rg_sql_open($rg_sql); $db = rg_sql_open($rg_sql);
37 38
38 39 $a = $rg; $a = $rg;
39 $a['login_organization'] = getenv('ROCKETGIT_LOGIN_ORGANIZATION');
40 40 $a['login_uid'] = sprintf("%u", getenv("ROCKETGIT_LOGIN_UID")); $a['login_uid'] = sprintf("%u", getenv("ROCKETGIT_LOGIN_UID"));
41 $a['login_username'] = getenv("ROCKETGIT_LOGIN_USERNAME");
42 41 $a['login_url'] = getenv('ROCKETGIT_LOGIN_URL'); $a['login_url'] = getenv('ROCKETGIT_LOGIN_URL');
43 42 $a['repo_id'] = sprintf("%u", getenv("ROCKETGIT_REPO_ID")); $a['repo_id'] = sprintf("%u", getenv("ROCKETGIT_REPO_ID"));
44 43 $a['ip'] = getenv("ROCKETGIT_IP"); $a['ip'] = getenv("ROCKETGIT_IP");
 
... ... $a['repo_clone_url'] = getenv('ROCKETGIT_REPO_CLONE_URL');
51 50 rg_log("Start a=" . rg_array2string($a)); rg_log("Start a=" . rg_array2string($a));
52 51 rg_log("_SERVER: " . rg_array2string($_SERVER)); rg_log("_SERVER: " . rg_array2string($_SERVER));
53 52
53 if ($a['login_uid'] > 0) {
54 $a['ui'] = rg_user_info($db, $a['login_uid'], '', '');
55 if ($a['ui']['ok'] != 1)
56 rg_git_fatal('internal error');
57 if ($a['ui']['exists'] != 1)
58 rg_git_fatal('user does not exists');
59 } else {
60 $a['ui'] = array(
61 'uid' => 0,
62 'username' => 'anonymous user',
63 'organization' => 0
64 );
65 }
66
54 67 umask(0022); umask(0022);
55 68
56 69
File inc/admin.inc.php changed (mode: 100644) (index 46212d5..2f21b5d)
... ... function rg_admin_invites_high_level($db, $rg)
161 161 $event = array( $event = array(
162 162 'category' => 6000, 'category' => 6000,
163 163 'prio' => 50, 'prio' => 50,
164 'ui' => array('uid' => $rg['login_ui']['uid']));
164 'ui' => $rg['login_ui']);
165 165 $event = array_merge($event, $inv); $event = array_merge($event, $inv);
166 166 $event['list'] = $list; $event['list'] = $list;
167 167 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
 
... ... function rg_init($db, $rg)
222 222 $rg['init']['pass'] = rg_var_str('init::pass'); $rg['init']['pass'] = rg_var_str('init::pass');
223 223 $rg['init']['pass2'] = rg_var_str('init::pass2'); $rg['init']['pass2'] = rg_var_str('init::pass2');
224 224 $rg['init']['session_time'] = rg_var_uint('init::session_time'); $rg['init']['session_time'] = rg_var_uint('init::session_time');
225 $rg['init']['confirmed'] = 1; /* = no need to confirm */
225 $rg['init']['confirmed'] = time(); /* = no need to confirm */
226 226 $rg['init']['ask_for_email_confirmation'] = 0; $rg['init']['ask_for_email_confirmation'] = 0;
227 227
228 228 if (!rg_valid_referer()) { if (!rg_valid_referer()) {
 
... ... function rg_admin_report1($db, $rg)
427 427 $sug = rg_admin_report1_suggestions($db, $y_start, $y_end); $sug = rg_admin_report1_suggestions($db, $y_start, $y_end);
428 428 $body .= "\n" . $sug; $body .= "\n" . $sug;
429 429
430 $rg['ui']['ignore_confirmed'] = 1;
430 431 $rg['ui']['email'] = $rg_admin_email; $rg['ui']['email'] = $rg_admin_email;
431 432 $rg['mail'] = array(); $rg['mail'] = array();
432 433 $rg['mail']['subject'] = 'RocketGit report' $rg['mail']['subject'] = 'RocketGit report'
File inc/apikeys.inc.php changed (mode: 100644) (index 49f213a..c0b0038)
... ... function rg_ak_event_notify_user($db, $event)
87 87 /* /*
88 88 * Remove api keys from database for user 'ui' * Remove api keys from database for user 'ui'
89 89 */ */
90 function rg_ak_remove($db, $uid, $list)
90 function rg_ak_remove($db, $ui, $list)
91 91 { {
92 92 rg_prof_start('ak_remove'); rg_prof_start('ak_remove');
93 93 rg_log_enter('ak_remove: list=' . rg_array2string($list)); rg_log_enter('ak_remove: list=' . rg_array2string($list));
 
... ... function rg_ak_remove($db, $uid, $list)
98 98 foreach ($list as $key_id => $junk) foreach ($list as $key_id => $junk)
99 99 $my_list[] = sprintf('%u', $key_id); $my_list[] = sprintf('%u', $key_id);
100 100
101 $params = array('uid' => $uid);
101 $params = array('uid' => $ui['uid']);
102 102 $sql_list = implode(', ', $my_list); $sql_list = implode(', ', $my_list);
103 103 $sql = 'DELETE FROM apikeys' $sql = 'DELETE FROM apikeys'
104 104 . ' WHERE uid = @@uid@@' . ' WHERE uid = @@uid@@'
 
... ... function rg_ak_remove($db, $uid, $list)
111 111 rg_sql_free_result($res); rg_sql_free_result($res);
112 112
113 113 $event = array( $event = array(
114 'category' => 'rg_ak_event_del',
114 'category' => 'ak_event_del',
115 115 'prio' => 50, 'prio' => 50,
116 'ui' => array('uid' => $uid),
116 'ui' => $ui,
117 117 'keys' => implode(',', $my_list)); 'keys' => implode(',', $my_list));
118 118 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
119 119 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_ak_remove($db, $uid, $list)
122 122 break; break;
123 123 } }
124 124
125 $key = 'user' . '::' . $uid . '::' . 'apikeys' . '::' . 'list';
125 $key = 'user' . '::' . $ui['uid'] . '::' . 'apikeys'
126 . '::' . 'list';
126 127 foreach ($my_list as $_key_id) foreach ($my_list as $_key_id)
127 128 rg_cache_unset($key . '::' . $_key_id, rg_cache_unset($key . '::' . $_key_id,
128 129 RG_SOCKET_NO_WAIT); RG_SOCKET_NO_WAIT);
 
... ... function rg_ak_remove($db, $uid, $list)
141 142 * Adds an apikey * Adds an apikey
142 143 * Returns the key_id of the key. * Returns the key_id of the key.
143 144 */ */
144 function rg_ak_add($db, $uid, $key, $name)
145 function rg_ak_add($db, $ui, $key, $name)
145 146 { {
146 147 rg_prof_start('ak_add'); rg_prof_start('ak_add');
147 148 rg_log_enter('ak_add: key=' . $key . ' name=' . $name); rg_log_enter('ak_add: key=' . $key . ' name=' . $name);
 
... ... function rg_ak_add($db, $uid, $key, $name)
160 161
161 162 $params = array( $params = array(
162 163 'itime' => $itime, 'itime' => $itime,
163 'uid' => $uid,
164 'uid' => $ui['uid'],
164 165 'key' => $key, 'key' => $key,
165 166 'name' => $name, 'name' => $name,
166 167 'count' => 0, 'count' => 0,
 
... ... function rg_ak_add($db, $uid, $key, $name)
180 181 $event = array( $event = array(
181 182 'category' => 'ak_event_new', 'category' => 'ak_event_new',
182 183 'prio' => 50, 'prio' => 50,
183 'ui' => array('uid' => $uid),
184 'ui' => $ui,
184 185 'key' => $key, 'key' => $key,
185 186 'name' => $name, 'name' => $name,
186 187 'key_id' => $key_id); 'key_id' => $key_id);
 
... ... function rg_ak_add($db, $uid, $key, $name)
198 199 } }
199 200 $do_rollback = 0; $do_rollback = 0;
200 201
201 $_key = 'user' . '::' . $uid . '::'
202 $_key = 'user' . '::' . $ui['uid'] . '::'
202 203 . 'apikeys' . '::' . 'list' . '::' . $key_id; . 'apikeys' . '::' . 'list' . '::' . $key_id;
203 204 rg_cache_merge($_key, $params, RG_SOCKET_NO_WAIT); rg_cache_merge($_key, $params, RG_SOCKET_NO_WAIT);
204 205
 
... ... function rg_ak_list_high_level($db, $rg, $paras)
451 452 } }
452 453
453 454 $list = rg_var_str('key_delete_ids'); $list = rg_var_str('key_delete_ids');
454 $r = rg_ak_remove($db, $rg['login_ui']['uid'], $list);
455 $r = rg_ak_remove($db, $rg['login_ui'], $list);
455 456 if ($r !== TRUE) { if ($r !== TRUE) {
456 457 $errmsg[] = 'cannot delete: ' . rg_ak_error(); $errmsg[] = 'cannot delete: ' . rg_ak_error();
457 458 break; break;
 
... ... function rg_ak_add_high_level($db, $rg, $paras)
515 516 break; break;
516 517 } }
517 518
518 $r = rg_ak_add($db, $rg['login_ui']['uid'], $rg['ak']['key'],
519 $r = rg_ak_add($db, $rg['login_ui'], $rg['ak']['key'],
519 520 $rg['ak']['name']); $rg['ak']['name']);
520 521 if ($r === FALSE) { if ($r === FALSE) {
521 522 $errmsg[] = rg_ak_error(); $errmsg[] = rg_ak_error();
File inc/bug.inc.php changed (mode: 100644) (index e8ac155..34af410)
... ... function rg_bug_event_add_one($db, $event)
51 51
52 52 $ret = FALSE; $ret = FALSE;
53 53 while (1) { while (1) {
54 // lookup user email
55 $ui = rg_user_info($db, $event['ui']['uid'], '', '');
56 if ($ui['exists'] != 1)
57 break;
58 // TODO: maybe test for deleted?
59
60 // If user is not confirmed, do not send mail
61 if ($ui['confirmed'] == 0) {
62 $ret = array();
63 break;
64 }
65
66 // send e-mail
67 $event['ui']['email'] = $ui['email'];
68 $r = rg_mail_template("mail/user/repo/bug/new", $event);
54 $r = rg_mail_template('mail/user/repo/bug/new', $event);
69 55 if ($r === FALSE) if ($r === FALSE)
70 56 break; break;
71 57
 
... ... function rg_bug_event_add_all($db, $event)
95 81 $r = rg_watch_load_by_obj_id($db, "repo", $event['ri']['repo_id'], 0); $r = rg_watch_load_by_obj_id($db, "repo", $event['ri']['repo_id'], 0);
96 82 if ($r === FALSE) if ($r === FALSE)
97 83 return FALSE; return FALSE;
98 if (!empty($r)) {
99 foreach ($r as $index => $uid) {
100 $x['ui']['uid'] = $uid;
101 $ret[$uid] = $x;
102 }
84 $full = rg_user_list_to_full_info($db, $r);
85 if ($full === FALSE)
86 return FALSE;
87 foreach ($full as $uid => $ui) {
88 $x['ui'] = $ui;
89 $ret[$uid] = $x;
103 90 } }
104 91
105 92 // We will sent notifications to all watchers of a bug // We will sent notifications to all watchers of a bug
 
... ... function rg_bug_event_add_all($db, $event)
107 94 $event['bug']['bug_id']); $event['bug']['bug_id']);
108 95 if ($r === FALSE) if ($r === FALSE)
109 96 return FALSE; return FALSE;
110 if (!empty($r)) {
111 foreach ($r as $index => $uid) {
112 $x['ui']['uid'] = $uid;
113 $ret[$uid] = $x;
114 }
97 $full = rg_user_list_to_full_info($db, $r);
98 if ($full === FALSE)
99 return FALSE;
100 foreach ($full as $uid => $ui) {
101 $x['ui'] = $ui;
102 $ret[$uid] = $x;
115 103 } }
116 104
117 105 rg_prof_end("bug_event_add"); rg_prof_end("bug_event_add");
 
... ... function rg_bug_event_note_add_one($db, $event)
134 122 break; break;
135 123 } }
136 124
137 if ($ui['confirmed'] == 0) {
138 $ret = array();
139 break;
140 }
141
142 // send e-mail
143 125 $event['ui']['email'] = $ui['email']; $event['ui']['email'] = $ui['email'];
144 126 $r = rg_mail_template("mail/user/repo/bug/new_note", $event); $r = rg_mail_template("mail/user/repo/bug/new_note", $event);
145 127 if ($r === FALSE) if ($r === FALSE)
 
... ... function rg_bug_event_note_add_all($db, $event)
171 153 $event['bug']['bug_id']); $event['bug']['bug_id']);
172 154 if ($r === FALSE) if ($r === FALSE)
173 155 return FALSE; return FALSE;
174 if (!empty($r)) {
175 foreach ($r as $index => $uid) {
176 $x['ui']['uid'] = $uid;
177 $ret[] = $x;
178 }
156 $full = rg_user_list_to_full_info($db, $r);
157 if ($full === FALSE)
158 return FALSE;
159 foreach ($full as $uid => $ui) {
160 $x['ui'] = $ui;
161 $ret[] = $x;
179 162 } }
180 163
181 164 rg_log_ml("DEBUG: ret: " . print_r($ret, TRUE)); rg_log_ml("DEBUG: ret: " . print_r($ret, TRUE));
 
... ... function rg_bug_edit($db, $login_ui, $ri, $data)
469 452 } }
470 453
471 454 // TODO: seems I do not distinguish between 'add' and 'edit' // TODO: seems I do not distinguish between 'add' and 'edit'
472 $event = array("category" => 4100, "prio" => 200,
473 'ui' => array('uid' => $login_ui['uid']),
455 $event = array(
456 'category' => 4100,
457 'prio' => 200,
458 'ui' => $login_ui,
474 459 'ri' => array( 'ri' => array(
475 460 'repo_id' => $ri['repo_id'], 'repo_id' => $ri['repo_id'],
476 461 'name' => $ri['name']), 'name' => $ri['name']),
 
... ... function rg_bug_note_add($db, $repo_id, $bug_id, $login_uid, $data)
985 970 if ($_ui['exists'] == 1) if ($_ui['exists'] == 1)
986 971 $who_added_text = $_ui['username']; $who_added_text = $_ui['username'];
987 972
988 $event = array("category" => 4000, "prio" => 200,
989 'ui' => array('uid' => $login_uid),
973 $event = array(
974 'category' => 4000,
975 'prio' => 200,
976 'ui' => $_ui,
990 977 'bug' => array( 'bug' => array(
991 978 'bug_id' => $bug_id, 'bug_id' => $bug_id,
992 979 'title' => $_bi['title'], 'title' => $_bi['title'],
File inc/events.inc.php changed (mode: 100644) (index 6908ef0..6859bd8)
... ... function rg_event_process($db, $ev_id, $event)
146 146
147 147 if (!isset($rg_event_split_functions[$category])) { if (!isset($rg_event_split_functions[$category])) {
148 148 rg_event_set_error("Cannot find event function [cat=$category]!"); rg_event_set_error("Cannot find event function [cat=$category]!");
149 rg_log("DEBUG: rg_event_split_functions=" . rg_array2string($rg_event_split_functions));
149 rg_log_ml("DEBUG: rg_event_split_functions="
150 . print_r($rg_event_split_functions, TRUE));
150 151 break; break;
151 152 } }
152 153
File inc/git.inc.php changed (mode: 100644) (index 6cea0c4..a27905a)
... ... function rg_git_update_tag($db, $a)
1224 1224 $x['type'] = 'repo_refs'; $x['type'] = 'repo_refs';
1225 1225 $x['owner'] = $a['repo_uid']; $x['owner'] = $a['repo_uid'];
1226 1226 $x['uid'] = $a['login_uid']; $x['uid'] = $a['login_uid'];
1227 $x['username'] = $a['login_username'];
1227 $x['username'] = $a['ui']['username'];
1228 1228 $x['needed_rights'] = ''; $x['needed_rights'] = '';
1229 1229 $x['ip'] = $a['ip']; $x['ip'] = $a['ip'];
1230 1230 $x['misc'] = $a['refname']; $x['misc'] = $a['refname'];
 
... ... function rg_git_update_tag($db, $a)
1298 1298 // Not clear when we do not have a namespace. // Not clear when we do not have a namespace.
1299 1299 if (!empty($a['namespace'])) { if (!empty($a['namespace'])) {
1300 1300 // Update the main ref (not a namespace) // Update the main ref (not a namespace)
1301 $reason = $a['login_username'] . ' pushed tag ' . $a['refname'];
1301 $reason = $a['ui']['username'] . ' pushed tag ' . $a['refname'];
1302 1302 $r = rg_git_update_ref($a['repo_path'], $a['refname'], $r = rg_git_update_ref($a['repo_path'], $a['refname'],
1303 1303 $a['old_rev'], $a['new_rev'], $reason); $a['old_rev'], $a['new_rev'], $reason);
1304 1304 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_git_update_branch($db, $a)
1329 1329 $_x['type'] = 'repo_refs'; $_x['type'] = 'repo_refs';
1330 1330 $_x['owner'] = $a['repo_uid']; $_x['owner'] = $a['repo_uid'];
1331 1331 $_x['uid'] = $a['login_uid']; $_x['uid'] = $a['login_uid'];
1332 $_x['username'] = $a['login_username'];
1332 $_x['username'] = $a['ui']['username'];
1333 1333 $_x['needed_rights'] = ''; $_x['needed_rights'] = '';
1334 1334 $_x['ip'] = $a['ip']; $_x['ip'] = $a['ip'];
1335 1335 $_x['misc'] = $a['refname']; $_x['misc'] = $a['refname'];
 
... ... function rg_git_update_branch($db, $a)
1443 1443
1444 1444 // anonymous push - create a merge request // anonymous push - create a merge request
1445 1445 $ev = $a; $ev = $a;
1446 $ev['category'] = 'rg_mr_event_new';
1446 $ev['category'] = 'mr_event_new';
1447 1447 $ev['prio'] = 100; $ev['prio'] = 100;
1448 $ev['ui'] = array('uid' => $a['login_uid']);
1449 1448 $r = rg_event_add($db, $ev); $r = rg_event_add($db, $ev);
1450 1449 if ($r !== TRUE) if ($r !== TRUE)
1451 1450 rg_git_fatal($a['refname'] . ": " . rg_event_error()); rg_git_fatal($a['refname'] . ": " . rg_event_error());
 
... ... function rg_git_update_branch($db, $a)
1465 1464 // Not clear when we do not have a namespace. // Not clear when we do not have a namespace.
1466 1465 if (!empty($a['namespace'])) { if (!empty($a['namespace'])) {
1467 1466 // Updating main ref (not a namespace) // Updating main ref (not a namespace)
1468 $reason = $a['login_username']
1467 $reason = $a['ui']['username']
1469 1468 . ' pushed ref ' . $a['refname']; . ' pushed ref ' . $a['refname'];
1470 1469 $r = rg_git_update_ref($a['repo_path'], $a['refname'], $r = rg_git_update_ref($a['repo_path'], $a['refname'],
1471 1470 $a['old_rev'], $a['new_rev'], $reason); $a['old_rev'], $a['new_rev'], $reason);
 
... ... function rg_git_update_branch($db, $a)
1478 1477 $ev = $a; $ev = $a;
1479 1478 $ev['category'] = 3007; $ev['category'] = 3007;
1480 1479 $ev['prio'] = 50; $ev['prio'] = 50;
1481 $ev['ui'] = array(
1482 'organization' => $a['login_organization'],
1483 'uid' => $a['login_uid'],
1484 'username' => $a['login_username']
1485 );
1486 1480 $ev['ri'] = array( $ev['ri'] = array(
1487 1481 'repo_id' => $a['repo_id'], 'repo_id' => $a['repo_id'],
1488 1482 'name' => $a['repo_name'], 'name' => $a['repo_name'],
File inc/keys.inc.php changed (mode: 100644) (index 669da99..f164a44)
... ... function rg_keys_remove($db, $ui, $list)
318 318 } }
319 319 rg_sql_free_result($res); rg_sql_free_result($res);
320 320
321 $event = array("category" => 1001, "prio" => 50,
322 'ui' => array(
323 'uid' => $ui['uid'],
324 'email' => $ui['confirmed'] > 0 ? $ui['email'] : "",
325 ),
326 "keys" => implode(",", $my_list));
321 $event = array(
322 'category' => 1001,
323 'prio' => 50,
324 'ui' => $ui,
325 'keys' => implode(',', $my_list));
327 326 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
328 327 if ($r !== TRUE) { if ($r !== TRUE) {
329 328 rg_keys_set_error("cannot add event" rg_keys_set_error("cannot add event"
 
... ... function rg_keys_add($db, $ui, $key)
436 435 $key_id = $row['key_id']; $key_id = $row['key_id'];
437 436 rg_sql_free_result($res); rg_sql_free_result($res);
438 437
439 $event = array("category" => 1000, "prio" => 50,
440 'ui' => array(
441 'uid' => $ui['uid'],
442 'email' => $ui['confirmed'] > 0 ? $ui['email'] : ""
443 ),
438 $event = array(
439 'category' => 1000,
440 'prio' => 50,
441 'ui' => $ui,
444 442 'ki' => $ki, 'ki' => $ki,
445 443 'key_id' => $key_id); 'key_id' => $key_id);
446 444 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
File inc/mail.inc.php changed (mode: 100644) (index 7189cf7..e6a499e)
... ... function rg_mail_template($template, $more)
29 29 rg_prof_start("mail_template"); rg_prof_start("mail_template");
30 30 rg_log("mail_template: $template, more=" . rg_array2string($more)); rg_log("mail_template: $template, more=" . rg_array2string($more));
31 31
32 // Account was not confirmed, so do not send mail
33 // BUT, first time, when we ask for confirmation?!
34 if (empty($more['ui']['email'])) {
35 rg_log('BUG! ui::email is not set in @more!');
36 return TRUE;
37 }
32 $ret = FALSE;
33 while (1) {
34 if (!isset($more['ui']['ignore_confirmed']))
35 $more['ui']['ignore_confirmed'] = 0;
36
37 if (($more['ui']['ignore_confirmed'] == 0)
38 && ($more['ui']['confirmed'] == 0)) {
39 rg_log('Confirmed is 0!');
40 $ret = TRUE;
41 break;
42 }
43
44 if (empty($more['ui']['email'])) {
45 rg_internal_error('email is not set in more array');
46 $ret = TRUE;
47 break;
48 }
49
50 if (!isset($more['debug']))
51 $more['debug'] = 0;
52
53 $more['HTML:rg_admin_email'] = $rg_admin_email;
54 $more['HTML:utf8_rg_admin_name'] = "=?UTF-8?B?"
55 . base64_encode($rg_admin_name) . "?=";
56
57 $subject = rg_template($template . ".subj.txt", $more, FALSE /*xss*/);
58 $subject = trim($subject);
59 $subject = str_replace("\r", '', $subject);
60 $subject = str_replace("\n", '', $subject);
61 // TODO: do not encode it as UTF-8 if not needed
62 $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
63
64 $header = rg_template("mail/common.head.txt", $more, FALSE /*xss*/);
65 $header .= rg_template($template . ".head.txt", $more, FALSE /*xss*/);
66 $header = trim($header);
67
68 $body = rg_template($template . ".body.txt", $more, FALSE /*xss*/);
69
70 rg_log("CHECK: mail_template(" . $more['ui']['email'] . ",
71 $subject, $body, $header, -f $rg_admin_email");
72 if ($more['debug'] == 1) {
73 if (!isset($more['ui']['uid']))
74 $k = 0;
75 else
76 $k = $more['ui']['uid'];
77
78 rg_cache_set('DEBUG::' . $k . '::mail',
79 array(
80 'header' => $header,
81 'subject' => $subject,
82 'to' => $more['ui']['email'],
83 'body' => $body
84 ), RG_SOCKET_NO_WAIT);
85 $ret = TRUE;
86 break;
87 }
38 88
39 if (!isset($more['debug']))
40 $more['debug'] = 0;
41
42 $more['HTML:rg_admin_email'] = $rg_admin_email;
43 $more['HTML:utf8_rg_admin_name'] = "=?UTF-8?B?"
44 . base64_encode($rg_admin_name) . "?=";
45
46 $subject = rg_template($template . ".subj.txt", $more, FALSE /*xss*/);
47 $subject = trim($subject);
48 $subject = str_replace("\r", '', $subject);
49 $subject = str_replace("\n", '', $subject);
50 // TODO: do not encode it as UTF-8 if not needed
51 $subject = "=?UTF-8?B?" . base64_encode($subject) . "?=";
52
53 $header = rg_template("mail/common.head.txt", $more, FALSE /*xss*/);
54 $header .= rg_template($template . ".head.txt", $more, FALSE /*xss*/);
55 $header = trim($header);
56
57 $body = rg_template($template . ".body.txt", $more, FALSE /*xss*/);
58
59 rg_log("CHECK: mail_template(" . $more['ui']['email'] . ",
60 $subject, $body, $header, -f $rg_admin_email");
61 if ($more['debug'] == 1) {
62 if (!isset($more['ui']['uid']))
63 $k = 'nouid';
64 else
65 $k = $more['ui']['uid'];
66
67 rg_cache_set('DEBUG::' . $k . '::mail',
68 array(
69 'header' => $header,
70 'subject' => $subject,
71 'to' => $more['ui']['email'],
72 'body' => $body
73 ), RG_SOCKET_NO_WAIT);
74 $ret = TRUE;
75 } else {
76 89 $ret = mail($more['ui']['email'], $subject, $body, $header, $ret = mail($more['ui']['email'], $subject, $body, $header,
77 90 "-f $rg_admin_email"); "-f $rg_admin_email");
91 if ($ret === FALSE)
92 rg_log("Sending mail failed to=" . $more['ui']['email']
93 . " subject=$subject!");
94 break;
78 95 } }
79 if ($ret === FALSE)
80 rg_log("Sending mail failed to=" . $more['ui']['email']
81 . " subject=$subject!");
82 96
83 97 rg_prof_end("mail_template"); rg_prof_end("mail_template");
84 98 return $ret; return $ret;
File inc/mr.inc.php changed (mode: 100644) (index ee8e0b8..507fb2f)
... ... function rg_mr_error()
32 32 * Event functions * Event functions
33 33 */ */
34 34 $rg_mr_functions = array( $rg_mr_functions = array(
35 'rg_mr_event_new' => 'rg_mr_event_new',
36 'rg_mr_event_add_to_db' => 'rg_mr_event_add_to_db',
35 'mr_event_new' => 'rg_mr_event_new',
36 'mr_event_add_to_db' => 'rg_mr_event_add_to_db',
37 37 'mr_merge' => 'rg_mr_event_merge' 'mr_merge' => 'rg_mr_event_merge'
38 38 ); );
39 39 rg_event_register_functions($rg_mr_functions); rg_event_register_functions($rg_mr_functions);
 
... ... function rg_mr_event_new($db, $ev)
81 81
82 82 // Insert it into database // Insert it into database
83 83 $ret[] = array_merge($ev, $ret[] = array_merge($ev,
84 array('category' => 'rg_mr_event_add_to_db', 'prio' => 100));
84 array('category' => 'mr_event_add_to_db', 'prio' => 100));
85 85
86 86 // TODO: Notify admins of the repo // TODO: Notify admins of the repo
87 87
 
... ... function rg_mr_event_add_to_db($db, $a)
119 119 // TODO: git may fail to update the reference after this hook; // TODO: git may fail to update the reference after this hook;
120 120 // the mr code should check if the update was done. // the mr code should check if the update was done.
121 121 $mr = 'refs/mr/' . $id; $mr = 'refs/mr/' . $id;
122 $reason = $a['login_username'] . ' pushed a merge request'
122 $reason = $a['ui']['username'] . ' pushed a merge request'
123 123 . ' for ref ' . $a['refname'] . ' for ref ' . $a['refname']
124 124 . ' into ' . $mr; . ' into ' . $mr;
125 125 $r = rg_git_update_ref($a['repo_path'], $mr, '', $a['new_rev'], $reason); $r = rg_git_update_ref($a['repo_path'], $mr, '', $a['new_rev'], $reason);
File inc/repo.inc.php changed (mode: 100644) (index ce5f443..68f6e8b)
... ... function rg_repo_delete($db, $repo_id, $ui)
921 921 } }
922 922 rg_sql_free_result($res); rg_sql_free_result($res);
923 923
924 $event = array("category" => 3001, "prio" => 50,
925 'ui' => array(
926 'email' => $ui['confirmed'] > 0 ? $ui['email'] : "",
927 'uid' => $ui['uid']),
924 $event = array(
925 'category' => 3001,
926 'prio' => 50,
927 'ui' => $ui,
928 928 'ri' => array( 'ri' => array(
929 929 'name' => $ri['name'], 'name' => $ri['name'],
930 930 'repo_id' => $repo_id 'repo_id' => $repo_id
 
... ... function rg_repo_edit($db, $login_ui, &$new)
1164 1164 // TODO: we should log what changed // TODO: we should log what changed
1165 1165 } }
1166 1166
1167 $event = array('category' => $cat, 'prio' => 50,
1167 $event = array(
1168 'category' => $cat,
1169 'prio' => 50,
1168 1170 'notification' => $notification, 'notification' => $notification,
1169 'ui' => array(
1170 'uid' => $login_ui['uid'],
1171 'email' => $login_ui['confirmed'] > 0 ? $login_ui['email'] : ""
1172 ),
1171 'ui' => $login_ui,
1173 1172 'history_category' => $hcat, 'history_category' => $hcat,
1174 1173 'history_message' => $hmess); 'history_message' => $hmess);
1175 1174 $event = rg_array_merge($event, 'ri_old', $ri); $event = rg_array_merge($event, 'ri_old', $ri);
File inc/user.inc.php changed (mode: 100644) (index 2dc469f..a47e1c6)
... ... function rg_user_rename($db, $ui, $new_name)
448 448 break; break;
449 449
450 450 // TODO: Check if all parameters are used. // TODO: Check if all parameters are used.
451 $event = array("category" => 2005, "prio" => 50,
452 'ui' => array(
453 'rename_from' => $ui['username'],
454 'rename_to' => $new_name,
455 'uid' => $ui['uid']
456 )
451 $event = array(
452 'category' => 2005,
453 'prio' => 50,
454 'ui' => $ui,
455 'rename_from' => $ui['username'],
456 'rename_to' => $new_name
457 457 ); );
458 458 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
459 459 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_user_rename($db, $ui, $new_name)
478 478 */ */
479 479 function rg_user_edit($db, $d) function rg_user_edit($db, $d)
480 480 { {
481 global $rg_account_email_confirm;
482
483 481 rg_prof_start("user_edit"); rg_prof_start("user_edit");
484 482 rg_log_enter("user_edit: d: " . rg_array2string($d)); rg_log_enter("user_edit: d: " . rg_array2string($d));
485 483
 
... ... function rg_user_edit($db, $d)
496 494 if ($d['ask_for_email_confirmation'] == 1) if ($d['ask_for_email_confirmation'] == 1)
497 495 $d['confirmed'] = 0; $d['confirmed'] = 0;
498 496
499 if (($d['confirmed'] == 0)
500 && ($rg_account_email_confirm == 0)) {
501 // no need to confirm account
502 $d['confirmed'] = 1;
503 }
504
505 497 $update_pass = !empty($d['pass']); $update_pass = !empty($d['pass']);
506 498 if ($update_pass) { if ($update_pass) {
507 499 if (strcmp($d['pass'], $d['pass2']) != 0) { if (strcmp($d['pass'], $d['pass2']) != 0) {
 
... ... function rg_user_edit($db, $d)
548 540 . ", rights = @@rights@@" . ", rights = @@rights@@"
549 541 . ", session_time = @@session_time@@" . ", session_time = @@session_time@@"
550 542 . ", plan_id = @@plan_id@@" . ", plan_id = @@plan_id@@"
543 . ", confirmed = @@confirmed@@"
551 544 . ", confirm_token = @@confirm_token@@" . ", confirm_token = @@confirm_token@@"
552 545 . $salt_pass_add . $salt_pass_add
553 546 . " WHERE uid = @@uid@@"; . " WHERE uid = @@uid@@";
 
... ... function rg_user_edit($db, $d)
568 561 rg_cache_set('user' . '::' . $d['uid'] . '::' . 'info', rg_cache_set('user' . '::' . $d['uid'] . '::' . 'info',
569 562 $d, RG_SOCKET_NO_WAIT); $d, RG_SOCKET_NO_WAIT);
570 563
571 $event = array('category' => 2000, 'prio' => 50,
564 // we need to be able to send the welcome mail
565 $d['ignore_confirmed'] = 1;
566
567 $event = array(
568 'category' => 2000,
569 'prio' => 50,
572 570 'ui' => $d, 'ui' => $d,
573 'rg_account_email_confirm' => $rg_account_email_confirm,
574 571 'url' => rg_base_url() 'url' => rg_base_url()
575 572 ); );
576 573 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
 
... ... function rg_user_login_by_sid($db, &$rg)
793 790 $rg['login_ui']['rights'] = ""; $rg['login_ui']['rights'] = "";
794 791 $rg['login_ui']['username'] = ""; $rg['login_ui']['username'] = "";
795 792 $rg['login_ui']['organization'] = 0; $rg['login_ui']['organization'] = 0;
793 $rg['login_ui']['confirmed'] = 0;
796 794
797 795 $ret = FALSE; $ret = FALSE;
798 796 while (1) { while (1) {
 
... ... function rg_user_auto_login($db, $uid, $lock_ip, &$ui)
921 919 function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip, function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip,
922 920 &$ui) &$ui)
923 921 { {
922 global $rg_account_email_confirm;
923
924 924 rg_prof_start("user_login_by_user_pass"); rg_prof_start("user_login_by_user_pass");
925 925 rg_log_enter("user_login_by_user_pass: user=$user" rg_log_enter("user_login_by_user_pass: user=$user"
926 926 . " login_token=$login_token lock_ip=$lock_ip"); . " login_token=$login_token lock_ip=$lock_ip");
 
... ... function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip,
953 953 break; break;
954 954 } }
955 955
956 if ($ui0['confirmed'] == 0) {
956 if ($rg_account_email_confirm && ($ui0['confirmed'] == 0)) {
957 957 rg_user_set_error("invalid user, pass or login token"); rg_user_set_error("invalid user, pass or login token");
958 958 rg_log("account is not confirmed"); rg_log("account is not confirmed");
959 959 break; break;
 
... ... function rg_user_login_by_user_pass($db, $user, $pass, $login_token, $lock_ip,
979 979 } }
980 980
981 981 $event = array( $event = array(
982 'ui' => array('uid' => $ui0['uid']),
983 982 'category' => 2001, 'category' => 2001,
984 983 'prio' => 100, 'prio' => 100,
984 'ui' => $ui0,
985 985 'itime' => time()); 'itime' => time());
986 986 $r = rg_event_add($db, $event); $r = rg_event_add($db, $event);
987 987 if ($r !== TRUE) { if ($r !== TRUE) {
 
... ... function rg_user_forgot_pass_mail($db, $rg, $email)
1323 1323
1324 1324 $ret['exists'] = 1; $ret['exists'] = 1;
1325 1325
1326 $rg['ui'] = array('email' => $email);
1326 $rg['ui'] = $rg['login_ui'];
1327 $rg['ui']['email'] = $email;
1328 $rg['ui']['ignore_confirmed'] = 1;
1327 1329 $rg['forgot_token'] = $r['token']; $rg['forgot_token'] = $r['token'];
1328 1330
1329 1331 $r = rg_mail_template('mail/user/forgot/recover', $rg); $r = rg_mail_template('mail/user/forgot/recover', $rg);
 
... ... function rg_user_confirm($db, $token)
1429 1431 } }
1430 1432
1431 1433 $params = array("token" => $token); $params = array("token" => $token);
1432 $sql = "SELECT uid, confirmed FROM users WHERE confirm_token = @@token@@";
1434 $sql = 'SELECT uid, confirmed FROM users'
1435 . ' WHERE confirm_token = @@token@@';
1433 1436 $res = rg_sql_query_params($db, $sql, $params); $res = rg_sql_query_params($db, $sql, $params);
1434 1437 if ($res === FALSE) { if ($res === FALSE) {
1435 rg_user_set_error("cannot search for token (" . rg_sql_error() . ")");
1438 rg_user_set_error('cannot search for token');
1436 1439 break; break;
1437 1440 } }
1438 1441 $rows = rg_sql_num_rows($res); $rows = rg_sql_num_rows($res);
 
... ... function rg_user_confirm($db, $token)
1445 1448 } }
1446 1449 $uid = $row['uid']; $uid = $row['uid'];
1447 1450
1448 if ($row['confirmed'] < 2) {
1451 if ($row['confirmed'] == 0) {
1449 1452 // "< 2" because we mark with "1" if "no need to confirm" // "< 2" because we mark with "1" if "no need to confirm"
1450 1453 $params = array("confirmed" => $now, "uid" => $uid); $params = array("confirmed" => $now, "uid" => $uid);
1451 $sql = "UPDATE users SET confirmed = @@confirmed@@"
1452 . " WHERE uid = @@uid@@"
1453 . " AND confirmed < 2";
1454 $sql = 'UPDATE users SET confirmed = @@confirmed@@'
1455 . ' WHERE uid = @@uid@@';
1454 1456 $res = rg_sql_query_params($db, $sql, $params); $res = rg_sql_query_params($db, $sql, $params);
1455 1457 if ($res === FALSE) { if ($res === FALSE) {
1456 1458 rg_user_set_error('cannot set confirmed'); rg_user_set_error('cannot set confirmed');
 
... ... function rg_user_api($db, $a)
1782 1784 */ */
1783 1785 function rg_user_ask_for_email_confirmation($db, $uid) function rg_user_ask_for_email_confirmation($db, $uid)
1784 1786 { {
1787 $ui = rg_user_info($db, $uid, '', '');
1788 if ($ui['exists'] != 1)
1789 return FALSE;
1790
1785 1791 $ev = array( $ev = array(
1786 1792 'category' => 'ask-email-confirmation', 'category' => 'ask-email-confirmation',
1787 1793 'prio' => 200, 'prio' => 200,
1788 'ui' => array('uid' => $uid),
1794 'ui' => $ui,
1789 1795 'base_url' => rg_base_url() 'base_url' => rg_base_url()
1790 1796 ); );
1791 1797 $r = rg_event_add($db, $ev); $r = rg_event_add($db, $ev);
 
... ... function rg_user_ask_for_email_confirmation($db, $uid)
1796 1802 return TRUE; return TRUE;
1797 1803 } }
1798 1804
1805 /*
1806 * Transforms a list of uids into a list with full user info
1807 */
1808 function rg_user_list_to_full_info($db, $list)
1809 {
1810 $ret = array();
1811 foreach ($list as $index => $uid) {
1812 $ret['ui'] = rg_user_info($db, $uid, '', '');
1813 if ($ret['ui']['ok'] != 1)
1814 return FALSE;
1815
1816 if ($ret['ui']['exists'] != 1)
1817 continue;
1818 }
1819
1820 return $ret;
1821 }
1822
1799 1823 ?> ?>
File inc/user/home-page.php changed (mode: 100644) (index affe658..e7bd91f)
... ... if ($rg['page_ui']['uid'] == $rg['login_ui']['uid']) {
26 26 if (empty($rg['login_ui']['email'])) if (empty($rg['login_ui']['email']))
27 27 $hints[]['HTML:hint'] = rg_template('user/hints/email_empty.html', $hints[]['HTML:hint'] = rg_template('user/hints/email_empty.html',
28 28 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
29 else if ($rg['login_ui']['confirmed'] < 10)
29 else if ($rg['login_ui']['confirmed'] == 0)
30 30 $hints[]['HTML:hint'] = rg_template('user/hints/econf.html', $hints[]['HTML:hint'] = rg_template('user/hints/econf.html',
31 31 $rg, TRUE /*xss*/); $rg, TRUE /*xss*/);
32 32
File inc/user/repo-page.php changed (mode: 100644) (index 323f3e7..c640fc7)
... ... if (strcmp($_subop, "history") == 0) {
235 235 else else
236 236 $commit = rg_git_reference($paras[0]); $commit = rg_git_reference($paras[0]);
237 237 if ($commit === FALSE) { if ($commit === FALSE) {
238 rg_log("Invalid commit"
239 . " [" . $paras[0] . "]."
240 . " Make it empty.");
238 rg_log("Invalid commit; make it empty.");
241 239 // TODO: give an error on the page?! // TODO: give an error on the page?!
242 240 $commit = ''; $commit = '';
243 241 } }
File root/themes/default/doc/api.html changed (mode: 100644) (index 6558691..ba5362e)
... ... $ ssh rocketgit@rocketgit.com api user_info user=bla
42 42 "session_time": "3600", "session_time": "3600",
43 43 "last_seen": "1464805192", "last_seen": "1464805192",
44 44 "disk_used_mb": null, "disk_used_mb": null,
45 "confirmed": "1",
45 "confirmed": "1468297652",
46 46 "confirm_token": "c215e946b2b15d66d14b", "confirm_token": "c215e946b2b15d66d14b",
47 47 "organization": "0", "organization": "0",
48 48 "realname": "my real name", "realname": "my real name",
File scripts/remote.php changed (mode: 100644) (index 5379e0d..b03344f)
... ... if (($push == 1) && rg_user_over_limit($db, $owner_ui, $max))
286 286 . " (" . $owner_ui['disk_used_mb']. "MiB >= " . $max . "MiB)"); . " (" . $owner_ui['disk_used_mb']. "MiB >= " . $max . "MiB)");
287 287
288 288 // Put in environment all we need // Put in environment all we need
289 putenv("ROCKETGIT_LOGIN_ORGANIZATION=" . $conn_ui['organization']);
290 289 putenv("ROCKETGIT_LOGIN_UID=" . $login_uid); putenv("ROCKETGIT_LOGIN_UID=" . $login_uid);
291 putenv("ROCKETGIT_LOGIN_USERNAME=" . $conn_ui['username']);
292 290 putenv("ROCKETGIT_LOGIN_URL=" . rg_re_userpage($conn_ui)); putenv("ROCKETGIT_LOGIN_URL=" . rg_re_userpage($conn_ui));
293 291 putenv("ROCKETGIT_KEY_ID=" . $key_id); putenv("ROCKETGIT_KEY_ID=" . $key_id);
294 292 putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']); putenv("ROCKETGIT_REPO_ID=" . $ri['repo_id']);
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/catalinux/rocketgit

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/catalinux/rocketgit

Clone this repository using git:
git clone git://git.rocketgit.com/user/catalinux/rocketgit

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main