version-control: node下的版本管理模块(svn & git)

MacOS IDEA集成SVN全攻略:环境配置、日常操作与避坑指南 版本控制系统是软件开发中管理代码变更的核心工具,其中SVN(Subversion)作为集中式版本控制的代表,以其清晰的权限管理和目录结构,在企业级项目开发中仍有广泛应用。其工作原理是通过中央服务器存储所有版本历史,开发者通过客户端进行代码的检出、更新和提交。对于使用IntelliJ IDEA进行开发的Mac用户而言,在macOS系统上高效整合IDEA与SVN客户端,能直接提升传统版本控制场景下的开发体验与工程效率。这涉及到环境准备、组件选型与IDE配置等多个环节,例如通过Homebrew包管理器安装SVN客 阅读详情

最近在开发一个构建工具,需要操作版本管理系统,实现代码提交(如:svn add, svn commit…),GitHub上有类似的库,但存在两个问题:

  1. 长久没人维护,使用人数较少;
  2. 只支持git或svn;

基于我需要兼容git和svn,于是自己简单实现一个版本管理模块:version-control,下面将简单记录一下设计中的一些考虑和遇到的一些问题。

由于开发时间有限和本人使用场景较为简单,若你想使用version-control,请先自行评估是否能满足你的需求,当然作为开源项目,欢迎提issue,发PR。

目录

  1. 【思路】node下的版本管理模块实现;
  2. 【思路】 如何优雅兼容svn和git操作;
  3. 【问题】中文显示的问题;
  4. 【问题】svn本地版本和线上服务器版本不一致问题;
  5. 【问题】svn 如何add所有文件;
  6. 【问题】svn log没有显示刚刚commit的信息;
  7. 【TODO】

一、node下的版本管理模块实现思路

回想我们在没有GUI版本管理工具的时候是怎么进行版本操作的:敲命令行,于是自然想到实现思路:基于node执行指定命令行来实现版本操作。

这里要注意的是,Windows下在命令行中不一定有git或者svn的执行环境,需要安装额外的安装包,由于Mac OS暂时没有这个问题,所以我还没有做处理。

// node执行命令
const child_process = require('child_process');

module.exports = (command, cwd) => new Promise((resolve, reject) => {
  child_process.exec(command, { cwd }, (err, stdout) => {
    if (err) reject(err);
    else resolve(stdout);
  });
});

二、如何优雅兼容svn和git操作

凡是说到兼容,我就会想到抽象,站在用户的角度,要完成的任务是版本管理,并不太在意具体用哪些命令。于是我从svn和git操作中跳脱出来,只关心用户需要,针对用户需要,梳理出以下几个接口:

  1. 查看当前文件修改状态:VersionControl.status
  2. 更新代码:VersionControl.update
  3. 提交代码:VersionControl.commit
  4. 版本回退:VersionControl.revert

确定了抽象接口之后,我采用动态引入的方式兼容svn和git,并在架构上进行作用域隔离,单独维护svn操作逻辑和git操作逻辑:

VersionControl在实例化的时候判断用户需要svn还是git,根据用户需要引入底层实现,最后在对外接口中调用具体的底层实现来实现svn和git兼容。

/**
 * VersionControl
 * @TODO 实现Git状态管理
 */
class VersionControl {
  constructor(versionControlSystemType) {
    if (versionControlSystemType && !['svn', 'git'].contains(versionControlSystemType)) throw new Error('Only git or svn can be pass in.');
    this.type = versionControlSystemType || 'svn';
    // vsc = versionControlSystem
    /* eslint global-require: "off" */
    this.vcs = this.type === 'svn' ? require('./svn') : require('./git');
  }

  status(codePath) {
    return this.vcs.status(codePath);
  }

  update(codePath) {
    return this.vcs.update(codePath);
  }

  commit(codePath, commitMsg) {
    return this.vcs.commit(codePath, commitMsg);
  }

  log(codePath) {
    return this.vcs.log(codePath);
  }

  revert(codePath, commitMsg, version) {
    return this.vcs.revert(codePath, commitMsg, version);
  }
}

module.exports = VersionControl;

三、中文显示的问题

在执行svn commit -m '中文'时,在某些node环境下(例如electron编译后的安装包中)会报错:

svn: Can't convert string from 'UTF-8' to native encoding

经过构建前后差异分析定位,我发现,electron构建前后执行时,node的环境不一样(具体环境参数可以通过process.env获取,更多详情请参考:node.js文档 - process.env)。具体原因在于:编码格式不一样。

