Rebase是一个错误的工具,但是Git并没有为你的工作提供正确的工具,因为这个工作。。。Git从来没有设计过这样的功能
做
.
不过,吉特
可以
去做吧。这只是使用底层组件的问题,而不是任何面向用户的顶级(“瓷器”)命令。
我可以想到的方法是对所有提交进行git归档(或git diff和根提交),对它们进行排序,并创建一个全新的历史记录。有更好的方法吗?
使用
git archive
会是
可以
,但这项工作超出了需要。使用
git diff
每一次都会有更多的工作要做,而且不太合适。
最简单的方法是使用
git commit-tree
.这是一个低级(“管道”)命令,需要三个输入:
-
它需要一个
父哈希ID列表
。在父提交(单数)时,您将选择第一次提交的根提交,然后选择您刚刚为每个后续提交所做的最后一次提交。
-
它需要一个(单一的)
树哈希ID
用于将源树存储在提交中。对于每一次新的提交,您都将选择与当天提交相关联的源代码树。
-
最后,它需要一个
提交消息
.你可以把当天的承诺信息反馈给它。
您可能还希望覆盖提交人和提交人日期以及作者和作者日期的默认设置。你可以从四个到六个独立的环境变量,
GIT_AUTHOR_NAME
,
GIT_AUTHOR_EMAIL
,
GIT_AUTHOR_DATE
,以及相应的三个变量
COMMITTER
代替
AUTHOR
.或者,在tcsh/bash大括号扩展语法中,
GIT_{AUTHOR,COMMITTER}_{NAME,EMAIL,DATE}
.获取这些值的地方将是您转换的原始提交。
总体而言,您的脚本可能如下所示:
last=$root # find and set the root commit hash ID
for commit in $(get-list-of-original-commits-to-copy-in-new-order); do
set_author_and_committer $commit # set-and-export GIT_{AUTHOR,COMMITTER}_*
new=$(git log --no-walk --format=%B $commit |
git commit-tree -p $last ${commit}^{tree})
last=$new
done
git branch rewrite $last
(未经测试,需要编写一些函数)。这个
git log --no-walk --format=%B
提取表单中的原始提交消息
git提交树
需要,以及
git提交树
默认情况下从stdin读取提交消息,因此这里没有特殊工作。我们只是通过
-p
以及通过符号方法指定与被复制的提交相关联的树的树散列(参见
the gitrevisions documentation
).
用于设置和导出
GIT_*
变量可以在
the old
git filter-branch
script
.
请注意,此脚本会破坏提交中的任何GPG签名;处理它们需要一些更高级的东西。