/** * 删除分支 */ function _del_branch_action() { if ($this->role < 2) { throw new \Exception('firegit.u_power'); } $branch = implode('/', func_get_args()); $reposite = new \firegit\git\Reposite($this->gitGroup, $this->gitName); $ret = $reposite->delBranch($branch); if ($ret > 0) { throw new \Exception('branch.u_delBranchFailed code:' . $ret); } $repos = new \firegit\app\mod\git\Reposite(); $repos->delBranch($this->gitGroup, $this->gitName, $branch); }
/** * 开始接收数据前 * @param Hook $hook * @param $commits * @return bool */ static function preReceive(Hook $hook, $commits) { $reposite = new Reposite($hook->group, $hook->name); // 检查用户是否能操作该库 $mod = new \firegit\app\mod\git\Reposite(); $users = $mod->getUsers($hook->group, $hook->name); $user = ''; $role = -1; if ($hook->fromHttp) { $user = $hook->authUser; if (!$user) { ColorConsole::error('用户尚未登录'); return false; } if (!isset($users[$user])) { ColorConsole::error('用户' . $user . '没有该项目的权限'); return false; } $role = $users[$user]['repo_role']; if ($role <= \firegit\app\mod\git\Reposite::GROUP_ROLE_READER) { ColorConsole::error('用户' . $user . '没有提交该项目的权限'); return false; } } // 检查每个分支是否已经创建过 $merges = array(); $branches = array(); foreach ($commits as $commit) { $branch = $commit['branch']; if (strpos($branch, Util::TAG_PREFIX) !== 0) { if ($role == \firegit\app\mod\git\Reposite::GROUP_ROLE_BASIC) { if (!$reposite->isBranchExists($branch)) { if (!in_array($branch, array(Util::normalBranch('release'), Util::normalBranch('develop'), Util::normalBranch('beta')))) { ColorConsole::error('服务器上还没有' . $branch . '分支,请先通过web界面创建'); return false; } elseif ($commit['end'] == \firegit\git\util::ZERO_COMMIT) { $repos = new \firegit\app\mod\git\Reposite(); $repos->delBranch($hook->group, $hook->name, $branch); } } } // 非管理员不能往主分支提交 if (in_array($role, array(\firegit\app\mod\git\Reposite::GROUP_ROLE_BASIC, \firegit\app\mod\git\Reposite::GROUP_ROLE_ADVANCED))) { if ($branch == Util::normalBranch('master') || $branch == Util::normalBranch('beta')) { ColorConsole::error('您没有提交到' . $branch . '分支的权限'); return false; } } // 找出增加或修改的文件,对其进行代码审查 $diffFiles = self::getDiffFiles($commit['start'], $commit['end']); if ($diffFiles) { if (!self::checkFiles($commit['end'], $diffFiles)) { ColorConsole::error('代码审查没有通过,请修改完毕再提交!'); return false; } } // 对分支做操作 if (!$reposite->isBranchExists($branch)) { $repos = new \firegit\app\mod\git\Reposite(); $repos->saveBranch($hook->group, $hook->name, $branch, $user); } elseif ($commit['end'] == \firegit\git\util::ZERO_COMMIT) { $repos = new \firegit\app\mod\git\Reposite(); $repos->delBranch($hook->group, $hook->name, $branch); } $_ms = $reposite->listMergeCommits($commit['start'], $commit['end']); if ($_ms) { $merges = array_merge($merges, $_ms); } $branches[substr($branch, strlen(Util::BRANCH_PREFIX))] = $commit['end']; } } // 设置分支信息 $mod->setBranches($hook->group, $hook->name, $user, $commits); // 处理合并请求 $merge = new \firegit\app\mod\git\Merge(); if ($merges) { $merge->handleMerges($hook->group, $hook->name, $merges); } // 处理分支 if ($branches) { $merge->updateBranches($hook->group, $hook->name, $branches); } }
/** * 将指定的合并对应的合并请求标志为合并成功 * @param $repoGroup * @param $repoName * @param $merges * @return array */ function handleMerges($repoGroup, $repoName, $merges) { // 现获取所有的合并 $db = Db::get('firegit'); $rows = $db->table('fg_merge')->field('merge_id', 'orig_branch', 'orig_hash', 'dest_hash', 'dest_branch')->where(array('repo_group' => $repoGroup, 'repo_name' => $repoName, 'merge_status!' => MERGE_STATUS_CANCELED))->order('merge_id', false)->get(); // 合并完的分支自动删除 $repo = new \firegit\git\Reposite($repoGroup, $repoName); foreach ($merges as $key => $merge) { foreach ($rows as $key => $row) { if ($merge['orig'] == $row['orig_hash'] && $merge['dest'] == $row['dest_hash']) { \firegit\log\Logger::trace('merge.chageStatus merge_id=%d orig=%s dest=%s', $row['merge_id'], $merge['orig'], $merge['dest']); $this->endMerge($row['merge_id'], MERGE_STATUS_MERGED); $this->updateDeployStatus($row['merge_id'], DEPLOY_STATUS_BETA); // 合并之后不删除分支 等合并到mater的时候在删除 if ($row['dest_branch'] == 'master' && !$repo->isProtected($row['orig_branch'])) { $repo->delBranch($row['orig_branch']); $repos = new \firegit\app\mod\git\Reposite(); $repos->delBranch($repoGroup, $repoName, $row['orig_branch']); \firegit\log\Logger::trace('merge.delBranch branch=%s hash=%s', $row['orig_branch'], $row['orig_hash']); } unset($rows[$key]); } } } }
/** * 合并到master ---------后期要重新优化代码@----------- * @param $mergeIds * @throws \Exception */ function _mergemaster_action() { $mergeIds = $this->post('merge_ids'); if (empty($mergeIds)) { throw new \Exception('firegit.merge_id_empty'); } $repoTmp = TMP_ROOT . '/merge/'; $api = new \firegit\app\mod\git\Merge(); foreach ($mergeIds as $mergeId) { $repoDir = $repoTmp . '/master'; if (is_dir($repoDir)) { // stat beta system('rm ' . $repoDir . ' -rf'); } mkdir($repoDir, 0777, true); chdir($repoDir); $mergeinfo = $api->getMerge($mergeId); if (!$mergeinfo) { throw new \Exception('firegit.u_notfound'); } // 检查合并状态 只允许预上线已确认的 if ($mergeinfo['deploy_status'] != 4) { throw new \Exception('firegit.u_mergeedFailed'); } $origDir = GIT_REPO . $mergeinfo['repo_group'] . '/' . $mergeinfo['repo_name'] . '.git'; // clone远程分支 $cmd = sprintf('git clone %s -b master ./', $origDir); exec($cmd, $outputs, $code); unset($outputs); system('git config user.name ' . $this->user); system('git config user.email ' . $this->user . '@hunbasha.com'); $cmd = sprintf('git fetch origin %s:%s', $mergeinfo['orig_branch'], $mergeinfo['orig_branch']); exec($cmd, $outputs, $code); unset($outputs); $cmd = sprintf('git merge -m "Merge remote-tracking branch \'%s\' into %s" %s', $mergeinfo['orig_branch'], 'master', $mergeinfo['orig_branch']); exec($cmd, $outputs, $code); $merge = new \firegit\app\mod\git\Merge(); if ($code) { $merge->endMerge($mergeId, false, implode("\n", $outputs)); throw new \Exception('firegit.merge_master_error:' . $mergeinfo['orig_branch']); } unset($outputs); //push 到远程 $cmd = sprintf('git push origin master:master'); exec($cmd, $outputs, $code); if ($code != 0) { throw new \Exception('firegit.push_master_error:' . $mergeinfo['orig_branch']); } $repo = new \firegit\git\Reposite($mergeinfo['repo_group'], $mergeinfo['repo_name']); //删除合并的分支 if (!$repo->isProtected($mergeinfo['orig_branch'])) { $repo->delBranch($mergeinfo['orig_branch']); $repos = new \firegit\app\mod\git\Reposite(); $repos->delBranch($mergeinfo['repo_group'], $mergeinfo['repo_name'], $mergeinfo['orig_branch']); \firegit\log\Logger::trace('merge.delBranch branch=%s hash=%s', $mergeinfo['orig_branch'], $mergeinfo['orig_hash']); } $merge->updateDeployStatus($mergeId, 0x11); } }