解决方案:将node执行环境中的语言改成UTF8:process.env.LANG = 'zh_CN.UTF-8';

四、svn本地版本和线上服务器版本不一致问题

在执行svn操作是,报错:svn: E155036: Please see the 'svn upgrade' command; svn: E155036: The working copy at 'xxx',意思是本地svn和服务器svn版本不一致,需要更新,此时执行svn upgrade即可,但需要注意的是,svn upgrade只能在svn根目录中执行,不然会报另外一个错误,于是我们需要在上面的报错信息中解析出svn root,也就是上面说的working copy。

部分代码如下,有很大的优化空间,例如这个错误处理逻辑,应该抽离出来当成通用的错误处理逻辑(因为所有的svn操作都有可能会报这个错误)。

static async status(codePath) {
  const command = 'svn status';
  let statusData = [];
  await exec(command, codePath)
    .then((data) => {
      statusData = parseStatus(data);
    })
    .catch(async (error) => {
      const { message } = error;
      // 处理svn upgrade提示:在svn根目录(Working Copy Root Path)执行svn upgrade
      // @NOTE 错误提示
      // svn: E155036: Please see the 'svn upgrade' command
      // svn: E155036: The working copy at 'xxx'
      if (message.indexOf('svn upgrade') !== -1) {
        const SVN_ROOT_REG = /The working copy at '(.*)'/;
        const svnRoot = SVN_ROOT_REG.exec(message)['1'];
        await this.upgrade(svnRoot);
        return this.status(codePath);
      }
      return statusData;
    });
  return statusData;
}

五、svn 如何add所有文件

我在svn文档中没有找到类似git add --all的命令,于是在stackoverflow中找到了解决方法:

svn add --force * --auto-props --parents --depth infinity -q

刚开始在本地测试的时候测试通过,后台构建工具发布后,同事反馈commit的时候耗时很长(一分钟),于是我开始了问题定位之旅:

  1. 理论分析svn commit慢的因素(①传输内容多 ②svn仓库大 ③svn add all耗时长);
  2. 打点分析;
  3. 得出结论,svn add all耗时长,占总commit耗时的90%以上;

从上面命令的参数可以看到,执行这个命令会去深度遍历指定路径下的所有目录,导致耗时过长。

这其实是一个全量操作和增量操作的问题,全量操作方便,但耗费性能,增量操作繁琐,但性能优越。于是在全量操作遇到问题后,我只好自己手动实现svn add all:

  1. svn status:分析当前的文件修改;
  2. svn add xxx:对每一个修改进行svn add;(如果是资源删除,则是svn delete);
