GitButler CLI:Scott Chacon 谈 GitButler

GGitButler
Computing/SoftwareSmall Business/StartupsInternet Technology

Transcript

00:00:00欢迎大家,我要做个简短的演示,如果你还不了解 Git Butler,它是一款全新的版本控制工具。
00:00:07我们已经开发了几年。我们从 JJ 那里“借鉴”了不少好东西。
00:00:10所以,如果你平时使用 Jujutsu,说明我们从你们那儿学到了很多。
00:00:16总之,还没用过 Git Butler 的朋友,它就是一个版本控制工具。
00:00:19它通常是一个图形界面工具。
00:00:21但我们正在开发命令行工具(CLI),我想展示一些 CLI 的功能,因为你们都在处理 Git 相关工作,而且……
00:00:26Git 的命令行界面非常有趣。
00:00:29我们也从 Jujutsu 那里借鉴了一些概念。
00:00:33不过也有一些我觉得非常酷的新功能。
00:00:36所以我想展示给你们看,听听大家的想法,看看还能做哪些超酷的改进。
00:00:40好的,我会逐一讲解。
00:00:43那么……
00:00:46这里有几个不同的……这个命令行工具叫作 “but”。
00:00:49既然我一直在讲冷笑话,我觉得这个名字还挺合适的。
00:00:52你可以运行 “but status”,这有点像一个简短的日志(short log)。
00:00:57如果你用过 Sapling 或 Jujutsu 并查看过日志,
00:01:00我们会显示磁盘上被修改的文件,
00:01:05显示你的工作目录相对于目标分支的变化。
00:01:08同时,我们也会显示你拥有的提交记录,对吧?
00:01:11你也可以输入 “but status -F”,它会显示每个提交中修改的具体文件。
00:01:18如果你运行 Git Butler 的图形界面,你可以看到分支泳道之类的信息。
00:01:23但 Git Butler 有很多 Git 做不到的酷功能,比如这种漂亮的简短日志。
00:01:29就是它。
00:01:30而且,你知道……
00:01:32我们通常会提供一种日志,显示这些提交是本地的还是其他的,这类似于那种……
00:01:39短日志。
00:01:40在其他工具中也有,我们还可以创建新分支。
00:01:44如果我运行 status,可以看到,我正在做一个 Twitter 克隆版。
00:01:50我有几个分支,一个是堆叠(stacked)在另一个之上的。
00:01:52如果使用 update-ref,Git 在某种程度上也能做到这一点。
00:01:56设置好后,它会在你进行变基(rebase)之类操作时重写你的引用。
00:02:00但我们做得更自然,对吧?
00:02:03我们会自动更新你的引用,你可以随意更改,变基过程会全程追踪。
00:02:09但我们还可以实现……
00:02:11并行分支(Parallel branches),也就是说我们可以同时应用多个分支。我现在演示一下。
00:02:23先创建一个新分支,
00:02:26然后再次运行,现在就有了一个与正在处理的分支并行的分支,对吧?
00:02:33我可以进入那个分支,开始分配文件、提交内容。
00:02:39我们接下来会看到。
00:02:41另一个很酷的功能是我们有多个暂存区(staging areas)。
00:02:45你的每个堆栈都有自己的暂存区,所以你可以运行……
00:02:51“rub” 是这个命令,比如你可以对这个文件运行 “rub KU”,然后说把它放进 “ZA” 里。
00:02:58它就会把文件分配到特定的暂存区。如果我想分配某些东西,
00:03:04它会给你这些简短的代码,对吧,你可以说:好的,
00:03:12这个分配到这里,那个分配到那里。
00:03:15如果我提交它们,我可以同时把它们提交到这两个分支中。
00:03:21来看看这个。我们可以看到这个已经提交了,或者说已经分配了,所以我可以说:
00:03:27“but commit -o”。
00:03:30然后它就提交到这里了,对吧。
00:03:40现在这个文件就在这个提交里了,而且最棒的是,这底层全是 Git,所以我也可以……
00:03:48这样说,
00:03:50它实际上创建了一个 Git 提交,我可以推送那个分支等等。
00:03:57但是……
00:03:59是的,我可以分配到分支,或者直接运行 “but commit”,它会处理所有未分配的内容并提交到目标分支。
00:04:07我可以指定想把新内容提交到哪个分支。
00:04:11所以我们想出了这个词,叫作 “rubbing”(揉合)。
00:04:14我跟很多人提起过 Caleb,他喝了一整晚酒,现在还没来。
00:04:18如果他进来了,我们都应该站起来给他热烈的掌声。
00:04:21是他想出了 “rubbing” 这个词,本质上就是把两样东西放在一起,看看能变成什么。
00:04:28如果你玩过《我的世界》(Minecraft)之类的游戏,肯定知道“合成台”的概念。
00:04:32你很清楚这个概念,就是……
00:04:34把这个和那个放在一起,创造出一些新的、更有趣的东西,对吧?
00:04:38所以,你可以通过 “but rub” 命令在 but CLI 中进行很多“揉合”操作。
00:04:45我来演示几种不同的操作。我们可以分配文件,就像我刚才演示的那样,把未提交或……
00:04:52已修改的文件放入分支,但你也可以撤销分配。这里有一个特殊的模式 “00”。
00:05:01我可以运行 “but rub”,
00:05:05比如把整个提交……
00:05:07揉合到 “00”。
00:05:11它就撤销了那个提交。本质上是针对那个提交执行了一次 “soft reset”(软重置)。
00:05:17我也可以修正(amend)内容,比如运行 “rub le r”。
00:05:24y。
00:05:27RV。天哪,我得戴老花镜了,我也挺老了。
00:05:32SW,也就是我们的……抱歉,实际上是到……
00:05:3511 W。试试这个。
00:05:38是 IW 吗?谢谢。
00:05:41哎呀。
00:05:44那是个 I 吗?
00:05:48抱歉。
00:06:02然后……
00:06:04它就把它提交进去了。我还可以执行……
00:06:10Rub I。
00:06:14我可以撤销提交。
00:06:16对吧,我还可以压缩(squash)提交。如果我想合并这两个提交,可以运行 “but rub”。
00:06:22J e GE。
00:06:25然后它就把这些提交压缩在一起了。我可以撤销提交,随意移动内容。
00:06:32基本上,你觉得合并两样东西会发生什么,
00:06:37它就会执行相应的操作。如果你把某样东西合并到未分配的更改中,它本质上就是撤销操作,对吧?
00:06:42你甚至可以……我不确定这个现在能不能行。
00:06:48你也可以移动文件,比如……
00:06:53J 8 2。
00:07:02然后……
00:07:03它本质上是从那个提交中取出文件,然后……
00:07:07从该提交中撤销,并将其移入下方的提交中,对吧?
00:07:11有趣的地方不在于这在 Git 里做不到,而在于在 Git 里做起来相对困难,比如撤销……
00:07:19中间的某个特定提交,或者在提交之间移动文件,或者把一个文件修正到下面第三层的提交里。
00:07:27对吧,虽然在 Git 里你能做到,比如你可以做一种……
00:07:31临时的 fixup 提交然后自动压缩(auto squash)之类的。
00:07:34但能像这样直接“揉合”并把内容移到你想要的地方,感觉非常棒。
00:07:40而且还能同时拥有多个分支。
00:07:43另一件能做的事是,你可以非常轻松地拆分提交。我们还有这个 “but new” 命令。
00:07:51比如我想运行……
00:07:54“but new”。
00:07:56H e,然后它会……
00:07:59在那里创建一个新的空白提交,里面什么都没有。
00:08:03对。这是 Jujutsu 风格,你可以创建一个没有任何内容的空提交。
00:08:08然后如果我想的话,可以把文件“揉合”进去,比如我可以运行……
00:08:12选中这个文件。
00:08:150。
00:08:23选中它。
00:08:29它就把这个文件移到了这个新提交里,然后我可以运行 “describe”。
00:08:32刚才那个是 X u c 吗?
00:08:45我该怎么……
00:08:56Status -F,文件状态。它会显示每个提交中的文件。所以运行 “but ST”……
00:09:02“but status” 只显示提交记录。
00:09:04而 “but status -F” 会显示每个提交里的文件,这样你就能通过“揉合”来移动它们。
00:09:11好了,有 “new” 和 “describe”,最后一样是 “marking”(标记),这也非常有 JJ 的风格。
00:09:16如果你用过 Jujutsu,你可以标记一个提交,把它设为目标。
00:09:21这样工具看到的所有新内容都会放入那个提交,所以你可以进行标记。
00:09:25这其实挺有意思的,对吧,我可以运行……
00:09:29“but new -M” 或者我直接标记,运行 “but mark”。
00:09:33Z a。
00:09:35它就会标记这个,你可以看到它已经把未提交的东西放进了那个……
00:09:42分支泳道(lane)。
00:09:44然后我可以提交东西,或者我也可以标记……
00:09:47某个特定的提交。
00:09:56噢,那个是分支,抱歉。
00:09:58它标记了一个特定的提交,然后如果我执行类似 echo “new”……
00:10:07它就会获取那个更改并自动提交到被标记的提交中,对吧。
00:10:15这很有趣,因为这是一个堆叠分支,有好几个提交,而我现在做的任何事情……
00:10:21都会自动修正到堆叠分支中下面第三层的提交里,对吧?
00:10:26这有点像 JJ 的操作方式,你运行 “jj new” 然后开始工作。
00:10:31它会自动修正你最近的一次提交。
00:10:33不同的是,你可以标记几乎任何一个提交。
00:10:36继续工作,它会一直尝试把改动合入那个提交,然后你可以随时取消标记。
00:10:41对吧。
00:10:44总之,这些就是我们正在开发的一些好玩的功能。
00:10:48我觉得能在这个工具上工作真的很棒。
00:10:52另外一个同样是从 JJ 借鉴来的功能是 “oplog”(操作日志)。
00:10:56这是我们已经开发了很久的功能。
00:10:59如果你用过 Git Butler 图形界面,会有一个选项卡显示我们执行的所有操作。
00:11:03但我每次运行命令时,它都会记录……
00:11:06一个操作历史,我可以查看 Git Butler 执行的所有操作,我可以恢复到其中任何一个,或者说……
00:11:12执行……
00:11:13“undo”(撤销)。
00:11:14哎呀,拼对了的话,我可以运行 undo,它就会撤销操作,把工作目录和状态恢复到……
00:11:20之前的样子。或者我可以运行……
00:11:22“restore”(恢复)。
00:11:24恢复到任何这些 SHA 值。
00:11:26哎呀。
00:11:29然后……
00:11:33它会将我的工作目录、分支以及所有内容重置回之前的状态。
00:11:38用这种方式做演示其实挺有趣的,因为我可以先创建一个……
00:11:44我知道能成功的场景,然后恢复回去,再重新演示一遍。
00:11:50但显然,如果你想说:“其实我不想那么做”或者“我陷入了……”
00:11:54“冲突区域”之类的,直接撤销然后继续工作,这就非常方便了。
00:11:58好了,就这些。噢,还有一件事,所有命令都有 JSON 输出,你可以加上 “-J”……
00:12:06或者 “--json” 运行任何命令,它会给你相同的数据,但格式是 JSON。
00:12:11所以如果你想写脚本,这比解析 Git 的 porcelain 输出要好得多。
00:12:15你可以直接导入,或者通过 jq 处理来查找特定的条目之类的。
00:12:21这样编写 CLI 脚本会更方便。
00:12:24就这些,非常感谢大家。

