node实现比较git两个不同分支的组件差异(新增、删除、更新)及获取组件版本号,踩坑之旅!!!

news/2024/7/10 20:41:33 标签: git, 数据库, 开源

引言

大家好,我是学习了吗,我给大家分享使用node比较git分支差异和踩坑过程中的解决思路,希望大家在类似的需求上面可以迎刃而解和帮助到大家

git_4">如何在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_106">git restore获取其他分支内容

git restore -s [branch] -- [path]

执行完这个命令之后,此时在当前分支下,path下的文件的还没有处于「暂存」(staged)状态。
该分支下已经有已修改的状态,需求我们获取完版本号后重置更改,也是该命令行

  1. 当前分支没有path下的组件文件夹和文件名,需要创建
  2. 创建文件夹后,使用restore重置更改,报错
  3. 使用fs.unlink删除文件夹,告诉我没有权限
  4. 既然fs.unlink不行,那我就直接删除我创建的文件夹,使用rmdir,本以为也会删除该文件夹下的文件名,抱歉,是我想多了,必须删除完该文件夹下的所有文件才能删除

问题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;
          }
        }
      }
    }


http://www.niftyadmin.cn/n/5442228.html

相关文章

全量知识系统“全基因序列”程序构想及SmartChat的回复

感觉上&#xff0c;全量知识系统的程序起点基本确定。下一步就是程序了。程序的整个设计过程都准备同时使用两个AI工具。以下是和“百度AI”同步进行的Q&A。 Q1. 基本假设&#xff1a;“全基因序列”中“基因”的本质是联结collection。 做法是&#xff1a; 对给出的一个…

MySql实战--深入浅出索引(上)

提到数据库索引&#xff0c;我想你并不陌生&#xff0c;在日常工作中会经常接触到。比如某一个SQL查询比较慢&#xff0c;分析完原因之后&#xff0c;你可能就会说“给某个字段加个索引吧”之类的解决方案。但到底什么是索引&#xff0c;索引又是如何工作的呢&#xff1f;今天就…

深度学习pytorch——高阶OP(where gather)(持续更新)

where 1、我们为什么需要where&#xff1f; 我们经常需要一个数据来自好几个的取值&#xff0c;而这些取值通常是不规律的&#xff0c;这就会导致使用传统的拆分和合并会非常的麻烦。我们也可以使用for循环嵌套来取值&#xff0c;也是可以的&#xff0c;但是使用for循环就意味…

SpringCloud-Nacos配置管理

在nacos中添加配置文件 如何在nacos中管理配置呢&#xff1f; 然后在弹出的表单中&#xff0c;填写配置信息&#xff1a;如&#xff1a;userservice-dev.yaml 注意&#xff1a;项目的核心配置&#xff0c;需要热更新的配置才有放到nacos管理的必要。基本不会变更的一些配置…

Alias许可与软件升级

在当今快速发展的科技时代&#xff0c;软件升级已成为企业持续发展的重要驱动力。然而&#xff0c;企业在享受软件升级带来的技术优势时&#xff0c;也面临着许可管理的挑战。如何确保软件升级与许可的合规性&#xff0c;降低潜在风险&#xff0c;是许多企业关注的焦点。Alias许…

javaSE习题

javaSE课后练习 1.BMI是根据体重测量健康的方式。通过以千克为单位的体重除以以米为单位的身高的平方计算出BMI。下面是16 岁以上人群的BMI图表: 编写一个程序&#xff0c;提示用户输人以磅为单位的体重和以英寸为单位的身高&#xff0c;然后显示BMI值。注意: 1磅是0.453592 3…

GAT精译 - 1

2 GAT ARCHITECTURE 我们将描述一个单独的图注意力层&#xff0c;因为单层在我们实验中GAT架构。我们使用这个特殊的注意力是follow Bahdanau et al 2015的工作。 我们层的输入是节点的特征&#xff0c;&#xff0c;,N是节点的数量&#xff0c;F是每一个节点的特征数量。这个层…

Java小项目--满汉楼

Java小项目–满汉楼 项目需求 项目实现 1.实现对工具包的编写 先创建libs包完成对jar包的拷贝和添加入库 德鲁伊工具包 package com.wantian.mhl.utils;import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.io.FileInputStream…