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就这些,非常感谢大家。