使用 SVN 作为版本控制的时候,整理过一个 导出文件脚本:利用 PHP 导出 SVN 新增或修改过的文件
现在换成了 Git,整理出类似的脚本:
【第一版】git.php
<?php /** * 导出指定版本之间的差异文件,如 100 和 200 之间的差异则导出 100(不包括) - 200(包括) 的所有修改 * 【Git 命令行】 * 1、查看版本间差异 * git diff b361dbd323dbfc442ddbdc43b00cba3e66c50214 988526fa12dfcbddc2462e232eae7f614ff28976 --name-status * * @example git.php old版本号 new版本号 * @author phpgo.cnblogs.com */ // 根目录 define('SITE_PATH', '/Users/jianbao/123'); // Git 工作区 define('GIT_WORK_PATH', '/Users/jianbao/PhpStormProjects/fiisoo/git_sjf_web'); // 项目路径前缀 $prefix = 'sjf_'; $error_msg = "You must useage like {$_SERVER['argv'][0]} old_version(不包括) new_version(包括)\n"; if ($_SERVER['argc'] != 3) { echo $error_msg; exit(1); } $old_version = $_SERVER['argv'][1]; $new_version = $_SERVER['argv'][2]; //$export_path = SITE_PATH . "/${prefix}${old_version}_${new_version}"; $export_path = SITE_PATH . "/${prefix}" . date('H:i:s'); // 切换至 Git 工作区 chdir(GIT_WORK_PATH); echo "开始分析版本差异...\n"; $diff_cmd = "git diff ${old_version} ${new_version} --name-status"; exec($diff_cmd, $diff_list, $return); $diff_list = (array)$diff_list; foreach ($diff_list as $diff_info) { echo $diff_info . "\n"; } // 清空旧数据 @system('rm -rf ' . SITE_PATH . "/${prefix}*"); // 新建文件夹 dir_mkdir($export_path); $diff_count = count($diff_list); if ($diff_count < 1) { echo "版本间没有差异\n"; exit(1); } $diff_count = 0; // 导出版本差异文件 echo "开始导出...\n"; foreach ($diff_list as $diff_info) { if (preg_match('/([\w]+)\s+(.+)/', $diff_info, $matches)) { $git_file_mode = $matches[1]; $git_file_name = $matches[2]; // A、M、D、AM(即增加且修改) // 文件被删除 if ($git_file_mode == 'D') { continue; } $diff_count++; // 复制到导出目录 $from_file_path = GIT_WORK_PATH . '/' . $git_file_name; $to_file_path = $export_path . '/' . $git_file_name; $to_file_dir = dirname($to_file_path); dir_mkdir($to_file_dir); copy($from_file_path, $to_file_path); } } echo "共导出${diff_count}个差异文件\n"; exit(0); /** * 创建文件夹 * * @param string $path 文件夹路径 * @param int $mode 访问权限 * @param bool $recursive 是否递归创建 * @return bool */ function dir_mkdir($path = '', $mode = 0777, $recursive = true) { clearstatcache(); if (!is_dir($path)) { mkdir($path, $mode, $recursive); return chmod($path, $mode); } return true; } /** * 写文件 * * @param string $filename 文件名 * @param string $text 要写入的文本字符串 * @param string $openmod 文本写入模式('w':覆盖重写,'a':文本追加) * @return bool */ function file_write($filename = '', $text = '', $openmod = 'w') { if (@$fp = fopen($filename, $openmod)) { flock($fp, 2); fwrite($fp, $text); fclose($fp); return true; } else { return false; } } /** *【本地调试用】写对象(包括 数字、字符串、数组) * * @param string $text 要写入的文本字符串 * @param string $type 文本写入类型('w':覆盖重写,'a':文本追加) * @return bool */ function write2($text, $type = 'a') { $filename = SITE_PATH . '/write2.txt'; $text = "\n++++++++++++++++++++++++++++++++++++++++++\n" . date('Y-m-d H:i:s') . "\n" . print_r($text, true); return file_write($filename, $text, $type); }
【第二版】git_sjf_mas.php
<?php /** * 导出 某个分支(如:master/develop) 下,指定版本之间的差异文件, * 如 100 和 200 之间的差异则导出 100(不包括) - 200(包括) 的所有修改 * * @example git_sjf_mas.php old版本号 new版本号 * @author phpgo.cnblogs.com */ // 检查参数 $errorMsg = "【出错】You must useage like {$_SERVER['argv'][0]} old_version(不包括) new_version(包括)\n"; if ($_SERVER['argc'] != 3) { echo $errorMsg; exit(1); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 项目路径 $projectUrl = 'git@git.cnblogs.com:phpgo/sjf_web.git'; // 分支名 $branchName = 'master'; // 开发分支 改为 develop // 本地项目名 $projectName = 'git_sjf_mas'; // 开发分支 改为 git_sjf_dev // 输出路径 $exportPath = '/Users/jianbao/123'; // Git 工作区 $gitWorkPath = '/Users/jianbao/1/projects'; //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ $subGitWorkPath = $gitWorkPath . "/${projectName}"; // 克隆 远程 develop 分支 if (!is_dir($subGitWorkPath)) { // 切换至 Git 工作区 chdir($gitWorkPath); // 克隆 分支 system("git clone ${projectUrl} --branch ${branchName} ${subGitWorkPath}"); // 新建本地分支 develop chdir($subGitWorkPath); system("git branch ${branchName}"); } else { chdir($subGitWorkPath); } // 切换分支 develop system("git checkout ${branchName}"); // 更新分支 system("git pull origin ${branchName}"); $oldVersion = $_SERVER['argv'][1]; $newVersion = $_SERVER['argv'][2]; // 检查 版本号 $oldVersionCmd = "git log --pretty='%h' -1 ${oldVersion}"; $newVersionCmd = "git log --pretty='%h' -1 ${newVersion}"; $ret = 0; system($oldVersionCmd, $ret); if ($ret !== 0) { echo "【出错】版本号 ${oldVersion} 不存在\n"; exit(1); } system($newVersionCmd, $ret); if ($ret !== 0) { echo "【出错】版本号 ${newVersion} 不存在\n"; exit(1); } // 输出路径 $subExportPath = $exportPath . "/${projectName}_" . date('H:i:s'); echo "开始分析版本差异...\n"; $diffCmd = "git diff --name-status ${oldVersion} ${newVersion}"; exec($diffCmd, $diffList, $return); $diffList = (array)$diffList; foreach ($diffList as $diffInfo) { echo $diffInfo . "\n"; } // 清空旧数据 //@system('DELTREE ' . $exportPath . "/${projectName}*"); $dh = opendir($exportPath); while ($file = readdir($dh)) { if ($file != "." && $file != "..") { $fullpath = $exportPath . "/" . $file; if (is_dir($fullpath) && (strpos($file, $projectName) !== false)) { dir_rmdir($fullpath); } } } closedir($dh); // 新建文件夹 dir_mkdir($subExportPath); $diffCount = count($diffList); if ($diffCount < 1) { echo "版本间没有差异\n"; exit(1); } $diffCount = 0; // 导出版本差异文件 echo "开始导出...\n"; foreach ($diffList as $diffInfo) { if (preg_match('/([\w]+)\s+(.+)/', $diffInfo, $matches)) { $gitFileMode = $matches[1]; $gitFileName = $matches[2]; // A、M、D、AM(即增加且修改) // 文件被删除 if ($gitFileMode == 'D') { continue; } $diffCount++; // 复制到导出目录 $fromFilePath = $subGitWorkPath . '/' . $gitFileName; $toFilePath = $subExportPath . '/' . $gitFileName; $toFileDir = dirname($toFilePath); dir_mkdir($toFileDir); copy($fromFilePath, $toFilePath); } } echo "共导出 ${diffCount} 个差异文件\n"; exit(0); //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** * 创建文件夹 * * @param string $path 文件夹路径 * @param int $mode 访问权限 * @param bool $recursive 是否递归创建 * @return bool */ function dir_mkdir($path = '', $mode = 0777, $recursive = true) { clearstatcache(); if (!is_dir($path)) { mkdir($path, $mode, $recursive); return chmod($path, $mode); } return true; } /** * 清空/删除 文件夹 * * @param string $dir 文件夹路径 * @param bool $self 是否删除自己 * @return bool */ function dir_rmdir($dir, $self = true) { $dh = opendir($dir); while ($file = readdir($dh)) { if ($file != "." && $file != "..") { $fullpath = $dir . "/" . $file; if (!is_dir($fullpath)) { unlink($fullpath); } else { dir_rmdir($fullpath); } } } closedir($dh); if ($self&& rmdir($dir)) { return true; } else { return false; } } /** * 写文件 * * @param string $filename 文件名 * @param string $text 要写入的文本字符串 * @param string $openmod 文本写入模式('w':覆盖重写,'a':文本追加) * @return bool */ function file_write($filename = '', $text = '', $openmod = 'w') { if (@$fp = fopen($filename, $openmod)) { flock($fp, 2); fwrite($fp, $text); fclose($fp); return true; } else { return false; } } /** *【本地调试用】写对象(包括 数字、字符串、数组) * * @param string $text 要写入的文本字符串 * @param string $type 文本写入类型('w':覆盖重写,'a':文本追加) * @return bool */ function write2($text, $type = 'a') { $filename = $GLOBALS['exportPath'] . '/write2.txt'; $text = "\n++++++++++++++++++++++++++++++++++++++++++\n" . date('Y-m-d H:i:s') . "\n" . print_r($text, true); return file_write($filename, $text, $type); }