ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

isomorphic-git 快速入门:在浏览器中纯 JavaScript 实现 git clone、status、add、commit 全流程

isomorphic-git 快速入门:在浏览器中纯 JavaScript 实现 git clone、status、add、commit 全流程 开发工具【免费下载链接】isomorphic-gitA pure JavaScript implementation of git for node and browsers!项目地址https://gitcode.com/gh_mirrors/is/isomorphic-git点击查看免费下载本篇指南以 isomorphic-git 项目官方 Quick Start 文档website/versioned_docs/version-1.x/guide-quickstart.md为骨架带你在浏览器环境中完成一次完整的 Git 操作之旅从搭建 LightningFS 虚拟文件系统与 isomorphic-git 运行环境到克隆真实仓库、查看提交历史、追踪文件状态、暂存修改、删除文件并提交新版本。读完本文你将掌握 isomorphic-git 的clone、log、status、add、remove、commit六大核心 API 的调用方式、参数含义与底层实现原理并能在自己的浏览器项目中直接复刻这套工作流。环境搭建让 Git 跑在浏览器里isomorphic-git 的卖点在于它是同构的同一套 API 既可以在 Node.js 环境运行也可以在浏览器中运行项目描述即 A pure JavaScript implementation of git for node and browsers!。浏览器没有文件系统也没有 git 二进制因此官方 Quick Start 使用了两样东西配合LightningFSisomorphic-git/lightning-fs一个基于 IndexedDB 的浏览器文件系统实现为 isomorphic-git 提供fs接口isomorphic-git 浏览器版 HTTP 客户端负责执行网络请求替代 Node.js 的http模块。官方文档给出的初始化代码如下script srchttps://unpkg.com/isomorphic-git/lightning-fs/script script srchttps://unpkg.com/isomorphic-git/script script typemodule import http from https://unpkg.com/isomorphic-git/http/web/index.js // Initialize isomorphic-git with a file system window.fs new LightningFS(fs) // I prefer using the Promisified version honestly window.pfs window.fs.promises /script要点说明两个script标签分别把LightningFS构造器和git全局对象挂到window上new LightningFS(fs)中的fs是虚拟文件系统在 IndexedDB 中的数据库名称浏览器端 HTTP 客户端需要从isomorphic-git/http/web/index.js以 ES Module 方式导入对应源码为 src/http/webNode.js 环境则改用 src/http/nodewindow.fs.promises是 Promise 化的文件系统 APIpfs.mkdir、pfs.readdir、pfs.writeFile、pfs.unlink等方便配合await使用。从源码结构看所有公开 API 都从 src/index.js 统一导出同时支持具名导出import { clone } from isomorphic-git和默认导出对象import git from isomorphic-git即教程中git.clone的调用方式。关于fs参数的具体契约可进一步参考 docs/fs.md。选择工作目录在虚拟文件系统里建文件夹环境就绪后第一步是选定一个工作目录。Git 操作需要一个工作树working tree在浏览器场景中它同样存在于 LightningFS 里window.dir /tutorial console.log(dir); await pfs.mkdir(dir); // Behold - it is empty! await pfs.readdir(dir);这里把虚拟路径/tutorial作为本次实验的目录pfs.mkdir创建它pfs.readdir确认它是空的。教程中的window.dir /tutorial是为了让每个代码块都能访问到共享状态——这种写法与 Docusaurus 交互式文档js live代码块可在线运行是配套的你在自己的项目里完全可以按局部变量或模块作用域组织dir。关于工作树与 Git 目录的关系isomorphic-git 有专门的说明文档 docs/dir-vs-gitdir.mddir是工作树目录gitdir默认是join(dir, .git)即仓库元数据所在的目录。后续所有 API 都接受这个可选的gitdir参数。克隆仓库clone 的参数与 CORS 代理目录就绪后官方教程克隆了 isomorphic-git 自己的仓库how meta!。为了节省时间、带宽和浏览器存储空间只克隆单个分支、且只取最近 10 个提交await git.clone({ fs, http, dir, corsProxy: https://cors.isomorphic-git.org, url: https://github.com/isomorphic-git/isomorphic-git, ref: main, singleBranch: true, depth: 10 }); // Now it should not be empty... await pfs.readdir(dir);为什么需要 corsProxy浏览器环境受同源策略CORS限制而当时的 GitHub git clone 端点没有返回 CORS 响应头。isomorphic-git 的解决方案是引入一个 CORS 代理服务器corsProxy把浏览器发出的 git 协议请求转发到真实远端。官方文档的注释点明了这一历史背景They never suspected that abrowserwould want to run git clone!。如果你有自建代理也可以参考 isomorphic-git/cors-proxy 的部署方式该链接为 npm 包页面本项目文档 docs/guide-webworker.md 与 docs/authentication.md 中亦有相关使用说明。clone 的完整参数清单对照 src/api/clone.js 的 JSDocclone除教程用到的参数外还支持参数类型/默认值说明fsFsClient必填文件系统实现httpHttpClient必填HTTP 客户端dirstring工作树目录noCheckout为 true 时可不传gitdirstring join(dir,.git)Git 目录路径urlstring必填远端仓库 URLcorsProxystringCORS 代理会被写入该仓库的 git configrefstring要检出的分支默认是远端主分支singleBranchboolean false只拉取单个分支而不是全部分支noCheckoutboolean false只 fetch 不检出省去写盘时间noTagsboolean false默认会拉取全部标签设为 true 可禁用remotestring origin新建远端的名depthnumber获取多少层历史浅克隆sinceDate只获取该日期之后的提交与depth互斥excludestring[] []让服务端不要发送这些 ref 可达的提交relativeboolean falsedepth相对当前浅深度而非分支尖端计算headersobject {}附加 HTTP 请求头类似 git 的extraHeadercacheobject缓存对象见 docs/cache.mdonProgress/onMessage/onAuth等回调进度、消息、认证等回调见 docs/onProgress.md 等从实现看clone内部由 src/commands/clone.js 完成实际流程是fetch checkout的组合并通过discoverGitdir定位真正的.git目录。assertParametersrc/utils/assertParameter.js会在参数缺失时立即抛出MissingParameterError。查看提交历史log 的用法与返回结构克隆完成后用git.log查看该分支的最近提交历史await git.log({fs, dir})教程提示expand the objects so you can see all the properties。log返回一个ReadCommitResult数组每个元素包含oid提交 SHA-1与commit对象message、tree、parent、author、committer等字段。对照 src/api/log.jslog还支持这些参数ref HEAD从哪个提交开始往回走depth限制返回的提交数量教程后续提交时会用到depth: 1since只返回晚于该日期的历史filepath只返回该文件的提交历史follow/force配合单文件历史使用支持跟踪重命名includeChanges让每条记录附带变更的文件对象 ID。// 只看最近 1 条提交教程提交后的用法 let commits await git.log({fs, dir, depth: 1}) console.log(commits[0])追踪文件状态status 的 13 种取值Git 的核心职责是追踪文件。isomorphic-git 的git.status负责把工作目录中的单个文件与当前分支HEAD进行对比await git.status({fs, dir, filepath: README.md})刚克隆完一切未改动返回unmodified。教程随后依次演示了修改、新增、删除三种场景下状态的变化这正是理解暂存区index/staging area的关键。修改文件从*modified到modifiedawait pfs.writeFile(${dir}/README.md, Very short README, utf8) await git.status({fs, dir, filepath: README.md})带星号的*modified表示文件在工作目录里有改动但还没有进入暂存区。教程用一个很形象的比喻文本编辑器会在标题栏显示*表示有未保存的更改。执行git.add之后await git.add({fs, dir, filepath: README.md}) await git.status({fs, dir, filepath: README.md})星号消失状态变成modified——改动已暂存。新增文件从*added到addedawait pfs.writeFile(${dir}/newfile.txt, Hello World, utf8) await git.status({fs, dir, filepath: newfile.txt})未跟踪的新文件返回*added已出现在工作目录但未暂存git.add之后变为added。删除文件先 unlink再 removeawait pfs.unlink(${dir}/package.json) await git.status({fs, dir, filepath: package.json})有意思的是仅仅删掉文件还不够——你还需要告诉 git 你删除了它await git.remove({fs, dir, filepath: package.json}) await git.status({fs, dir, filepath: package.json})一个反直觉的边界情况教程还演示了一个容易困惑的场景如果对实际上并没有删除的文件执行git.remove会怎样await git.remove({fs, dir, filepath: package-lock.json}) await git.status({fs, dir, filepath: package-lock.json})结果是文件同时报告为untracked和deleted。这是因为git.remove只把文件从索引index中移除并不会删除工作目录里的文件——它的文档注释明确写着 Note that this does NOT delete the file in the working directory见 src/api/remove.js。于是工作目录里有文件、索引里没有、HEAD 里有状态机便同时呈现未跟踪与已删除两个特征。教程随后用git.add把这个文件重新加回索引恢复added状态。status 的完整取值表src/api/status.js 的 JSDoc 给出了status的全部 13 种可能返回值是理解该 API 的第一手权威资料status说明ignored文件被 .gitignore 规则忽略unmodified文件与 HEAD 提交一致*modified有改动尚未暂存*deleted已删除删除尚未暂存*added未跟踪尚未暂存absentHEAD、暂存区、工作目录中都不存在modified有改动已暂存deleted已删除已暂存added先前未跟踪现已暂存*unmodified工作目录与 HEAD 一致但索引不同*absent工作目录与 HEAD 都没有但索引中存在*undeleted已从索引删除但工作目录仍有该文件*undeletemodified已从索引删除但工作目录中的文件有改动带*前缀的状态意味着尚未暂存。从 src/api/status.js 的实现可以推断status的判定基于三元组HEAD 中是否存在 / 索引中是否存在 / 工作目录中是否存在并通过对工作目录文件重新计算 blob 的 SHA-1hashObject与 HEAD 树、索引条目比对得出最终结论.gitignore只对未跟踪文件生效代码注释中对此有明确说明。若某条路径同时存在于 HEAD 与索引中则工作目录的哈希基于core.autocrlf规范化后计算避免 CRLF 换行导致误报 modified。暂存与移除的底层实现git.add见 src/api/add.js把文件加入 git 索引暂存区await git.add({fs, dir, filepath: README.md})其参数与实现要点filepath支持字符串或字符串数组也支持目录会递归处理子文件force false即使匹配 .gitignore 也强制加入等价于git add --force默认情况下被忽略的文件会被跳过内部通过GitIgnoreManager.isIgnored判断并遵守已在索引中的路径不受后续 ignore 规则影响的语义parallel true并行处理多个文件更快但更耗内存实现上通过GitIndexManager.acquire独占式修改索引src/managers/GitIndexManager.js为每个文件调用_writeObject写入 blob 对象再把{filepath, stats, oid}插入索引目录参数会递归展开为子文件逐个处理。git.remove见 src/api/remove.js则只做一件事在索引中删除该条目index.delete({ filepath })工作目录文件原样保留。这解释了前面删除但未删除的怪现象。提交commit 的调用与返回值教程把一天的工作成果删掉 package.json、把 README 改成 Very short README正式提交let sha await git.commit({ fs, dir, message: Delete package.json and overwrite README., author: { name: Mr. Test, email: mrtestexample.com } }) console.log(sha)git.commit返回新提交的 SHA-1 对象 IDshasum。对照 src/api/commit.js还有这些实用参数author/committer都支持name、email、timestampUnix 秒、timezoneOffset与 UTC 的分钟差不传committer时默认复用authorname/email未指定时回退到仓库配置的user.name/user.emailamend false为 true 时替换ref指向的最近一次提交dryRun false只模拟提交以验证能否成功noUpdateBranch false创建提交但不更新分支指针disallowEmpty false没有暂存改动时是否抛EmptyCommitErrorparent/tree显式指定父提交与树对象默认分别取ref指向的提交和由当前索引生成的新树signingKey/onSignPGP 私钥签名支持。提交后再次用git.log({fs, dir, depth: 1})查看最新提交即可确认自己工作成果已经进入历史。清理现场重置 LightningFS交互式教程的末尾提供了一个一键清空的代码块用于在重复练习时重置虚拟文件系统window.fs new LightningFS(fs, { wipe: true }) window.pfs window.fs.promises console.log(done)wipe: true会清空该名字对应的 IndexedDB 存储让你从零开始重跑整个流程。总结与延伸阅读至此你已经在浏览器里走完了 Git 的核心生命周期clone获取→ status对比→ add/remove暂存/移除→ commit提交→ log查看历史。教程最后提到This just scratches the surface——isomorphic-git 的能力远不止于此。本项目 1.x 版本的全部公开 API 可查阅 website/versioned_docs/version-1.x/alphabetic.md字母序索引或直接浏览 src/api 目录下的源码与 JSDoc。继续深入学习还可以参考docs/fs.md文件系统实现契约Node 与浏览器各自如何接入docs/dir-vs-gitdir.mddir与gitdir的区别与默认约定docs/cache.mdcache参数如何加速多次操作docs/http.mdHTTP 客户端接口说明docs/guide-quickstart-with-bundlers.md 与 website/versioned_docs/version-1.x/guide-browser.md面向打包器webpack/rollup与浏览器的更深入配置指南各 API 的测试用例集中在tests如tests/test-clone.js、tests/test-status.js、tests/test-add.js、tests/test-commit.js可对照验证本文涉及的行为。赞分享开发工具【免费下载链接】isomorphic-gitA pure JavaScript implementation of git for node and browsers!项目地址https://gitcode.com/gh_mirrors/is/isomorphic-git点击查看免费下载相关推荐isomorphic-git 浏览器端快速上手在浏览器中运行 git clone、status、add、commit 全流程isomorphic git 浏览器端快速上手在浏览器中运行 git clone、status、add、commit 全流程 导读 isomorphic gi开发工具探索isomorphic-git浏览器中的纯JavaScript Git实现探索isomorphic git浏览器中的纯JavaScript Git实现 isomorphic git是一个强大的纯JavaScript Git实现它能开发工具isomorphic-git 快速上手Node 与浏览器中克隆仓库、status/add/commit 工作流完整实践isomorphic git 快速上手Node 与浏览器中克隆仓库、status/add/commit 工作流完整实践 本文基于仓库内的 Quick Star开发工具上一篇KawaiiLogos全平台设计规范确保Logo在任何设备上都清晰下一篇Superpowers 完整指南给 AI 编码代理一套真正的开发纪律创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表