static async addAll(codePath) {
  const statusData = await this.status(codePath);
  for (let i = 0; i < statusData.length; i += 1) {
    const { rawType, path } = statusData[i];
    /* eslint default-case: "off" */
    /* eslint no-await-in-loop: "off" */
    switch (rawType) {
      case '?':
        // svn add xxx
        await this.add(codePath, path);
        break;
      case '!':
        // svn delete xxx
        await this.delete(codePath, path);
        break;
    }
  }

六、svn log没有显示刚刚commit的信息;

在使用svn commit之后,执行svn log并没有看到刚刚提交的记录,查阅资料发现,需要在commit后执行svn update才会看到记录,这属于svn的特性吧,简单记录一下。

TODO

上面只是提到一些实现思路和解决的一些问题,细节欢迎大家阅读version-control源码。此外大家会发现里面有许多不完善的地方,但目前已经能满足我的需求,后续随着需求的变更,我也继续更新,也欢迎大家issue,pr走起。下面是一些要做的事情:

  1. 支持git;
  2. 发布npm包;
  3. 跨平台兼容性处理;

博客写得比较简单,更像是工作笔记。有一段时间没有写博客了,因为**陷入了一个怪圈,觉得小的东西没必要写,大的东西又还没有成果不好写。**好在同事建议说:“就当做工作笔记好了,不用太认真”。想想也是,起码一直在记录,也能促进自己沉淀。

SVN新手实操指南:从Checkout到冲突处理快速上手版本控制 版本控制是团队协作的基石,集中式与分布式模型各有其适用场景。SVN(Apache Subversion)作为经典的集中式版本控制系统,凭借清晰的权限管理、稳定的目录控制和较低的操作门槛,在传统软件企业、外包团队及非研发岗位中仍被广泛采用。理解中央仓库与本地工作副本的协作原理,是使用SVN的第一步。日常开发中,Checkout、Update、Commit 构成了最基本的工作闭环,掌握这些操作即可融入团队流程。当多人修改同一文件时,冲突不可避免,掌握冲突处理机制能有效保护代码完整性。此外,分支合并、标签快照以及 阅读详情

相关推荐

Git分支本质:轻量指针与协作时空管理

Git分支是软件工程中实现并行开发与版本演进的基础机制,其核心原理是作为指向某次commit的轻量级可移动指针,而非文件拷贝。这种设计带来毫秒级创建、零磁盘冗余、高频率切换的技术优势,支撑起现代CI/CD流水线与多人协同开发。相比SVN等集中式系统,Git分支的廉价性与可丢弃性,使其天然适配功能驱动(feature branch)、环境隔离(staging/prod)、合规归档(orphan分支)等关键应用场景。本文深入解析git switch、--orphan、merge策略及worktree等高频实践工

weixin_30680385的博客 438

Node-Control 项目使用教程

Node-Control 项目使用教程 1. 项目的目录结构及介绍 Node-Control 项目的目录结构如下: node-control/ ├── example/ │ └── controls.js ├── lib/ │ └── controllers.js ├── tasks/ │ └── deploy.js ├── .gitignore ├── LICENSE ├── REA...

gitblog_01070的博客 497

IntelliJ IDEA Community免费版安装配置教程:从JDK到Tomcat实战

Java开发离不开集成开发环境(IDE),它不仅是编写代码的编辑器,更是项目构建、调试与版本控制的统一平台。对于初学者、学生及中小型后端项目而言,IntelliJ IDEA Community作为JetBrains官方提供的免费IDE,凭借对JDK、Maven、Git等核心工具链的完整支持,成为性价比极高的入门选择。本文从IDE的环境配置原理出发,介绍如何下载安装Community版,完成JDK安装与项目SDK关联,并基于Maven构建项目结构,同时通过Smart Tomcat插件实现Web服务的本地部署。

weixin_34160277的博客 404

nodejs通过http调用实现操作svn

nodejs想操作svn进行list和下载操作,但是不依赖运行环境支持svn命令,可以通过下面的代码实现。

zzchances的博客 438

Pull Request本质:一场结构化技术协作对话

Pull Request(PR)是现代软件开发中基于Git的分布式协作核心机制,其本质并非代码提交动作,而是一套融合上下文说明、变更描述与验证证据的结构化沟通协议。它依托git命令行精准控制、远程repository作为事实源、GitHub平台实现可视化交互,技术价值在于降低协作熵增、提升代码可追溯性与团队认知对齐效率。典型应用场景包括开源贡献、跨职能协同(如PM/设计/测试参与评审)、CI/CD门禁集成及线上问题快速修复。理解PR即理解以人为核心的工程协作语言——这正是GitHub、git、reposit

weixin_30291791的博客 433

从PPT到实战:Git工作流与IDEA集成完全指南

版本控制是软件开发的基础设施,Git作为分布式版本控制系统的核心,通过快照机制和分支模型实现代码的并行开发与历史追溯。掌握Git不仅能提升团队协作效率,还能在代码回退、冲突解决等场景中保障项目稳定性。在IDEA等IDE中集成Git,可进一步简化提交、分支、合并等操作,降低人为错误。对于开发者而言,理解GitFlow等分支模型选型、熟练使用commit、merge、rebase等命令,是日常开发中不可或缺的技能。本文围绕Git安装配置、IDEA集成、分支管理及高频报错排查,提供一套可落地的实践路径。

weixin_33796205的博客 358

如何用Node拿到svn用户信息

目前我们还是用svn进行版本的控制,有时候我们要对一个人的代码进行一些监控,而svn用户名则是最好的用户标记。 那么我们要如何拿到一些svn的信息呢?

myhirra的专栏 2706

Git版本控制实战:从安装配置到IDEA集成与GitFlow工作流

版本控制是软件开发的核心实践,Git作为分布式版本控制系统,通过工作区、暂存区和本地仓库三层结构实现代码变更的精细管理。其原理基于快照存储和分支指针,支持高效的分支创建与合并,技术价值在于提升团队协作效率和代码可追溯性。在应用场景中,开发者常需在IDEA等IDE中集成Git,并遵循GitFlow等分支模型进行功能开发与发布。git安装与git的配置是入门第一步,而掌握git commit --amend、git bisect等命令能有效解决日常开发中的版本管理问题。

weixin_34152820的博客 398

nvm-desktop / nvm下载切换node,命令行显示成功,实际未成功或者报错node不是命令 / nvm下载node没有npm

nvm-desktop 安装注意 使用注意 版本冲突 安装 nvm nvm 后项目版本和下载版本不同 nvm 下载没有npm

全网同名:PBitW,更多内容,可以搜索《普通前端进阶记》 3552

svn-up-by-node:通过 nodejs 更新 svn

svn-up-by-node 通过 nodejs 更新 svn

使用amp训练出现Detected call of lr_scheduler.step() before optimizer.step().

这个警告是怎么产生的?是由于在算梯度的时候出现了nan,所以这一次更新会跳过,但是参数仍旧会更新所以出现了问题,按下面的做法加一个判断就行了。但是在使用amp进行混合精度训练出现的一个warning,调换代码顺序也不work。正常在训练的时候,对于优化器和参数更新的顺序这样就可以了。

weixin_46214675的博客 1306

MacOS IDEA集成SVN全攻略:从环境配置到实战避坑

版本控制系统是软件开发中管理代码变更的核心工具,其原理是通过记录文件的历史版本,实现团队协作与代码回溯。在众多版本控制工具中,SVN(Subversion)作为集中式版本控制系统的代表,因其严格的权限控制和审计能力,在企业级开发中仍有广泛应用。其技术价值在于为传统企业、金融项目等对代码管理有严格要求的场景提供了稳定可靠的解决方案。在实际开发环境中,开发者常需要在MacOS系统上使用IntelliJ IDEA这一主流集成开发环境进行SVN操作,这涉及到环境配置、客户端选型、插件集成等具体实践。本文将围绕SVN

weixin_34221036的博客 331

Matlab实战:用DQN算法让机器人学会自主避障(附完整代码)

本文详细介绍了如何使用Matlab实现DQN(深度Q网络)算法,使机器人在复杂环境中学会自主避障。通过环境建模、网络架构设计、奖励函数优化及实战调试,提供了完整的代码实现和训练策略,帮助开发者快速应用于机器人路径规划项目。

t8u9v0w1x的博客 232

CentOS 7下WordPress版本控制部署实战:Git+SVN+SELinux原子化方案

版本控制是现代Web应用部署的基础能力,其核心在于实现代码状态的可追溯、可回滚与协同管理。在Linux服务器环境中,尤其面向政企级生产系统,版本控制不仅关乎开发效率,更直接影响安全合规、等保审计与故障恢复能力。WordPress作为典型PHP应用,天然存在核心代码与运行时内容(如uploads、cache)混杂的问题,若不加隔离直接纳入Git或SVN,极易引发文件覆盖、权限冲突与SELinux拒绝访问等‘幽灵问题’。本文聚焦CentOS 7这一广泛使用的长期支持发行版,深入解析如何通过符号链接分离只读核心、

weixin_30258901的博客 436

matplotlib三维画图之观察博弈论混合策略下纳什均衡点

参考链接: 博弈论入门20讲之第16讲-猜谜游戏-散户如何赢庄家 游戏背景: 我的期望是: 你的期望是: 使用Python的matplotlib画图: import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D fig = plt.figure() ax = Axes3D(fig) X = np.linspace(0, 1, 100) Y = np.linspace(0, 1,

敲代码的小风 1258

别再傻傻分不清!5分钟搞懂倾斜摄影里‘地面分辨率’和‘模型精度’到底啥关系

本文深入解析倾斜摄影中‘地面分辨率’与‘模型精度’的关系,帮助读者快速理解两者的本质区别与内在关联。通过实战案例和公式计算,详细说明如何从航飞设计到精度验证全流程控制,避免常见认知误区,并针对不同应用场景提供精度需求建议。

weixin_33700350的博客 476

git 教程、常用命令

git 教程、常用命令

freeking101的博客 6626

SpringBoot 中 @RequestMapping 及衍生注解的全面解析与实践

本文全面解析Spring Boot中@RequestMapping及其衍生注解的使用,涵盖核心功能、HTTP方法特定注解(@GetMapping/@PostMapping等)、属性详解(路径/参数/头信息等)以及路径变量处理。文章详细介绍了注解的组合使用、继承特性、版本控制策略等高级应用,并针对405/404等常见错误提供解决方案。通过学习这些注解的规范用法,开发者能够构建符合RESTful风格的API接口,提升代码可读性和可维护性。建议优先使用HTTP方法特定注解,合理规划URL结构,并注意避免路径冲突。

Java&AI小吕布的博客 2037

Windows Git 安装配置完全指南:从下载到高频命令与报错排查

版本控制是软件开发中协作与历史追踪的基石,而 Git 作为分布式版本控制系统的代表,其记录每次变更、支持分支并行开发以及本地化操作的特点,使其在多种场景下成为团队协作的基础设施。在 Windows 环境下,正确安装与配置 Git 是开启高效工作流的第一步,涉及安装包下载、路径与环境变量设置、换行符处理、SSH 密钥生成等关键环节。理解 Git 的工作区、暂存区与版本库原理,掌握 commit、push、pull 等高频命令,能有效应对日常开发中的版本管理需求。同时,常见报错如仓库识别失败、认证失败或乱码等问

weixin_34050005的博客 402

【项目实战】分布式日志系统 之 Exactly-once 语义:确保数据处理的精确性

在分布式系统的数据传输与处理中,是一种核心可靠性保障,其目标是确保数据“仅被处理一次”——既不重复(避免多次处理),也不遗漏(避免未处理)。与,二者共同保障数据处理的精确性。Exactly-once 语义是分布式系统中数据可靠性的高级目标,其核心通过“幂等设计”(解决重复问题)和“分布式事务”(解决原子性问题)实现。在实际应用中,常结合 At-Least-Once 语义与幂等性,或通过事务 API 与唯一 ID 去重的组合,平衡可靠性与系统性能。

奶爸的编程之路,也就一周冷个三天 166

Android Audio录音——AudioRecord回声消除(九)

在语音通话或录音场景中,回声(Acoustic Echo)通常是指说话的声音从对方的扬声器播放出来,又被对方的麦克风拾取,然后有被传回来,导致我们听到了自己延迟了一段时间的重复声音。

小旭的专栏 1403

记录前端内网开发

记录前端内网开发 目录 正篇: 一、nvm 二、Node 三、npm 四、Git 五、VSCode 中篇: 一、package.json 1、catalog、workspace 2、npm i 报错 3、pnpm ⭐️ 3-1、pnpm 清理缓存命令 3-2、pnpm install 报错 3-3、pnpm run build 报错 二、pack-lock.json 三、Git 相关问题

Mr.小灰狼_随笔 591

SAP DRC 是什么?一文读懂 SAP Document and Reporting Compliance 的定位、架构与落地案例

把视线拉长,会发现SAP DRC的价值并不仅是用来交差的工具。它更像是企业在全球化经营中建设的一套公共底座:既能以最低的重复成本去应对各国不断演进的监管要求,也能为财务数字化与供应链协同提供可信数据回路。依托本地与云的分层职责、与的生态联动、以及按国家不断更新的任务目录,企业可以将合规变成一种标准化、工程化、可持续运营的能力。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1650

Git - 安装和使用

GitLab 是由 GitLabInc.开发,使用 MIT 许可证的基于网络的 Git 仓库管理工具,且具有wiki 和 issue 跟踪功能。使用 Git 作为代码管理工具,并在此基础上搭建起来的 web 服务。GitLab 由乌克兰程序员 DmitriyZaporozhets 和 ValerySizov 开发,它使用 Ruby 语言写成。后来,一些部分用 Go 语言重写。截止 2018 年 5 月,该公司约有 290 名团队成员,以及 2000 多名开源贡献者。

Hvitur的博客 679

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

Git分支管理实战:从模型设计到合并冲突与工具操作

版本控制是现代软件开发的基石,而Git分支则是团队协作中最核心也最易出错的环节。分支本质上只是一个指向提交对象的指针,创建成本极低,但若缺乏统一规范,多人协作时分支命名混乱、合并冲突频发、远程仓库堆积无用引用等问题便会接踵而至。理解Git Flow、GitHub Flow等主流分支模型的适用场景,是设计高效协作流程的前提;掌握merge与rebase的取舍、force push的安全边界、stash的临时切换技巧,则能显著降低日常操作风险。同时,无论使用IDEA、VSCode还是TortoiseGit,图形

WGH100817的博客 409

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Git 系统教程:核心原理、常用命令与工程实战

本文系统梳理Git核心机制与实战流程,涵盖从基础配置、工作区管理到分支合并、远程协作的完整知识体系。重点解析暂存区作用、提交历史记录原理及HEAD指针机制,强调通过git status、git diff等命令精准控制变更。结合真实开发场景,详解分支管理、合并冲突处理、版本回退与恢复策略,倡导“先查状态、再操作”的安全习惯。最终引导建立以可追溯、可恢复、可协作为核心的正确Git使用思维,助力高效团队开发。

青蛙king的博客 791

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

上一篇: 简单A/BTest验证图片懒加载效果
下一篇: 【告别】从优快云迁移到掘金
Sheldon_Law
博客等级 码龄11年 44粉丝 32原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值