#git-commit #git-rebase #版本控制 #自动 #hg #吸收 #修复

bin+lib git-absorb

git commit --fixup,但更自动

18 个版本

0.6.15 2024 年 8 月 3 日
0.6.14 2024 年 7 月 7 日
0.6.13 2024 年 4 月 3 日
0.6.12 2024 年 2 月 24 日
0.2.0 2018 年 3 月 12 日

#53 in 开发工具

Download history 17/week @ 2024-05-03 9/week @ 2024-05-10 16/week @ 2024-05-17 11/week @ 2024-05-24 9/week @ 2024-05-31 17/week @ 2024-06-07 10/week @ 2024-06-14 12/week @ 2024-06-21 7/week @ 2024-06-28 79/week @ 2024-07-05 28/week @ 2024-07-12 15/week @ 2024-07-19 23/week @ 2024-07-26 214/week @ 2024-08-02 37/week @ 2024-08-09 14/week @ 2024-08-16

每月 290 次下载

BSD-3-Clause

70KB
1.5K SLoC

git absorb

这是 Facebook 的 hg absorb 的移植,我第一次在 mozilla.dev.version-control 上了解到

  • Facebook 展示了 hg absorb,这可能是我多年来看到的最酷的版本控制工作流程增强。本质上,当你的工作目录在草稿提交集之上有不提交的更改时,你可以运行 hg absorb,不提交的修改会自动折叠(“吸收”)到适当的草稿祖先提交集中。这本质上是在不提交或手动修改历史修改规则的情况下执行 hg histedit + “滚动”操作。命令本质上查看被修改的行,找到修改这些行的提交集,并修改该提交集以包含你的不提交的更改。如果更改无法在不冲突的情况下进行,则它们将保持未提交状态。这个工作流程对于应用审查反馈等事情非常有用。你只需进行文件更改,运行 hg absorb,更改到提交的映射就会自己整理出来。这是神奇的。

简介

你有一个带有几个提交的功能分支。你的队友审查了分支,并指出了一些错误。你修复了这些错误,但你不希望将它们全部推入一个说 fixes 的不透明提交中,因为你相信原子提交。与其手动查找 git commit --fixup 的提交 SHA,或者手动运行交互式变基,你可以这样做

git add $FILES_YOU_FIXED
git absorb --and-rebase

git absorb 将自动识别哪些提交是安全的进行修改,以及哪些暂存更改属于每个提交。然后,将为这些更改中的每一个写入 fixup! 提交。

使用 --and-rebase 标志,这些 fixup 提交将自动整合到相应的提交中。或者,如果您不信任其输出,可以手动检查,然后使用 git 内置的 autosquash 功能将修复合并到您的功能分支中

git add $FILES_YOU_FIXED
git absorb
git log # check the auto-generated fixup commits
git rebase -i --autosquash master

安装

安装 git absorb 最简单的方法是下载最新 标记版本 的工件。工件适用于 Windows、MacOS 和 Linux(基于 Ubuntu,使用静态链接的 libgit2 构建)。如果您需要尚未发布的提交,请检查 最新的 CI 工件 或提交问题。

或者,git absorb 在以下系统包管理器中可用

Packaging status
仓库 命令
Arch Linux pacman -S git-absorb
Debian apt install git-absorb
DPorts pkg install git-absorb
Fedora dnf install git-absorb
FreeBSD Ports pkg install git-absorb
Homebrew 和 Linuxbrew brewinstall git-absorb
MacPorts sudoport install git-absorb
nixpkgs stable 和 unstable nix-env-iA nixpkgs.git-absorb
openSUSE zypper install git-absorb
Ubuntu apt install git-absorb
Void Linux xbps-install-S git-absorb
GNU Guix guix install git-absorb

从源码编译

crates.io badge Build

您需要以下内容

然后 cargo install git-absorb。请确保 $CARGO_HOME/bin 在您的 $PATH 中,以便 git 可以找到该命令。($CARGO_HOME 默认为 ~/.cargo。)

注意,git absorb 不使用系统 libgit2。这意味着您不需要安装 libgit2 就可以构建或运行它。然而,这也意味着您必须能够构建 libgit2。(由于 最近的变化,CMake 已不再需要构建它。)

