赞
踩
大家好,我是学习了吗,我给大家分享使用node比较git分支差异和踩坑过程中的解决思路,希望大家在类似的需求上面可以迎刃而解和帮助到大家
查看git方法是否有比较两个分支差异的方法
git diff [<options>] <commit>…<commit> [--] [<path>…]
问题:如何在node中执行该命令行
node内置库child_process
child_process中有个方法可以执行命令行
child_process.spawn()
const spawn = require("child_process").spawn;
const ret = await spawn('git', ['diff', '1.0.1.4', '1.0.1.5', '--stat'], {
cwd: process.cwd(),
stdio: "inherit",
});
child_process.exec()
const cmdStr = `git diff 1.0.1.4 1.0.1.5 --stat`;
const exec = require("child_process").execSync;
const ret = exec(cmdStr)
stat参数的作用是,只获取文件的变化,不会具体到文件中内容的差异
不同的项目中目录不同,实现原理是使用正则匹配对应路径中是组件的名称,并使用数组存储起来
有些项目可以是把不同类型的组件放在一个文件下形成组件库,只需要比较组件库的变更就行,同理,使用正则匹配对应的组件库,但是有一种情况需要考虑,使用diff获取的路径中不存在组件库名称,需要我们反解析
数据格式
{组件库: [组件,组件]}
技术glob库
require("glob")(`${paths}/*`, (err, files) => { // 存储对象 let pkgNameObj = {}; // 使用glob返回的paths路径下的第一层文件,为组件库 files.forEach((item) => { // 获取组件库名生成新链接 let pkgName = getPkgName(item)[0]; let nowPath = path.resolve(paths, pkgName + "\\components"); pkgNameObj[pkgName] = []; let nowfiles = require("glob").sync(`${nowPath}/*`); //遍历对应组件库的组件 nowfiles.forEach((nowItem) => { let cmpName = getCmpName(nowItem)[0]; pkgNameObj[pkgName].push(cmpName); }); resolve(pkgNameObj); }); });
通过diff获取的路径,通过正则拿不到组件库名称,但是获取的到组件名,通过上一步骤得到的组件库与组件的映射关系来获取组件库名
注意
不同的分支下相同的组件可能修改了不同地方,通过diff获取的路径可能有相同的组件名,需要去重
思路
使用上面所说的child_process执行切换分支命令行
这个方法比较简单不细说了
注意
如果当前分支有代码未提交,通过命令行切换分支会报错,提示有修改的内容未提交不能切换
思路
git restore -s [branch] -- [path]
执行完这个命令之后,此时在当前分支下,path下的文件的还没有处于「暂存」(staged)状态。
该分支下已经有已修改的状态,需求我们获取完版本号后重置更改,也是该命令行
坑
问题2 出现的原因
当发现当前分支没有其他分支的文件夹时,在当前分支创建,但是获取第二个分支的当前文件夹时,执行命令行git restore拿不到文件会直接报错
代码
function openCommand(command) { var exec = require("child_process").execSync; return exec(command); } function delFile(path, reservePath) { if (fs.existsSync(path)) { if (fs.statSync(path).isDirectory()) { let files = fs.readdirSync(path); files.forEach((file, index) => { let currentPath = path + "/" + file; if (fs.statSync(currentPath).isDirectory()) { delFile(currentPath, reservePath); } else { fs.unlinkSync(currentPath); } }); if (path != reservePath) { fs.rmdirSync(path); } } else { fs.unlinkSync(path); } } } // 写在一个类中,其中this指向实例 let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`); if (pathExists(paths)) { let nowData; // 问题2 需要try catch捕获 这种情况是传参第二个参数没有对应的组件库 try { await this.openCommand(`git restore -s ${branch} -- uicomponents/src/componentlibs/${item}/libSetting.json`); nowData = fs.readFileSync(path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`)); // 直接还原文件夹更改 // 问题:当前分支没有该文件夹会直接报错 if (this.createDirPath[item]) { // 不能直接删除文件夹,必须先删除文件夹中对应的文件然后才能删除 this.delFile(this.createDirPath[item]); } else { await this.openCommand(`git restore uicomponents/src/componentlibs/${item}/libSetting.json`); } } catch (e) { // 首先判断的第一个分支有代码库,本分支创建了文件夹,获取第二个分支没有该代码库,就会报错 // 所以在这里也要删除新建的文件夹 if (this.createDirPath[item]) { // 不能直接删除文件夹,必须先删除文件夹中对应的文件然后才能删除 this.delFile(this.createDirPath[item]); } console.log(`当前分支${branch}没有代码库${item}`); } return nowData && JSON.parse(nowData.toString()).version; } else { // 如果不创建文件夹的话,在当前分支没有该代码块,获取其他分支代码块,会报错找不到该文件夹,如果用try catch 就比较不了两个分支的版本差异,直接undefined let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}`); let createOk = this.createDir(paths); // 这样存储目录的目的是,可能新的分支创建了多个代码块,所以使用对象存储代码库的名称和对应的目录地址,方便删除 createOk && (this.createDirPath[item] = paths); if (createOk) { let paths = path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`); fs.writeFileSync(paths, "{}"); if (pathExists(paths)) { // 比较的两个分支有新建代码库,但是某个分支没有该代码库,但是已经新建了文件夹 // 当前分支获取其他其他分支的当前文件时拿不到路径会直接报错 // 这种情况是传参的第一个分支中没有对应的组件库 try { await this.openCommand(`git restore -s ${branch} -- uicomponents/src/componentlibs/${item}/libSetting.json`); let nowData = fs.readFileSync(path.resolve(process.cwd(), `uicomponents/src/componentlibs/${item}/libSetting.json`)); // await this.openCommand(`git restore uicomponents/src/componentlibs/${item}/libSetting.json`); return JSON.parse(nowData.toString()).version; } catch (e) { return undefined; } } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。