提醒 (2021)
2018 年原始答案:
我对 git 的主要问题是 git rebase --preserve-merges 非常慢
Git 2.20+(2018 年第四季度)可能不会那么慢,考虑到它包括对 C 中“rebase”机制的重写。
没有更多的 shell 脚本。
参见Pratik Karki (prertik)commit ac7f467、commit c7b64aa、commit 55071ea(2018 年 8 月 6 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 5ae5084,2018 年 11 月 2 日)
rebase:开始将其作为内置实现
此提交模仿用于将 difftool 转换为内置的策略。
我们首先将 shell 脚本 git-rebase.sh 重命名为 git-legacy-rebase.sh 并引入一个简单地执行 shell 脚本版本的 builtin/rebase.c,
除非配置设置 rebase.useBuiltin 设置为 true。
这背后的动机是重写所有的功能
前面提到的rebase.c中的shell脚本版本,一一对应
能够通过配置方便地测试新功能
rebase.useBuiltin.
在原来的difftool 转换中,如果sane_execvp() 试图
运行以非负状态返回的旧脚本版本,
命令静默退出,没有成功执行任何操作,但是
sane_execvp() 不应以非负状态返回
地方,所以我们用die()来通知这种异常情况。
我们故意避免直接读取配置以避免
当我们需要回退到时弄乱GIT_* 环境变量
exec() 执行 shell 脚本。
参见Ævar Arnfjörð Bjarmason (avar)commit 62c2393、commit d8d0a54(2018 年 11 月 14 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 4520c23,2018 年 11 月 18 日)
The documentation 现在声明:
rebase.useBuiltin:
如果git rebase,则设置为false 以使用旧版shellscript 实现。
默认为true,即使用C内置的重写。
C 重写首先包含在 Git 2.20 版中。
此选项提供了一个逃生舱口以重新启用旧版本,以防万一
在重写中发现了错误。
此选项和 shellscript 版本 git-rebase 将在未来的某个版本中删除。
如果你找到一些理由将此选项设置为 false 而不是一次性测试,你应该将行为差异报告为 git 中的错误。
在 Git 2.21(2019 年 2 月)中,“git rebase --merge”通过重用用于“git rebase -i”的内部机制重新实现。
参见commit 68aa495、commit c91c944、commit 7b76ac6、commit 899b49c、commit 45339f7、commit 5400677、commit 72ee673、commit c913c59(2018 年 12 月 11 日)Elijah Newren (newren)。
(由Junio C Hamano -- gitster -- 合并于commit 8fe9c3f,2019 年 2 月 7 日)
rebase:通过交互机制实现--merge
作为使 rebase 具有更统一行为的持续努力的一部分,通过在后者之上重新实现合并后端,修改合并后端以使其表现得像交互式后端。
交互式变基是根据cherry-pick而不是merge-recursive内置实现的,但cherry-pick默认情况下也会调用递归合并机制,并且可以接受特殊的合并策略和/或特殊的策略选项。
因此,确实没有必要同时拥有git-rebase--merge 和
git-rebase--interactive 了。
删除git-rebase--merge.sh,改为在builtin/rebase.c中实现。
rebase:定义线性化排序并强制执行
请参阅commit c91c944 了解性能。
此外,仍然是 Git 2.21(2019 年 2 月):“git rebase --merge”通过重用用于“git rebase -i”的内部机制重新实现。
参见Elijah Newren (newren)commit 29d03f8(2019 年 2 月 14 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit 6f07c7b,2019 年 2 月 14 日)
rebase:通过交互机制实现 --merge
作为使 rebase 具有更统一行为的持续努力的一部分,通过在后者之上重新实现合并后端,修改合并后端以使其表现得像交互式后端。
交互式rebase是根据cherry-pick而不是merge-recursive内置实现的,但是cherry-pick也调用了
默认情况下递归合并机制,可以接受特殊的合并策略和/或特殊的策略选项。
因此,确实没有必要同时拥有git-rebase--merge 和
git-rebase--interactive 了。
删除git-rebase--merge.sh,改为在builtin/rebase.c中实现。
这会导致一些经过深思熟虑但用户可见的微小更改:
- 进度输出已修改(参见 t3406 和 t3420 示例)
- 现在修复了一些已知的测试失败问题(参见 t3421)
- 在 rebase --merge 期间的 bash 提示现在是
REBASE-i 而不是 REBASE-m。
原因:提示是后端在使用中的反映;这允许用户使用适当的后端信息向 git 邮件列表报告问题,并允许高级用户
知道在哪里搜索相关的控制文件。 (见 t9903)
由于“git rebase --preserve-merge”已通过重用用于“git rebase -i”的内部机制重新实现,因此此 Git 2.22(2019 年第二季度)补丁很有趣:
见commit 460bc3c, commit 297b1e1, commit 0ea0847, commit 73fdc53, commit 3389853, commit 7d3488e, commit c44c246, commit 0609b74, commit 0609b74, commit 6023c92, commit 28dc09d, @17654391@, @92 2019 年)和 Phillip Wood (phillipwood) 的 commit fc4a673(2019 年 3 月 19 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit 7ba06bc,2019 年 5 月 13 日)
rebase -i:不分叉运行rebase --interactive
当内置 rebase 启动交互式 rebase 时,它会解析选项,然后重新打包它们并分叉 rebase--interactive。
将cmd_rebase__interactive() 中的选项解析从业务逻辑中分离出来,以允许通过直接调用run_rebase_interactive() 来运行交互式rebase 而无需分叉rebase__interactive。
在不分叉的情况下启动交互式变基可以轻松调试
测序仪无需担心附加到孩子身上
进程。
Ævar 还报告了一些rebase perf tests are 30% faster。
此补丁还可以轻松删除cmd_rebase__interactive()
git-legacy-rebase.sh 和 git-rebase--preserve-merges.sh 退休的未来。
“git rebase -i”(和朋友们)过去常常不必要地检查要重新设置的分支的尖端,这已在 Git 2.26(2020 年第一季度)中得到纠正,
参见 Alban Gruin (``) 的 commit 767a9c4(2020 年 1 月 24 日)。
(由 Junio C Hamano -- gitster -- 合并到 commit d8b8d59,2020 年 2 月 14 日)
报告人:SZEDER Gábor
签字人:Alban Gruin
使用基于定序器的变基(即rebase -i、rebase -r 或rebase -m)时首先要做的事情之一就是创建一个待办事项列表。
这需要知道 rebase 的提交范围。
要获取范围的最后一次提交的 oid,使用prepare_branch_to_be_rebased() 检出要变基的分支的尖端,然后读取头部的 oid。
在此之后,分支的尖端甚至没有被修改。另一方面,“am”后端不签出分支。
在大型存储库中,这是性能损失:rebase -i', the user may have to wait before editing the todo list while git is extracting the branch silently, and "quiet" rebases will be slower than am'。
由于我们在opts->orig_head中已经有了分支尖端的oid,所以切换到这个提交是没有用的。
这将删除do_interactive_rebase() 中对prepare_branch_to_be_rebased() 的调用,并添加一个orig_head' parameter to get_revision_ranges()`。
prepare_branch_to_be_rebased() 被删除,因为它不再使用。
这引入了一个可见的变化:因为我们没有将分支的尖端切换到 rebase,所以在 rebase 的开头没有为它创建 reflog 条目。
对linux.git 进行的不科学性能测量如下:
在这个补丁之前:
$ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50
real 0m8,940s
user 0m6,830s
sys 0m2,121s
在这个补丁之后:
$ time git rebase -m --onto v4.18 463fa44eec2fef50~ 463fa44eec2fef50
real 0m1,834s
user 0m0,916s
sys 0m0,206s
作为 Git 2.26(2020 年第一季度)的注释,“git rebase”已学会默认使用合并后端(即驱动“rebase -i”的机器),同时允许使用“--apply”选项“apply”后端(例如“format-patch piped to am”的道德等价物)。
rebase.backend 配置变量可以设置为自定义。
见commit 10cdb9f、commit 2ac0d62、commit 8295ed6、commit 76340c8、commit 980b482、commit c2417d3、commit 6d04ce7、commit 52eb738、commit 8af14f0、@987654412、@、@987654412、@989 @、commit 93122c9、commit 55d2b6d、commit 8a997ed、commit 7db00f0、commit e98c426、commit d48e5e2(2020 年 2 月 15 日)和commit a9ae8fd、commit 22a69fd(2020 年 1 月 16 日)@987654。 br>(由 Junio C Hamano -- gitster -- 合并于 commit 8c22bd9,2020 年 3 月 2 日)
rebase: 重命名两个主要的 rebase 后端
签字人:Elijah Newren
将“交互式”后端重命名为“合并”,因为:
- 'interactive' 作为一个名字引起了混淆;此后端已用于多种非交互式 rebase,并且考虑到我们将其设为默认值,未来可能会用于更多非交互式 rebase,而不是交互式 rebase。
- “交互”不是基本策略;合并是。
- 存储状态的目录不是
.git/rebase-interactive,而是.git/rebase-merge。
使用 Git 2.27(2020 年第二季度),您还可以允许“git rebase”重新应用所有本地提交,即使它们可能已经在上游,而无需先检查。
git rebase --reapply-cherry-picks
这将加速变基过程。
参见Jonathan Tan (jhowtan)commit 0fcb4f6(2020 年 4 月 11 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit d6d561d,2020 年 4 月 22 日)
签字人:Jonathan Tan
签字人:Elijah Newren
当针对自原始分支创建以来已多次提交的上游进行 rebase 时:
O -- O -- ... -- O -- O (upstream)
\
-- O (my-dev-branch)
它必须读取每个新的上游提交的内容,除了上游的尖端和合并基础,因为“git rebase”试图排除与上游重复的提交。
这可能会对性能造成重大影响,尤其是在部分克隆中,其中对对象的读取可能最终成为提取。
将标志 --reapply-cherry-picks 添加到“git rebase”以允许禁止此功能。
此标志仅在使用“merge”后端时有效。
此标志更改 sequencer_make_script() 的行为,从 do_interactive_rebase() run_rebase_interactive() run_specific_rebase() cmd_rebase() 调用。使用此标志,limit_list()(从sequencer_make_script() 到prepare_revision_walk() 间接调用)将不再调用cherry_pick_list(),因此不再设置PATCHSAME。
避免设置PATCHSAME既意味着不再读取上游的中间提交(如测试所示),也意味着sequencer_make_script()不会直接或通过@987654573完成PATCHSAME导致的提交跳过@。
在 Git 2.30(2021 年第一季度)中,“git-parse-remote”shell 脚本库已经过时了。
见commit 66d36b9(2020 年 11 月 24 日)Jeff King (peff)。
请参阅Ævar Arnfjörð Bjarmason (avar) 的commit a89a2fb、commit e63f7b0、commit 1c15180(2020 年 11 月 14 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit e89ecfb,2020 年 12 月 3 日)
签字人:Ævar Arnfjörð Bjarmason
前两次提交删除了该库中最后一次使用的函数,但其中大部分已经有一段时间是死代码了。
只有"get_default_remote" 函数仍在使用中。
尽管我们有这个库的手册页,但它从未打算(或者实际上我期望)在git.git 之外使用。让我们删除它,如果有人仍然关心这里的功能,他们可以将它们拉入自己的项目中。
-
最后一次使用error_on_missing_default_upstream():
d03ebd411c ("rebase: 移除 rebase.useBuiltin 设置",
2019-03-18)
-
上次使用get_remote_merge_branch():49eb8d39c7 ("Remove> contrib/examples/*", 2018-03-25)
-
https://lore.kernel.org/git/87a6vmhdka.fsf@evledraar.gmail.com/
使用 Git 2.32(2021 年第 2 季度),删除了过去使用脚本化 git rebase 的最终提示。
参见Ævar Arnfjörð Bjarmason (avar)commit 9bcde4d(2021 年 3 月 23 日)。
(由 Junio C Hamano -- gitster -- 合并于 commit dc2a073,2021 年 3 月 30 日)
rebase: 移除临时 rebase.useBuiltin 设置和环境
签字人:Ævar Arnfjörð Bjarmason
签字人:Johannes Schindelin
删除 rebase.useBuiltin 设置和现已过时的 GIT_TEST_REBASE_USE_BUILTIN 测试标志。
这是在我的d03ebd4 之后保留的(“rebase:删除 rebase.useBuiltin 设置”,2019-03-18,Git v2.22.0-rc0 -- merge 在batch #5 中列出)帮助任何使用实验标志并想知道它是默认标志的人,或者他们应该将他们的测试环境转换为无条件地使用内置 rebase。
对于这些用户来说,了解这一点已经足够长了。
所以移除所有在d03ebd4之后留在原地的脚手架。
我还删除了文档条目,如果有人在他们的配置中仍然有这个,他们可以做一些源考古来弄清楚它曾经做什么,这比让每个阅读文档的 Git 用户都暴露于这个遗留配置开关更有意义.