文件上传
拖拽文件到此处或点击选择文件
支持任意大小的文件,无数量限制
isFile() && !strpos($file->getPathname(), '.git')) { $relativePath = str_replace('\\', '/', substr($file->getPathname(), strlen(__DIR__) + 1)); $files[] = $relativePath; } } return $files; } // 处理文件上传 function handleFileUpload($files) { $uploadedFiles = []; if (!isset($files['files']) || empty($files['files']['name'][0])) { return ['success' => false, 'message' => '没有选择文件']; } $uploadDir = __DIR__ . '/uploads/'; if (!is_dir($uploadDir)) { mkdir($uploadDir, 0777, true); } $fileCount = count($files['files']['name']); for ($i = 0; $i < $fileCount; $i++) { if ($files['files']['error'][$i] === UPLOAD_ERR_OK) { $tmpName = $files['files']['tmp_name'][$i]; $fileName = basename($files['files']['name'][$i]); $uploadPath = $uploadDir . $fileName; // 移动上传的文件 if (move_uploaded_file($tmpName, $uploadPath)) { $uploadedFiles[] = $fileName; } } } return ['success' => true, 'files' => $uploadedFiles]; } // 获取远程仓库配置 function getRemoteConfig() { global $remoteConfigFile; if (file_exists($remoteConfigFile)) { $config = json_decode(file_get_contents($remoteConfigFile), true); return $config ?: ['remotes' => []]; } return ['remotes' => []]; } // 保存远程仓库配置 function saveRemoteConfig($config) { global $remoteConfigFile; return file_put_contents($remoteConfigFile, json_encode($config, JSON_PRETTY_PRINT)); } // 添加远程仓库 function addRemote($name, $url) { global $currentDir; try { exec('cd "' . $currentDir . '" && git remote add ' . escapeshellarg($name) . ' ' . escapeshellarg($url), $output, $returnCode); if ($returnCode === 0) { // 保存到配置文件 $config = getRemoteConfig(); $config['remotes'][$name] = $url; saveRemoteConfig($config); return ['success' => true, 'message' => '远程仓库添加成功']; } else { return ['success' => false, 'message' => '远程仓库添加失败']; } } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 获取远程仓库列表 function getRemotes() { global $currentDir; try { exec('cd "' . $currentDir . '" && git remote -v', $output, $returnCode); $remotes = []; foreach ($output as $line) { if (preg_match('/^(\S+)\s+(\S+)\s+\((\w+)\)/', $line, $matches)) { $remotes[$matches[1]] = [ 'url' => $matches[2], 'type' => $matches[3] ]; } } return ['success' => true, 'remotes' => $remotes]; } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 推送代码到指定远程仓库 function pushToRemote($remote = 'origin', $branch = 'main') { global $currentDir; try { exec('cd "' . $currentDir . '" && git push ' . escapeshellarg($remote) . ' ' . escapeshellarg($branch), $output, $returnCode); return ['success' => $returnCode === 0, 'output' => $output]; } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 获取分支列表 function getBranches() { global $currentDir; try { $output = []; $returnCode = 0; // 获取本地分支 exec('cd "' . $currentDir . '" && git branch -a', $output, $returnCode); $branches = []; $currentBranch = ''; foreach ($output as $line) { $line = trim($line); if (empty($line)) continue; // 检查是否是当前分支 if (strpos($line, '*') === 0) { $currentBranch = trim(substr($line, 1)); $branches[] = [ 'name' => $currentBranch, 'current' => true, 'remote' => false ]; } else { // 检查是否是远程分支 $isRemote = strpos($line, 'remotes/') !== false; $branchName = $isRemote ? substr($line, strpos($line, 'remotes/') + 8) : $line; $branches[] = [ 'name' => trim($branchName), 'current' => false, 'remote' => $isRemote ]; } } return ['success' => true, 'branches' => $branches, 'current' => $currentBranch]; } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 创建新分支 function createBranch($branchName) { global $currentDir; try { exec('cd "' . $currentDir . '" && git checkout -b ' . escapeshellarg($branchName), $output, $returnCode); if ($returnCode === 0) { return ['success' => true, 'message' => '分支创建成功', 'output' => $output]; } else { return ['success' => false, 'message' => '分支创建失败', 'output' => $output]; } } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 删除分支 function deleteBranch($branchName, $force = false) { global $currentDir; try { $forceFlag = $force ? '-D' : '-d'; exec('cd "' . $currentDir . '" && git branch ' . $forceFlag . ' ' . escapeshellarg($branchName), $output, $returnCode); if ($returnCode === 0) { return ['success' => true, 'message' => '分支删除成功', 'output' => $output]; } else { return ['success' => false, 'message' => '分支删除失败', 'output' => $output]; } } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 切换分支 function switchBranch($branchName) { global $currentDir; try { exec('cd "' . $currentDir . '" && git checkout ' . escapeshellarg($branchName), $output, $returnCode); if ($returnCode === 0) { return ['success' => true, 'message' => '分支切换成功', 'output' => $output]; } else { return ['success' => false, 'message' => '分支切换失败', 'output' => $output]; } } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 处理Git操作 function handleGitOperation($operation, $message = '', $files = [], $remote = 'origin', $branch = 'main') { global $currentDir; try { $output = []; $returnCode = 0; switch ($operation) { case 'status': exec('cd "' . $currentDir . '" && git status --porcelain', $output, $returnCode); break; case 'add': if (!empty($files)) { foreach ($files as $file) { exec('cd "' . $currentDir . '" && git add "' . $file . '"', $output, $returnCode); } } else { exec('cd "' . $currentDir . '" && git add .', $output, $returnCode); } break; case 'commit': if (empty($message)) { $message = '自动提交'; } exec('cd "' . $currentDir . '" && git commit -m "' . addslashes($message) . '"', $output, $returnCode); break; case 'push': // 使用新的推送函数,支持指定远程仓库和分支 return pushToRemote($remote, $branch); case 'log': exec('cd "' . $currentDir . '" && git log --oneline -10', $output, $returnCode); break; } return ['success' => $returnCode === 0, 'output' => $output]; } catch (Exception $e) { return ['success' => false, 'message' => $e->getMessage()]; } } // 处理AJAX请求 if ($_SERVER['REQUEST_METHOD'] === 'POST') { header('Content-Type: application/json; charset=utf-8'); $action = $_POST['action'] ?? ''; switch ($action) { case 'upload': $result = handleFileUpload($_FILES); echo json_encode($result); break; case 'git_operation': $operation = $_POST['operation'] ?? ''; $message = $_POST['message'] ?? ''; $files = $_POST['files'] ?? []; $remote = $_POST['remote'] ?? 'origin'; $branch = $_POST['branch'] ?? 'main'; $result = handleGitOperation($operation, $message, $files, $remote, $branch); echo json_encode($result); break; case 'add_remote': $name = $_POST['name'] ?? ''; $url = $_POST['url'] ?? ''; if (empty($name) || empty($url)) { echo json_encode(['success' => false, 'message' => '远程仓库名称和地址不能为空']); } else { $result = addRemote($name, $url); echo json_encode($result); } break; case 'get_remotes': $result = getRemotes(); echo json_encode($result); break; case 'get_branches': $result = getBranches(); echo json_encode($result); break; case 'create_branch': $branchName = $_POST['branch_name'] ?? ''; if (empty($branchName)) { echo json_encode(['success' => false, 'message' => '分支名称不能为空']); } else { $result = createBranch($branchName); echo json_encode($result); } break; case 'delete_branch': $branchName = $_POST['branch_name'] ?? ''; $force = isset($_POST['force']) && $_POST['force'] === 'true'; if (empty($branchName)) { echo json_encode(['success' => false, 'message' => '分支名称不能为空']); } else { $result = deleteBranch($branchName, $force); echo json_encode($result); } break; case 'switch_branch': $branchName = $_POST['branch_name'] ?? ''; if (empty($branchName)) { echo json_encode(['success' => false, 'message' => '分支名称不能为空']); } else { $result = switchBranch($branchName); echo json_encode($result); } break; case 'get_files': $files = getFileList(); echo json_encode(['success' => true, 'files' => $files]); break; case 'check_git': echo json_encode(['success' => true, 'hasGit' => checkGitRepo()]); break; case 'init_git': $success = initGitRepo(); echo json_encode(['success' => $success]); break; default: echo json_encode(['success' => false, 'message' => '未知操作']); } exit; } ?>
拖拽文件到此处或点击选择文件
支持任意大小的文件,无数量限制