初始提交
This commit is contained in:
511
index.php
Normal file
511
index.php
Normal file
@@ -0,0 +1,511 @@
|
||||
<?php
|
||||
/**
|
||||
* Git文件上传工具
|
||||
* 支持JS和CSS分离,文件上传无限制
|
||||
*/
|
||||
|
||||
// 设置上传限制
|
||||
ini_set('upload_max_filesize', '0');
|
||||
ini_set('post_max_size', '0');
|
||||
ini_set('max_execution_time', '0');
|
||||
ini_set('memory_limit', '-1');
|
||||
|
||||
// 获取当前目录
|
||||
$currentDir = __DIR__;
|
||||
$gitDir = $currentDir . '/.git';
|
||||
$remoteConfigFile = $currentDir . '/.git_remote_config.json';
|
||||
|
||||
// 检查Git仓库是否存在
|
||||
function checkGitRepo() {
|
||||
global $gitDir;
|
||||
return is_dir($gitDir);
|
||||
}
|
||||
|
||||
// 初始化Git仓库
|
||||
function initGitRepo() {
|
||||
global $currentDir;
|
||||
try {
|
||||
exec('cd "' . $currentDir . '" && git init', $output, $returnCode);
|
||||
return $returnCode === 0;
|
||||
} catch (Exception $e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 获取文件列表
|
||||
function getFileList($dir = '.') {
|
||||
$files = [];
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
|
||||
RecursiveIteratorIterator::SELF_FIRST
|
||||
);
|
||||
|
||||
foreach ($iterator as $file) {
|
||||
if ($file->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;
|
||||
}
|
||||
|
||||
?>
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Git文件上传工具</title>
|
||||
<link rel="stylesheet" href="css/style.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<header>
|
||||
<h1>Git文件上传工具</h1>
|
||||
<div class="git-status" id="gitStatus">
|
||||
<span class="status-indicator" id="gitIndicator"></span>
|
||||
<span id="gitStatusText">检查Git状态...</span>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<!-- 文件上传区域 -->
|
||||
<section class="upload-section">
|
||||
<h2>文件上传</h2>
|
||||
<div class="upload-area" id="uploadArea">
|
||||
<div class="upload-placeholder">
|
||||
<svg class="upload-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/>
|
||||
</svg>
|
||||
<p>拖拽文件到此处或点击选择文件</p>
|
||||
<p class="upload-hint">支持任意大小的文件,无数量限制</p>
|
||||
</div>
|
||||
<input type="file" id="fileInput" multiple style="display: none;">
|
||||
</div>
|
||||
<div class="uploaded-files" id="uploadedFiles"></div>
|
||||
</section>
|
||||
|
||||
<!-- 文件列表 -->
|
||||
<section class="files-section">
|
||||
<h2>项目文件</h2>
|
||||
<div class="file-controls">
|
||||
<button id="refreshFiles" class="btn btn-secondary">刷新文件列表</button>
|
||||
<button id="selectAllFiles" class="btn btn-secondary">全选</button>
|
||||
<button id="deselectAllFiles" class="btn btn-secondary">取消全选</button>
|
||||
</div>
|
||||
<div class="file-list" id="fileList">
|
||||
<div class="loading">加载文件中...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Git操作区域 -->
|
||||
<section class="git-section">
|
||||
<h2>Git操作</h2>
|
||||
|
||||
<!-- 分支管理 -->
|
||||
<div class="branch-config">
|
||||
<h3>分支管理</h3>
|
||||
<div class="form-group">
|
||||
<label for="branchSelect">当前分支:</label>
|
||||
<select id="branchSelect" class="form-control">
|
||||
<option value="">加载分支中...</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="newBranchName">新分支名称:</label>
|
||||
<input type="text" id="newBranchName" placeholder="输入新分支名称">
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<button id="createBranch" class="btn btn-success">创建分支</button>
|
||||
<button id="switchBranch" class="btn btn-primary">切换分支</button>
|
||||
<button id="deleteBranch" class="btn btn-danger">删除分支</button>
|
||||
<button id="refreshBranches" class="btn btn-secondary">刷新分支</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr style="margin: 20px 0;">
|
||||
|
||||
<!-- 远程仓库配置 -->
|
||||
<div class="remote-config">
|
||||
<h3>远程仓库配置</h3>
|
||||
<div class="form-group">
|
||||
<label for="remoteName">远程仓库名称:</label>
|
||||
<input type="text" id="remoteName" placeholder="例如: origin" value="origin">
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="remoteUrl">仓库地址:</label>
|
||||
<input type="text" id="remoteUrl" placeholder="例如: https://github.com/username/repo.git">
|
||||
</div>
|
||||
<button id="addRemote" class="btn btn-info">添加远程仓库</button>
|
||||
<button id="showRemotes" class="btn btn-secondary">查看远程仓库</button>
|
||||
|
||||
<div class="remote-list" id="remoteList"></div>
|
||||
</div>
|
||||
|
||||
<hr style="margin: 20px 0;">
|
||||
|
||||
<div class="git-controls">
|
||||
<div class="form-group">
|
||||
<label for="commitMessage">提交信息:</label>
|
||||
<input type="text" id="commitMessage" placeholder="输入提交信息..." value="自动提交">
|
||||
</div>
|
||||
<div class="button-group">
|
||||
<button id="gitAdd" class="btn btn-primary">添加到暂存区</button>
|
||||
<button id="gitCommit" class="btn btn-success">提交更改</button>
|
||||
<button id="gitPush" class="btn btn-warning">推送到远程</button>
|
||||
<button id="gitStatusBtn" class="btn btn-info">查看状态</button>
|
||||
<button id="gitLog" class="btn btn-secondary">查看日志</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="git-output" id="gitOutput"></div>
|
||||
</section>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
<script src="js/main.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user