我有一个功能分支,有很多提交。
A---B---C master
\
\-B'---C'---D'...---Z' feature
我正在研究feature
,但另一位开发人员创建了提交B
和C
。现在我想在提交feature
时重新设置C
,但是我和/或automerge在rebase期间引入了错误。我的项目有非常好的测试覆盖率,我可以使用ant rebuild test
从控制台运行测试,现在我想让git告诉我哪个提交是第一次破坏我的测试的提交,所以我可以修复该提交。我怎样才能做到这一点?
当你在分支机构feature
执行:
git rebase --interactive --exec "ant rebuild test" C
这将导致git在提交C上再次启动,在顶部重放您的工作,它将在重放阶段应用的每次提交后运行您的测试。
如果您的测试失败,希望您的ant任务将具有非零退出代码。在这种情况下,一旦测试失败,git就会停止。您立即处于正确的位置以修改您的提交,以便测试将再次开心。修改后,像往常一样执行git rebase --continue
,git将继续检查你所有的提交。
在Git 2.9中引入,您现在可以使用-x
选项为每个提交执行命令,而不必添加--interactive
。
你现在可以运行git rebase -i --exec "cmd1 && cmd2 && ..."
而不是运行git rebase -x "cmd1 && cmd2 && ..."
。
要添加到OP yankee的excellent answer,Git 2.5+将提供更强大的git rebase --interactive --exec
体验,特别是在执行失败的情况下。
实际上,请在本答案的最后部分看到Git 2.21的新--reschedule-failed-exec
。
请参阅commit b12d3e9 [commit 1d968ca] [2015年5月22日]和Matthieu Moy (moy
) [2015年5月22日]。
(Junio C Hamano -- gitster
--在commit a6be52e合并,2015年6月1日)
'
exec
'命令将当前提交发送到stopped-sha
,它应该包含原始提交(在rebase之前)。 因此,如果'exec
'命令失败,则下一个'git rebase --continue
'将发送当前提交作为post-rewrite hook。
完整文档:
rebase -i
:使用失败的post-rewrite
命令修复exec
钩子通常,当'
git rebase
'在完成rebase之前停止时,它将为用户提供编辑提交的机会(例如使用'edit
'命令)。 在这种情况下,'git rebase
'使提交的sha1在"$state_dir"/stopped-sha
中被重写,随后的'git rebase --continue
'将使用这个sha1调用post-rewrite
钩子作为<old-sha1>
钩子的post-rewrite
参数。由于'
git rebase
'命令失败而导致'exec
'停止的情况不同:它为用户提供了检查或修复失败的机会,但并没有停止说“这是一个提交编辑,当你使用时使用--continue
完成”。 所以,没有理由为'exec'命令调用post-rewrite
钩子。 如果用户确实重写了提交,那么它将使用已经调用git commit --amend
钩子的'post-rewrite
'。将行为修复为:
- 如果
stopped-sha
命令失败,请不要留下exec
文件,- 如果没有找到
git rebase --continue
文件,并教'record_in_rewritten
'跳过stopped-sha
。
为了便于管理与rebase相关联的失败的exec指令,Git 2.21(2019年第一季度)引入了--reschedule-failed-exec
和“git rebase -i
”,它学会了重新执行一个命令'exec
',以便在最后一次失败后运行。
参见commit 81ef8ee,commit 969de3f,commit d421afa,Johannes Schindelin (dscho
)(2018年12月10日)。
(由Junio C Hamano -- gitster
--合并于commit d9d9ab0,2019年1月29日)
rebase
:介绍--reschedule-failed-exec
--exec
选项的一个常见用例是验证主题分支中的每个提交是否通过git rebase -x make <base>
完全编译。然而,当这样的rebase中的
exec
失败时,它不会被重新安排,在这种情况下并不是特别有用。让我们提供一个标志来重新安排失败的
exec
命令。基于Paul Morelle的想法。
git rebase
man page现在包括:
--reschedule-failed-exec:: --no-reschedule-failed-exec::
自动重新安排失败的
exec
命令。 这只适用于交互模式(或提供--exec
选项时)。
和:
rebase
:介绍--reschedule-failed-exec
的捷径在
--reschedule-failed-exec
之前写出-x <cmd>
选项有点麻烦;让我们介绍一个方便的选项,同时做两个:-y <cmd>
。
注意:第一次在commit e11ff89中查看commit 81ef8ee(2019年2月6日)和Johannes Schindelin (dscho
)(2018年12月10日)。
(由Junio C Hamano -- gitster
--合并于commit b966813,2019年2月9日)
还原“rebase:为--reschedule-failed-exec引入快捷方式”
这个补丁仅作为一个暂定的“我们可以引入一个方便的短期选项,如果我们不想改变长期的默认行为”补丁,打开讨论是否其他人同意弃用当前行为以支持重新安排行为。
但是在Git邮件列表上的共识是,在不久的将来显示警告是有意义的,并且默认情况下将默认的
rebase.rescheduleFailedExec
翻转为重新安排失败的exec
命令。因此,让我们回过头来补充我们同意的
-y
短期选项的补丁是不必要或不可取的。
同样在Git 2.21(2019年2月):“git rebase -x $cmd
”没有拒绝多行命令,即使该命令无法处理这样的命令。
它现在被拒绝了。
参见commit c762aad的Phillip Wood (phillipwood
)(2019年1月29日)。
(由Junio C Hamano -- gitster
--合并于commit 96e6547,2019年2月7日)
rebase -x
:健全检查命令如果用户给
--exec
一个空参数,那么git会创建一个无法解析的待办事项列表。在出错之前,rebase开始运行:error: missing arguments for exec error: invalid line 2: exec You can fix this with 'git rebase --edit-todo' and then run 'git rebase --continue'. Or you can abort the rebase with 'git rebase --abort'.
而是在启动rebase之前检查空命令。
还要检查该命令是否包含任何换行符,因为待办事项列表格式无法处理多行命令。 请注意,这会改变行为,在此更改之前可以执行以下操作:
git rebase --exec='echo one exec echo two'
它会在todo
列表中插入两个exec行,现在它会出错。
使用Git 2.23,配置变量rebase.rescheduleFailedExec
只应在运行交互式rebase时有效,并且在运行非交互式rebase时不应影响任何内容,但实际情况并非如此。
这已得到纠正。
参见commit 906b639撰写的Johannes Schindelin (dscho
)(2017年7月1日)。
(由Junio C Hamano -- gitster
--合并于commit 64096fb,2017年7月11日)
rebase --am
:忽略rebase.rescheduleFailedExec
exec
命令特定于交互式后端,因此非交互式rebase注意配置设置没有意义。当然,如果使用
--reschedule-failed-exec
启动非交互式rebase,我们仍然想要错误。Vas Sudanagunta通过commit 969de3f报道。