利用 PHP 导出 Git 某个分支下,新增或修改过的文件

使用 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);
}

 

posted @ 2017-03-23 11:04  52php  阅读(722)  评论(0编辑  收藏  举报