Key Takeaway

GitButler CLI 是一个基于 Git 但超越其限制的创新工具,通过引入揉合、操作日志和 JSON 原生支持,为开发者提供了更直观、灵活且易于脚本化的版本控制体验。

Highlights

GitButler 推出名为 "but" 的全新命令行工具(CLI),旨在提升 Git 的操作体验。

核心概念 "Rubbing"(揉合)允许用户轻松合并、拆分、移动或撤销提交内容。

支持并行分支(Parallel Branches)和堆栈式工作流,每个堆栈拥有独立的暂存区。

借鉴了 Jujutsu (JJ) 的标记(Marking)功能,可将更改自动重定向到特定历史提交。

内置操作日志(Oplog)系统,支持一键撤销(Undo)或恢复(Restore)到任意历史状态。

所有 CLI 命令均支持 JSON 格式输出,极大地方便了开发者编写自动化脚本。

Timeline

项目背景与 GitButler CLI 简介

Scott Chacon 开场介绍了 GitButler 这款开发多年的版本控制工具,并指出其 CLI 版本深受 Jujutsu (JJ) 等现代工具的影响。GitButler 最初以图形界面(GUI)为主,但团队现在致力于将其核心优势引入命令行界面。演讲者强调 Git 的原生 CLI 虽然有趣但存在局限,因此他们借鉴了 JJ 的先进概念并加入了独创功能。本段明确了工具的定位是服务于处理复杂 Git 任务的开发者,并希望通过演示获取社区反馈。这为后文展示 "but" 工具的具体指令和操作逻辑奠定了基础。

