@effected/git

中文文档
0.32.0发布于 2026/11/10MITTypeScriptES Module零依赖构建来源已验证近 30 天下载 9800

Typed git introduction over Effect's ChildProcessSpawner:在任意回放时读取寄存器状态而不检查,外加有标记的变异级.

中文使用文档
文档目录6 节
  1. 为什么
  2. 安装
  3. 快开始
  4. 特征
  5. 需要命令吗?
  6. 许可证

@ effected/ git (英语)

npm License: MIT Node.js %3E%3D24.11.0 TypeScript 7.0

被打入了git回想作为效果服务. 一个读取级解答了 单重工具实际上提出的问题—— Git.show 在任何裁判处都读到文件内容 而不检查出来, Git.nameStatus 将每个已更改的路径按添加、重新命名、删除等方式排列, Git.workingChanges 收集完整的工作树三角洲, Git.commitInfo 返回一个承诺的 sha, 签名裁决和原始消息—— 和一个有明确标记的变异级( )checkout, (中文(简体) ), fetch,子模块对, sparseCheckoutSet, (中文(简体) ), configSet, (中文(简体) ), add)故意更改寄存器状态. 子进程运行于 Effect 核心 ChildProcessSpawner 合同,在 R ,并在您的应用程序边缘提供一次,所以此软件包具有零运行时间依赖性和零 node: 进口.

