我有一个git分支B
,它比它的祖先A
提前了大约100次提交。对于这100个提交中的每一个,我想运行一个脚本:
1.运行一个现有的脚本edit.sh
,对一个源文件进行大约一千次自动搜索和替换编辑。
1.将原始提交的SHA附加到基于变更的提交的提交消息中。
除了这两个自动化的步骤,我不想在变基过程中做任何更改。
我可以通过git rebase -i
运行脚本并重写提交消息100次来手动完成这一任务,但是有什么好的方法可以自动完成整个任务呢?(不需要手动命令或编辑这100个提交中的每一个。
不过,我确实需要在历史中保留所有100个提交,因为我的分支不是一个功能分支。相反,我们的repo是另一个repo的分支,我的分支正在上游捕获我们的分支。能够在我的fork历史中显示每个上游提交是非常有帮助的,即使内容有点不同。但首先我需要修改这些提交以匹配我们的fork中的更改!
请注意,我们希望在forked repo中保持线性历史,因此我们正在rebase而不是使用merge commits。到目前为止,我们一直通过git rebase --onto
来实现这一点,它对所有文件都运行得很好,除了一个文件,这个文件在我们的fork中有太多的更改,以至于在其变基期间处理合并冲突是一个巨大的痛苦。
我只是在上游仓库中合并了一个PR,这将使有问题的文件与我们的fork更加相似。该PR中的更改通过此脚本自动执行。我证实了重新设定文件的基础变得容易多了。但是在此期间,我从upstream=>fork向port(又名git rebase --onto
)提交了大约100次,直到fork赶上upstream中的PR。
因此,我在这里尝试做的是创建一个本地分支,其中包含100个新提交,这些提交与上游的最后100个提交相同,除了在每个提交中,我使用创建上游PR时使用的脚本重写这些提交中的有问题的文件。然后,我可以对这个临时本地分支进行交互式的重新基化,这样就可以更容易地处理合并冲突。
更多信息(无需阅读)
顺便说一句,这里有更多关于我们为什么这样做的背景:
我是两个开源仓库的维护者之一:JavaScript repo tc39/proposal-temporal和该repo的TypeScript端口:js-temporal/temporal-polyfill。
JS repo是我们团队的“主要”repo:改变起源于那里,并且随后被移植到TS存储库。理想情况下,它可以以相反的顺序完成,所以我们可以自动化TS=>JS步骤,但repo是对JavaScript本身进行更改的建议。拥有JavaScript规范的ECMA TC 39标准委员会将不赞成使用TypeScript编写的JavaScript功能的引用polyfill。:-)所以我们需要维护两个polyfill:一个是标准委员会的JavaScript,一个是生产使用的TypeScript。
在大多数情况下,这个过程工作正常:TS repo将JS repo设置为远程,我们从JS repo获取提交并使用git rebase --onto
将提交重播到TS repo上。(我们实际上使用了一些由维护者编写的很酷的tools来使这种重基化更容易。
如果我们能够移植这100个提交,那么将来维护这个分支将会容易得多!
1条答案
按热度按时间bxjv4tth1#
一种可能的方法是创建一个脚本,通过利用
GIT_SEQUENCE_EDITOR
环境变量(即I mentioned here)来自动化变基过程。该变量允许我们以编程方式更改rebasetodo-list
,这是将在rebase操作期间应用的提交列表。下面是这样一个脚本的示例:
字符串
该脚本定义了一个
process_commit
bash函数,该函数将在变基期间为每次提交调用。该函数运行您的edit.sh
脚本,使用这些更改修改提交,并将原始提交SHA附加到提交消息。它使用
git rebase --onto target_branch source_branch^
命令启动rebase操作,该命令将来自source_branch
的提交重新应用到target_branch
上。-x
标志告诉git对每个被重新应用的提交执行一个shell命令。shell命令是对
bash -c "process_commit $GIT_COMMIT \"$(git log --format=%B -n 1 $GIT_COMMIT)\""
的调用。该命令在每次重新应用提交时执行一次。GIT_COMMIT
变量由git提供,包含被重新应用的提交的SHA。git log --format=%B -n 1 $GIT_COMMIT
命令检索原始提交消息。请将
/path/to/edit.sh
替换为edit.sh
脚本的实际路径,并将target_branch
和source_branch^
替换为实际的分支名称。该脚本应该会自动执行整个变基过程。但是,请注意,如果分支之间存在任何合并冲突,它仍然可能会停止。