Beagle SCM 的 URI 和 HTTP 动词与 git

Lobsters Hottest 工具

摘要

Beagle 是一个兼容 git 的源代码管理系统,它利用 HTTP URI 和动词为合并、变基等复杂的 git 工作流提供更简单、更正交的操作集。

<p><a href="https://lobste.rs/s/ybmrcg/beagle_scm_uris_http_verbs_with_git">评论</a></p>
查看原文
查看缓存全文

缓存时间: 2026/06/15 02:48

# Beagle: Git、URI 与所有那些棘手的术语 来源:https://replicated.wiki/blog/uris.html https://replicated.wiki/Human authored Git 的基本模型是一套极其简单的 blob 树和提交链系统,五分钟就能向任何人解释清楚。但在更高层次的抽象中,这种美妙的简洁性退化成了各种命令和标志的混乱组合,连拥有 20 年 Git 经验的开发者都难以记住。 当与 LLM 进行多任务协作时,这种混乱加倍严重。“我记得我们周二实现了这个功能,但这里怎么没有?它去哪了?”“哪个分支对应那个远程仓库?”等等。 要是我们有某种通用语言来寻址和访问本地与远程资源、文件以及文件中的位置就好了!哦等等,我们有 HTTP 和 URI,它们是最标准的协议了。它们本来就是为此设计的,被众多应用和库所支持。我们能把它应用到 Git 上吗? 当然可以。以 GitHub URI 为例,它们将 Git 空间映射到 HTTP URI 空间。这项工作的有趣之处在于定义一组正交操作(一个基),这样任何 Git 魔法都能被表示为这样一系列步骤,且没有歧义,但同时没有一个步骤可以被其他基本步骤的组合所表示。稍后会在 merge/rebase/cherry-pick 的例子中说明这一点。 ## URI 我们都牢记在心的 URI 布局: 1. `scheme:` —— 访问协议/寻址方案, 2. `//authority` —— 通常是网络主机, 3. `/path` —— 远程文件系统中的路径, 4. `?query` —— 其他信息(如参数), 5. `#fragment` —— 文档**内部**的位置。 我们能把它改造后用于版本化存储吗?嗯,如果所有版本信息都放到查询部分,其余部分就很明显了。例如:`http://somehost/dir/file?branch#L101`。事实上,[Beagle](https://github.com/gritzko/beagle) 就是一个完全这样做的、兼容 Git 的版本控制系统。 ## HTTP 动词 HTTP 的情况更有趣。最初,HTTP 有一组动词词汇:GET、HEAD、PUT、POST、PATCH、DELETE(参见 [RFC 7231](https://datatracker.ietf.org/doc/html/rfc7231))。虽然现在人们只用 GET 和 POST,但其他动词的存在是有理由的,对吧? - GET “检索信息” - HEAD 类似于 GET,但没有响应体 - POST 让服务器“接受实体” - PUT 请求“存储”实体 - DELETE 顾名思义 - PATCH(参见 [RFC 5789](https://www.rfc-editor.org/info/rfc5789/#section-2))请求“应用更改” 虽然这个词汇表有点模糊,但本质上它源自访问远程文件系统的需求。这自然符合 Git 模型,因为 Git 描述的是一个[内容寻址文件系统](https://git-scm.com/book/en/v2/Git-Internals-Git-Objects)。因此,Beagle **只使用** HTTP 动词。 等等,但它只有 **patch**?那 merge 和 rebase 呢? ## Git 的那些棘手术语 围绕 merge、rebase、squash、cherry-pick 以及所有与 Git 处理混乱编辑历史相关的技术,总是存在大量混淆。每个命令都做了几个通常不相关的事情,而每一件事情又可能由几个命令以微妙不同的方式完成。 Beagle 将这些实践分解为一组正交操作,构建在 Git 那个美妙简单的基础模型之上: - GET:将数据从仓库移动到工作目录(包括远程仓库) - HEAD:类似 GET 的预演——fetch 并报告 - POST:将数据从工作目录移动到仓库(提交) - PUT:仅编辑 reflog(设置分支/标签,暂存) - DELETE:类似 PUT,但用于删除 - PATCH:将另一个版本的更改应用到工作目录 正如你可能看到的,没有哪个操作可以被另一个操作替代:它们是严格正交的。我们来看看这如何应用于 merge/rebase/squash/cherry-pick 的混乱。 让我们看看所有 Git merge 变体做了什么: 1. 它们应用来自一个分叉提交或分支的更改, 2. 它们重用(rebase)或添加新消息(merge、squash), 3. 它们引用原始提交(merge)或不引用(rebase、squash)。 因此,我们有 8 种组合:提交/分支、重用/重命名、引用/遗忘。实际上,这 8 种中只有部分有相应的 Git 术语。例如,要 squash,我们必须完整应用一个分叉分支,添加一条新的提交消息,并且不引用原始分支。要 rebase,我们逐个应用提交,重用消息,不引用回去。要 merge,我们应用整个分支,添加一条新消息,并引用回去(父提交头)。 在 Beagle CLI 中的表达方式: ``` # 变基一个提交:首先将其应用到工作目录... be patch ?feature # 然后用相同的作者/消息提交,不引用父提交 be post #! # 合并一个分支:应用所有提交... be patch ?feature! # 然后用新消息提交(保留父提交引用) be post '#merge the feature' # 压缩一个分支:首先应用所有更改... be patch ?feature! # 然后用新消息提交,不引用父提交 be post '#add a new feature!' # 变基整个分支,逐个提交 while be patch ?feature; do # 检查每个树的状态是否有效,然后提交 make && make test && be post #!; done # 挑选一个提交:只应用差异 be patch #391a0d33 # 然后提交(相同作者/消息,不引用父提交) be post #! ``` 这里我们使用感叹号修饰符: 1. `?branch!` 应用整个分支(默认:一个提交), 2. `#message!` 遗忘原始提交(跳过父引用)。 当我们不提供消息时,会重用原始消息。对于变基,我们可能保留消息/作者但丢弃原始引用,所以咒语是:`#!`(重用消息,遗忘父提交)。 这里的分支变基只能通过循环进行,因为我们有多少个提交就做多少次 post。这也确保了所有提交的修订版本都能构建并通过测试(这是 Git 模型中的一个明显缺口)。 总体而言,这个模型更注重形式正确性和无歧义性,其总体思路是大部分时间 URI 将由 LLM 来拼写。 ## FAQ ### 那么,PUT 和 POST 有什么不同? POST 执行提交和/或快进。PUT 重置一个分支或标记一个文件为已提交/删除(仅 reflog 操作)。 ### 这与 Git 使用的 URI 相比如何? Git 只使用 URI 来访问仓库,例如 `git://github.com/gritzko/beagle.git`。这非常有限,所以我们想扩展这个寻址方案,以访问文件、修订版本以及文件中的位置。 ### 这与 GitHub URI 相比如何? GitHub URI 具有典型的 web 应用结构,这使它们在我们的场景中不太方便。 `https://github.com/gritzko/beagle/blob/main/keeper/README.md` 具体来说,beagle URI 将所有版本信息正交化到查询部分,以避免过度使用路径来表示所有东西(项目、用户、分支、路径)。Beagle 的分支是类似文件系统的树状结构,顶层条目是项目主干,因此上面的 GitHub URI 变成了: `be://replicated.live/keeper/README.md?/beagle` 注意,一个 Beagle 仓库可以托管任意数量的项目,默认传递项目的方式是查询。如果我们想查看一个分支,URI 变为: `be://replicated.live/keeper/README.md?/beagle/MEM-issues`

相似文章

Git history 命令值得更多关注

Hacker News Top

文章重点介绍了新的 `git history` 命令及其 `fixup`、`reword` 和 `split` 子命令,这些命令提供了原子化且感知分支的提交历史编辑功能,带来了类似 jj 的益处,而无需切换版本控制系统。

git rebase -i 并不可怕

Lobsters Hottest

解释 git 中的交互式变基命令,揭示其功能并强调通过中止和 reflog 的安全性。

Emacs 与 Bzr 的坎坷往事

Lobsters Hottest

文章回顾了 2008 年 GNU Emacs 开发者决定采用 Bazaar 而非 Git 作为版本控制系统的决策过程,重点强调了性能方面的顾虑,以及 Richard Stallman 坚持使用 GNU 软件包的立场,尽管技术基准测试显示 Git 更具优势。

Git并不好

Lobsters Hottest

本文对Git进行了批评,认为它并不像人们通常认为的那样好,并链接到Lobste.rs上的讨论。