按日期重新排序git提交历史记录

Bli*_*1eg 7 git rebase git-rebase

我已经将3个不同的git repos合并为一个,现在我的历史看起来像这样:

A1-A2-A3-B1-B2-B3-C1-C2-C3

现在我想按日期重新排序所有这些提交.所以最后它可能像C1-A1-A2-B1-C2 -...你明白了

如果我放弃所有原始SHA提交ID,我没问题.当然我不能手工重新排序,所以我需要一些脚本或一些想法如何解决这个问题.

小智 10

通过交互式变基重新排序

假设您只想更改一个分支 ( master) 上的提交顺序。

创建分支的副本。此步骤是可选的,您可以直接在分支上执行master

git checkout -b master2 master
Run Code Online (Sandbox Code Playgroud)

创建所有提交的列表。此命令将按作者时间对它们进行排序,最旧的在前。

git log --pretty='%H %at' | sort -k2 -n | awk '{ print "pick "$1 }' > /tmp/rebase.list
Run Code Online (Sandbox Code Playgroud)

输出文件如下所示:

pick <hash of C1>
pick <hash of A1>
pick <hash of A2>
pick <hash of B1>
..
Run Code Online (Sandbox Code Playgroud)

运行交互式变基,一直返回到存储库的根目录

git rebase -i --root
Run Code Online (Sandbox Code Playgroud)

您将看到当前的提交列表。删除所有内容并加载文件内容rebase.list(如果您的编辑器恰好是 vi,请发出命令:1,$d:r /tmp/rebase.list)。保存并退出。

解决冲突后,您应该最终得到master2所有提交都重新排序的分支。


axi*_*iac 7

这只是一个想法,我没有为这个场景测试它,但我使用它(以不同的方式)加入两个Git存储库并保留原始提交日期.

如果历史记录有分支和合并,我认为不可能重新排序它们并保持结构,甚至手动.你能得到的最好的是线性历史.

将提交哈希值和时间戳(%ct=提交日期,%at=作者日期)保存到文件中,按作者日期对其进行排序:

$ git log --pretty='%H %at %ct' --author-date-order --reverse > /tmp/hashlist
Run Code Online (Sandbox Code Playgroud)

如果上述命令提供的顺序不满足您,则通过使用其第二个字段(作者日期)对输出进行排序来强制执行该顺序:

$ git log --pretty='%H %at %ct' | sort -k 2 > /tmp/hashlist
Run Code Online (Sandbox Code Playgroud)

创建一个新存储库以保存按作者日期排序的历史记录.创建一个初始提交设置过去的提交者日期(在存储库中最早的提交之前):

$ GIT_COMMITTER_DATE='2010-01-01 12:00:00' GIT_AUTHOR_DATE='2010-01-01 12:00:00' git commit --allow-empty
Run Code Online (Sandbox Code Playgroud)

将您自己的日期放入上面的命令.

将旧存储库作为远程存储库添加到新存储库中,获取其所有提交.不要设置master新仓库的分支来跟踪旧仓库中的一个.

创建一个脚本,它将挑选提供的提交并将其应用于当前分支,保留原始作者日期和提交日期:

$ echo 'GIT_AUTHOR_DATE=@$2 GIT_COMMITTER_DATE=@$3 git cherry-pick $1' > /tmp/pick
$ chmod +x /tmp/pick
Run Code Online (Sandbox Code Playgroud)

如果您不想保留原始作者日期或提交者日期(或两者),则只需从上面的命令行中删除相应的分配.

使用新脚本xargs选择所选顺序中的每个提交,并将其提交到新主分支之上.

$ cat /tmp/hashlist | xargs -n 3 /tmp/pick
Run Code Online (Sandbox Code Playgroud)

如果一切顺利,则删除在此过程中创建的临时文件.

$ rm /tmp/hashlist
$ rm /tmp/pick
Run Code Online (Sandbox Code Playgroud)

备注:

  • 您将获得线性历史记录.原始分支和合并不会重新创建到新的历史时间轴中.
  • 根本不会复制未合并的分支.您可以使用git rebase它们复制并将它们附加到新提交.
  • 即使您的回购没有分支机构,仍然很有可能在樱桃选择上发生冲突; 它取决于新订单中提交引入的大量更改.
  • 如果它不起作用,您可以随时删除新的存储库并重新开始(或退出尝试); 旧存储库不会更改.

  • 这对我来说效果很好。我不需要初始空提交, git fetch 在空仓库上工作,并且对于cherry-pick,我添加了 `--strategy=recursive --strategy-option=theirs` 选项以避免合并冲突。重新排列了多个存储库,并且在发表此评论时它与 git 版本 2.23.0 一起工作。 (2认同)

小智 -5

如果不手动执行,则无法重新排列 A1-A2-A3-B1-B2-B3-C1-C2-C3