注意:当前 cargo install 未知如何安装手册页面(cargo#2729),因此如果您使用 cargo 进行安装,则 git absorb --help 将无法正常工作。这里有一个手动解决方案,假设您的系统有一个 ~/.local/share/man/man1 目录,该目录 man --path 已知

wget https://raw.githubusercontent.com/tummychow/git-absorb/master/Documentation/git-absorb.1
mv git-absorb.1 ~/.local/share/man/man1

用法

  1. 使用以下命令将您希望吸收的任何更改添加到版本控制中:git add。按照设计,git absorb 只会考虑 git 索引(暂存区)中的内容。
  2. 使用以下命令:git absorb。这将创建一系列提交到 HEAD。每个提交都将有一个 fixup! 消息,指示要合并的提交的消息(如果唯一)或 SHA。
  3. 如果对输出满意,可以使用 git rebase -i --autosquashfixup! 提交压缩到其前驱提交。如果您不需要编辑 rebase TODO 文件,可以设置 GIT_SEQUENCE_EDITOR 环境变量。
  4. 如果您不满意(或者发生了不好的事情),可以使用 git reset --soft 回到吸收前的提交以恢复旧状态。(您可以使用 git reflog 查找相关的提交。)如果您认为 git absorb 有问题,请 提交问题

工作原理(大致)

git absorb 通过检查两个补丁 P1 和 P2 是否 交换,即应用 P1 在 P2 之前是否会产生与应用 P2 在 P1 之前相同的结果。

git absorb 考虑从 HEAD 开始的一系列提交。第一个提交可以使用 --base <ref> 明确指定。默认情况下,将考虑最后 10 个提交(有关如何更改此设置,请参阅下文中的 配置)。

对于索引中的每个块,git absorb 将检查该块是否与最后一个提交交换,然后是前一个提交,等等。当它找到一个不与块交换的提交时,它推断这是此更改的正确父提交,并将块转换为修复提交。如果块与范围内的所有提交都交换,这意味着我们没有找到此更改的合适父提交;显示警告,该块仍然未提交到索引中。

配置

堆栈大小

在没有 --base 运行时,git-absorb 只会在一定范围内(默认为 10)搜索候选提交以修复。如果您遇到以下错误

WARN stack limit reached, limit: 10

编辑您本地的或全局的 .gitconfig 并添加以下部分

[absorb]
    maxStack=50 # Or any other reasonable value for your project

每个可修复提交一个修复

默认情况下,git-absorb将为每个可吸收的块生成单独的fixup提交。相反,可以使用-F标志为所有吸收到同一提交的块创建仅1个fixup提交。要始终具有此行为,请设置

[absorb]
    oneFixupPerCommit = true

如果未进行暂存,自动暂存所有更改

默认情况下,git-absorb只会考虑您通过git add添加到索引的文件。然而,有时人们想要尝试从所有更改中吸收,这需要首先通过git add .来暂存它们。为了避免这个额外步骤,请设置

[absorb]
    autoStageIfNothingStaged = true

这告诉git-absorb,在没有暂存任何更改的情况下,自动暂存所有更改,在可能的情况下创建fixup提交,并从索引中取消暂存剩余的更改。

fixup目标始终SHA

默认情况下,git-absorb将为fixup提交创建带有指向目标提交摘要的消息的提交,如果存在重复的摘要,将回退到指向目标的SHA。相反,可以通过以下方式始终指向目标的SHA

[absorb]
    fixupTargetAlwaysSHA = true

待办事项

  • 实现强制标志
  • 实现远程默认分支检查
  • 添加更小的强制标志以禁用单个安全检查
  • 停止使用failure::err_msg并确保所有错误输出都可供用户操作
  • 在成功情况下输出更多的日志信息
  • 更多测试(特别是主模块和集成测试)
  • 记录堆栈和通勤详情
  • 更多通勤情况(特别是复制/重命名检测)
  • 不要同时加载所有块到内存中,因为它们可能非常大
  • 实现某种索引锁定来保护对并发修改的保护

依赖项

~13–23MB
~418K SLoC