基础命令与并行分支功能演示

展示了名为 "but" 的 CLI 工具及其基础状态查询命令 "but status",该命令能以简洁的短日志形式显示修改的文件和提交记录。通过使用 "-F" 参数,用户可以直观地查看每个提交中涉及的具体文件变化,这在原生 Git 中往往需要复杂的参数组合。GitButler 的一大特色是支持并行分支,这意味着开发者可以同时在多个功能分支上应用更改,而不会互相干扰。演示中通过 Twitter 克隆项目的实例,展示了如何自然地处理堆栈分支,系统会自动在变基等操作中追踪并重写引用。这一部分体现了工具在处理多任务并行开发时的易用性优势。

核心概念:Rubbing(揉合)与多暂存区

本节重点介绍了 GitButler 的核心创新点:每个堆栈拥有独立的暂存区,以及名为 "rubbing"(揉合)的操作。通过 "but rub" 命令,用户可以将未提交的更改分配到特定的分支暂存区,甚至同时向两个分支提交内容。"Rubbing" 的灵感来源于《我的世界》中的合成台概念,寓意将两样东西结合产生新的结果。演讲者演示了使用 "but commit -o" 将特定分配的文件打包提交,并强调底层依然是标准的 Git 提交,保证了兼容性。这种设计打破了 Git 只有一个索引(Index)的限制,让代码整理过程变得极其灵活。此外,这种方式也极大简化了将改动分发到不同逻辑单元的复杂度。