预1.0.0。 。 。 . 此软件包是 @effected/* 在稳定基础上建造的工具包 效应v4(effect ~4.1.0) 并仍在 0.x 发展。 稳定效果 制作一个工具箱 1.0.0 可能,不是自动的。 为了保持你的 effect 财务报告和审定财务报表 @effect/* 该工具包在线上构建和测试、安装 @effected/pnpm-plugin-effected。 。 。 .

稳定:不稳定. 此软件包的 API 表面尚未考虑 完成并可能改变 0.x 释放 定一个确切的版本——甚至 标记软件包 稳定 在此之前 1.0.0 可以引入突破性更改 和精确的针 变成一个类型检查错误 而不是一个 跑步时间惊喜。 完全政策: 释放策略。 。 。 .

为什么

在你解释答案之前 外出玩游戏看起来很容易 git通过出站代码和stderr出站口来说话,出站口随问题而变化:一个未知的出站口,一个不是寄存器的目录,一个在出站口没有的出站口,一个真正失败的命令都以"非零出站口外加句子"的形式回归. 每个呼叫站点的字符串匹配器 都会在某个地方出错 最终每次都用不同的方式.

这个软件包只读出 git 的退出代码和 stderr 在一个分类步骤中, 而手你输入的答案: 在有效参考书中缺失的路径是 Option.none 从 show (关于裁判的事实,而不是错误),不能解决的裁判是: false 从 refExists 键入 UnknownRefError 在其它地方,任何工作树以外的目录都是 NotARepositoryError,其他一切都是一个 GitCommandError 携带出口代码 和 Stderr 完好无损。 螺旋级平台故障和每跑30秒天花板被吸收在同一分类中——没有 PlatformError 并且没有超时缺陷 永远不会从一个泄露 Git 方法。 每一个命令都会产生针头 LC_ALL=C,因此分类在各地都比较稳定,外加一组非相互作用的针头(GIT_TERMINAL_PROMPT=0 和一个空的 GIT_ASKPASS),一个到达远程的成员添加 -o BatchMode=yes 到 ssh 命令 git 否则会用到 – 所以一个证书要求的远程, 在 https 或 ssh 上, 快速失败, 而不是在 提示 、 密码句 或 主机键确认 上被阻断 。 树列表使用NUL已终止输出,所以包含一个空间的路径——或一新行——活下来解析.

没有选择退出 通过服务, 和针取胜: extendEnv: true 合并父环境, 但一个被绑住的键击败它, 所以 GIT_TERMINAL_PROMPT=1 在您的环境中,无法重新提示。 一个打来电话的人,谁真正想得到 迅速运行 GitCommand ——这些是纯净的,没有任何环境,因此它们继承了你的无所事事.

刺针是适应你而不是压倒你的 在一个成员到达远地产卵之前,服务解决了sh命令git会自己使用的问题——你 GIT_SSH_COMMAND,否则你的 core.sshCommand,否则 ssh ——和附件 -o BatchMode=yes 改为 那个,所以自定义身份文件,跳出主机或端口存活. 四起案子中,你只能呆在这里 GIT_SSH 是由什么决定的(它命名一个程序而不取任何参数,所以没有什么可以附加和固定任何会取代它的东西); 当程序不是OpenSSH(plink 没有 -o KEY=VALUE 结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结为结 ssh.variant 或者说 GIT_SSH_VARIANT 告诉 git 命令不是 OpenSSH, 不管它的名称是什么; 当您已经设置时 BatchMode 自己 —— OpenSSH 尊重给重复选项的第一个值, 所以您的选择是任意的 。 在其中的每一个中,其他的指针仍然适用;只有sh级被跳过.

GitCommand 24个生产效果芯的纯构造器 Command 值可以检查、记录或测试,而无需生产任何东西.

安装

npm install @effected/git effect
pnpm add @effected/git effect

需要节点.js~~24.11.0. effect v4是同级依赖,它是唯一的——git没有自己的运行时间依赖.

全体 @effected/* 软件包仅为无害环境管理:只公布出口地图 import 条件,所以 require() 包括解析 CJS 模式的工具 —— 与节点失败 ERR_PACKAGE_PATH_NOT_EXPORTED 而不是装入不存在的 CJS 建筑。 从ES模块导入.

子进程产物来自Effect Core的 ChildProcessSpawner 合同,不是从平台包。 消费者在边缘提供过一次 NodeServices.layer 从 @effect/platform-node 在节点上——一个测试提供了一种脚本产卵器 ChildProcessSpawner.make,没有涉及程序.

快开始

阅读一个参考文件, 列出所发生的变化

import { Git } from "@effected/git";
import * as NodeServices from "@effect/platform-node/NodeServices";
import { Effect, Layer, Option } from "effect";

const program = Effect.gen(function* () {
  const git = yield* Git;
  const manifest = yield* git.show("/repo", "v1.2.0", "package.json");
  const changed = yield* git.changedFiles("/repo", { base: "main", head: "HEAD" });
  const released = yield* git.refExists("/repo", "refs/tags/v1.2.0");
  return { manifest: Option.getOrNull(manifest), changed, released };
});

const GitLive = Git.layer.pipe(Layer.provide(NodeServices.layer));

Effect.runPromise(program.pipe(Effect.provide(GitLive))).then(console.log);
// { manifest: "…the package.json as it was at v1.2.0…", changed: ["src/index.ts"], released: true }

错误频道告诉你会发生什么 show 在裁判所没有的道路上

import { Git, NotARepositoryError, UnknownRefError } from "@effected/git";
import { Effect, Option } from "effect";

const contentAt = (cwd: string, ref: string, path: string) =>
  Effect.gen(function* () {
    const git = yield* Git;
    return yield* git.show(cwd, ref, path);
  }).pipe(
    Effect.catchTag("UnknownRefError", () => Effect.succeed(Option.none<string>())),
    Effect.catchTag("NotARepositoryError", (e) => Effect.die(e)),
  );
// Effect<Option<string>, GitCommandError, Git> — absent-at-ref was already Option.none, no catch needed

特征

26个服务方法:18个读取寄存器状态,8个读取变异,全部通过相同的一阶分出.

  • 内容和树: Git.show(cwd, ref, path) - 参考文件内容, Option.none 当那条路不存在的时候 Git.lsTree(cwd, ref) 带有可选路径谱,返回类型 LsTreeEntry 值(模式、类型、Oid、路径),NUL-parsed.
  • Diffs: (英语) Git.changedFiles(cwd, { base, head }) - 不同范围的道路发生了变化——和 Git.nameStatus,将每个修改按添加、修改、删除、重新命名、复制和更多键入 oldPath 重命名,并使用 base...head 范围或工作树对一参考.
  • 工作树: Git.unstagedChanges, (中文(简体) ), Git.stagedChanges, (中文(简体) ), Git.untrackedFiles 财务报告和审定财务报表 Git.workingChanges (他们的分裂结合),加 Git.status 作为已打入的瓷器 StatusEntry 数值( 默认情况下每个未跟踪文件一个条目; 通过) untrackedFiles: "normal" git 崩溃目录).
  • 探测器 : Git.refExists (单位:千美元)true编号 :false,包括: false 以不能解决的裁判者发誓, Git.mergeBase 财务报告和审定财务报表 Git.revParse (解决SHAs), Git.repoRoot (物理——已解决的连锁), Git.commonDir (这个绝对的,同义链接-解析的目录 一个寄存器与它所有链接的工作树共享,所以两个答案与 === 和在树上 Option- 答话 Git.defaultBranch (未设置远程头) Option.none远程前缀剥去, Git.currentBranch (分离的总部) Option.none, (中文(简体) ), Git.configGet 财务报告和审定财务报表 Git.remoteUrl。 。 。 .
  • 配置为: Git.configGet, (中文(简体) ), Git.configGetAll 财务报告和审定财务报表 Git.configList 选择 scope (单位:千美元)"local" | "global" | "system" | "worktree",则 GitConfigScope 类型). 直通仍意味着 市场汇率读取 ——git本身将使用的价值,包括机器的任意价值 ~/.gitconfig 套接相接,通过 { scope: "local" } 以询问单次退票申报的内容. configList 接受 file 或者说 scope永远不要两者兼有:.
  • 提交 : Git.commitInfo(cwd, ref?) - 键入 CommitInfo 与莎,莎,玛 %G? 签名裁决和原始的,未切入的信息.
  • 历史: Git.log(cwd, { paths?, follow?, limit?, firstParentDiffMerges? }) ——承诺行走按键 CommitLogEntry 值,每个带 sha,两个日期解码为 DateTime.Utc,作者的身份和所接触的路径。 用路径标出它,走一条路 跨越重命名 follow: true中输入路径列表 firstParentDiffMerges未出生者 HEAD 而一个没有触碰的路径表 既是空的,也不是失败.
  • 变相分级,每种方法都标记为: Git.checkout (有一个分离选项), Git.fetch (远程、参考、深度、标记), Git.fetchAny (先尝试标记形式,然后回到普通形式) UnknownRefError 或者说 GitCommandError, (中文(简体) ), Git.submoduleUpdate, (中文(简体) ), Git.submoduleAdd, (中文(简体) ), Git.sparseCheckoutSet (明镜旗), Git.configSet (书写是本地寄存器,总是:一无所有) git config 自己写出单 .git/config,而且没有给出全球或系统范围——写作没有可辩驳的"有效值"默认读取方式)和 Git.add此处没有序列化的并行访问——呼叫者拥有,每棵工作树.
  • GitCommand.* - 所有24项援引都是纯粹的、可核查的 Command 数值.
  • 错误 : GitCommandError, (中文(简体) ), NotARepositoryError, (中文(简体) ), UnknownRefError ——分类发生一次,在服务内部. 远程读取器没有表面为 UnknownRefError 键入的信号也带有标记和分支 Effect.orElse。 。 。 .

需要命令吗?

Git其范围被消费者关闭,而不是被git的瓷器关闭,所以它会 总是漏掉一些东西 当你打到它, 不复制此软件包 私营 src/internal/run.ts - 达到 @effected/commands' Run.collect这是公众, 相同“发出一个命令和收集”的 维护、 限定版本 在一个范围下同时设置 stdout/stderr/exit-code:

import { Run } from "@effected/commands";
import { ChildProcess } from "effect/process";

const shortlog = ChildProcess.make("git", ["shortlog", "-sn", "HEAD"], {
  // The pins Git applies to its own spawns, which you make yourself here:
  // LC_ALL=C keeps stderr classifiable; the next two keep a credential-
  // requiring remote from blocking on a prompt (an empty GIT_ASKPASS is a
  // hard stop that also suppresses core.askPass and SSH_ASKPASS). extendEnv
  // keeps PATH.
  //
  // No GIT_SSH_COMMAND here, deliberately: `shortlog` is local. If YOUR
  // command reaches a remote and you want the same non-interactive
  // guarantee, resolve what git would have used first — GIT_SSH_COMMAND,
  // else core.sshCommand, else GIT_SSH, else plain ssh — and append
  // `-o BatchMode=yes` to that. Pinning a bare `ssh` instead silently
  // displaces a configured core.sshCommand or GIT_SSH, because the
  // environment variable outranks both in git's own precedence order.
  env: {
    LC_ALL: "C",
    GIT_TERMINAL_PROMPT: "0",
    GIT_ASKPASS: "",
    SSH_ASKPASS_REQUIRE: "never",
  },
  extendEnv: true,
}).pipe((command) => ChildProcess.setCwd(command, cwd));

const output = yield* Run.collect(shortlog);
// output.stdout / output.stderr / output.exitCode — a non-zero exit is DATA
// here, not an error, which is what lets you classify stderr the way Git does.

Run.collect 手卷拷贝不会给你三样东西: { concurrency: "unbounded" } 三收可以保持完整的OS管缓冲 从僵局运行,一个16米B每流捕获天花板 而不是 和编辑 公开的秘密 都从俘虏 输出和它引起的任何错误. @effected/commands 是一个边界包,与 effect 作为唯一的同行,所以拿这个优势 消费者付出的除了 页:1 ChildProcessSpawner 层已提供给 Git。 。 。 .

Git 自己故意这样做 没有 抓住那个边缘 看 @effected/git设计文件说明为什么——所以这两个执行是平行的 根据设计。 要构建新代码的是 Run.collect。 。 。 .

许可证

麻省理工学院

版本与发布记录

@effected/git 共发布 41 个版本,首次发布于 2026/07/17;过去 12 个月发布了 41 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.32.0latest2026/11/102 天前
0.31.02026/11/103 天前
0.30.02026/11/0310 天前
0.29.02026/11/0112 天前
0.28.02026/10/3014 天前
0.27.02026/10/2915 天前

关于 @effected/git 的常见问题

@effected/git 是什么?

Typed git introduction over Effect's ChildProcessSpawner:在任意回放时读取寄存器状态而不检查,外加有标记的变异级.

如何安装 @effected/git?

在项目目录运行 npm install @effected/git,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:effect(~4.1.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@effected/git 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@effected/git 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@effected/git 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=24.11.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@effected/git 可以商用吗?

@effected/git 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@effected/git 的下载量有多少?

根据 npm 官方下载统计,@effected/git 在 2026/10/13 – 2026/11/11 这 30 天内被下载 9,800 次,日均约 327 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@effected/git 还在维护吗?

最新版本 0.32.0 发布于 2026/11/10(2 天前);至今共发布 41 个版本,其中过去 12 个月发布了 41 个;首次发布于 2026/07/17。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。