使用 git diff 命令实现根目录文档的更新的时候自动更新子文档 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
moment082
V2EX    程序员

使用 git diff 命令实现根目录文档的更新的时候自动更新子文档

  •  
  •   moment082 2024-04-11 11:26:46 +08:00 1038 次点击
    这是一个创建于 618 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在开始之前,首先描述一下我们目前遇到的场景,目前我们正在开发一个 前端脚手架 开源项目,当前项目使用 Truborepo+PNPM 开发的一个 Monorepo 项目,在根目录中,我们有一个文档,然后 packages 目录下有些子包的文档应该是和根目录下的包是一样的。

    因为我们的包是发布到 NPM 上的,并且是 GitHub 上开源的,所以根目录上的 README.me 应该是在 GItHub 上一打开项目的时候就能查看的,而 packages 目录下的子包文档应该是当在 NPM 网站上打开的时候就能看到的。

    如下图所示 GitHub:

    20240411073036

    而在 NPM 上也是这样的:

    20240411073140

    那么接下来我们的任务是当我们根目录下的 README.md 发生变动的时候,我们 packages 目录下的固定子包应该也会发生改变。

    git diff

    在开始之前,我们先来学习一下 git diff 这个命令。

    git diff 是 Git 版本控制系统中一个非常有用的命令,用于显示文件之间的差异、差异补丁和进行代码审查。这个命令可以用来比较文件的变化,检查工作目录中未暂存的改动,以及比较已暂存的改动和最近的提交等。

    查看未暂存的更改:

    git diff 

    这个命令将会显示自从上次 git add 之后,工作目录中有哪些更改尚未暂存。

    20240411075324

    查看已暂存的更改:

    git diff --cached # 或者使用另外一个写法 git diff --staged 

    20240411075655

    这个时候我们可以看得出,使用 git diff --cached 命令是我们还不能查找得出文件内容是否有发生变更的,这个前提是需要他把文件添加到暂存区,也就是执行 git add,如下所示:

    20240411075837

    除此之外,我们还可以查看到具体哪个文件发生了变化,使用的命令是 git diff --cached <具体文件路径>

    20240411080029

    生成补丁文件,这个在我们前面的文章内容中就已经有讲解过了:

    git diff > changes.patch 

    这个时候我们已经知道了怎么查找文件的变更了,那么我们应该如何来实现这个 git diff 命令呢,以及在哪里实现呢?

    配合 husky 来实现文档自动更新

    Husky 是一个流行的工具,用于在 Git 钩子中自动化 Javascript 和其他语言的项目的代码质量检查、测试以及在提交前自动修正问题。它使得配置和使用 Git 钩子变得简单便捷,如 pre-commit 或 pre-push 钩子,从而可以在代码提交到版本控制系统之前执行代码检查和格式化任务,确保代码库的整洁和一致性。

    要想实现我们的需求,首先我们可以在 pre-commit 钩子中通过 git diff 来查找出文件的变更或者然后根据这个文件变更的内容编写一个脚本自动复制到某个具体的文件。

    首先我们在 husky 的 pre-commit 中添加如下代码:

    #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" echo 'running pre-commit checks ...' npx lint-staged -q + npx ts-node --transpile-only ./scripts/check-readme-change.ts echo -e 'pre-commit success!\n' 

    需要提前执行 pnpm add ts-node -Dw

    然后我们要在根目录下的 scripts 目录下添加 check-readme-change.ts 文件并编写如下代码:

    const { execSync } = require("child_process"); const fs = require("fs"); const path = require("path"); const fileToCheck = "README.md"; // 需要检查的文件 const destinatiOnFiles= ["packages/core/README.md"]; try { // 执行 git diff 命令以检查是否有文件更改 const result = execSync(`git diff --cached --name-only`).toString(); // 检查目标文件是否在更改列表中 if (result.split("\n").includes(fileToCheck)) { // 如果文件有更改,读取文件内容 const data = fs.readFileSync(fileToCheck, "utf8"); // 将内容复制到所有目标文件 destinationFiles.forEach((filePath) => { const targetPath = path.join(process.cwd(), filePath); fs.writeFileSync(targetPath, data); console.log(`Copied updated ${fileToCheck} to ${targetPath}`); }); // 提交文件更改 execSync("git add ."); execSync("git commit --no-verify --allow-empty-message"); } } catch (error) { console.error("Error executing git diff:", error); process.exit(1); // 有错误发生时退出脚本 } 

    在上面的代码中就是查找出 README.md 文件有没有发生改变,如果没有发生改变的直接跳过,如果改变了则将文件复制到固定目录下并使用 git add . 将所有修改过的文件添加到 Git 暂存区。用 git commit --no-verify --allow-empty-message 提交更改到本地仓库。

    如下图所示,我们的文件发生了如下变化:

    20240411101718

    当我们执行完成 git commit 的时候,packages 目录下固定包的 README 文件被我们正确的修改了:

    20240411101916

    到这里,我们就完成了我们的文档自动同步的需求了。

    总结

    在这篇文章中我们只要使用 git diff 在 Git 提交流程中自动检测和处理特定文件的更改,确保所有相关的部分都保持最新,并自动完成这些更改的提交。这种自动化有助于保持项目的不同部分同步,特别是在大型项目中,当某个核心文件(如 README.md )更新时,需要同步更新到多个位置。

    最后分享两个我的两个开源项目,它们分别是:

    这两个项目都会一直维护的,如果你想参与或者交流学习,可以加我微信 yunmz777 如果你也喜欢,欢迎 star

    目前尚无回复
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     915 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 24ms UTC 18:56 PVG 02:56 LAX 10:56 JFK 13:56
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86