高级提交操作:压缩、拆分与撤销

深入演示了使用 "but rub" 进行的高级版本库操作,包括修正(Amend)、压缩(Squash)和撤销(Undo)。通过特定的短代码标记,用户可以将整个提交重置为未分配状态,或者将特定文件从一个提交移动到另一个提交中。虽然这些操作在原生 Git 中可以通过交互式变基实现,但 "but" 工具通过简短的指令让这些动作变得即时且低门槛。演讲者提到在 Git 中移动中间层的提交内容非常困难,而 GitButler 让这种“揉合”变得像拼图一样简单。这一段展示了工具在处理代码整洁度(Cleanup)方面的强大威力,显著降低了重构提交历史的成本。这种直观的操作逻辑是该工具相较于传统 Git 最大的竞争优势之一。

标记功能与自动修正流

介绍了借鉴自 JJ 的 "marking"(标记)功能,允许用户将某个历史提交设为当前活跃目标。一旦标记了某个提交,后续所有的文件更改和写入都会自动“揉合”并修正到该目标中,即使它位于提交堆栈的底层。演示中通过 "but new" 创建空提交,并利用 "but mark" 实现了自动化的增量更新,省去了频繁手动执行 amend 的麻烦。这种工作流非常适合进行长周期的功能开发,开发者可以专注于代码逻辑,而由工具负责归档。演讲者指出,这种灵活性让用户可以随时切换目标或取消标记,极大地增强了开发者的掌控力。这部分内容展示了 GitButler 在自动化日常繁琐任务方面的深度思考。

操作日志(Oplog)与 JSON 脚本支持

最后展示了极其强大的操作日志(Oplog)功能,系统记录了通过 GitButler 执行的每一次操作历史。如果开发者在复杂的变基或揉合中出错,可以使用 "but undo" 快速回滚,或使用 "but restore" 恢复到特定的历史 SHA 状态。这种容错机制为实验性的版本操作提供了安全网,避免了因误操作导致的代码丢失风险。此外,所有命令都提供了 JSON 输出模式(-J),使得第三方工具或自定义脚本可以轻松解析版本状态。相比于解析 Git 的文本输出,JSON 格式为自动化集成和工具链扩展提供了更规范的接口。Scott Chacon 以此总结了 GitButler 在提升开发者生产力和工具可扩展性方面的愿景。

Community Posts

View all posts