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

问题描述 投票:7回答:3

我将3个不同的git仓库合并为一个现在我的历史看起来像这样:

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

现在,我想按日期重新排列所有这些提交。所以最后可能是这样的C1-A1-A2-B1-C2 -...您的想法

如果我删除所有原始SHA提交ID,我很好。当然,我无法手动进行重新排序,因此我需要一些脚本或一些想法来解决此问题。

git rebase git-rebase
3个回答
-1
投票

如果不手动进行操作,将无法重新排列A1-A2-A3-B1-B2-B3-C1-C2-C3


7
投票

[这只是一个想法,我没有对此场景进行测试,但我将它(以另一种方式)用于join two Git repositories and keep the original commit dates

如果历史有分支和合并,我认为不可能重新排序它们并保留结构,甚至是手工的。您可以获得的最好的是线性历史记录。

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

%at

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

$ git log --pretty='%H %at %ct' --author-date-order --reverse > /tmp/hashlist

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

$ git log --pretty='%H %at %ct' | sort -k 2 > /tmp/hashlist

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

将旧存储库作为远程存储库添加到新存储库中,获取其所有提交。 DO NOT设置新存储库的$ GIT_COMMITTER_DATE='2010-01-01 12:00:00' GIT_AUTHOR_DATE='2010-01-01 12:00:00' git commit --allow-empty 分支以跟踪旧存储库之一。

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

master

如果您不想保留原始作者日期或提交者日期(或两者都保留,则只需从上面的命令行中删除相应的作业即可。

将新脚本与$ echo 'GIT_AUTHOR_DATE=@$2 GIT_COMMITTER_DATE=@$3 git cherry-pick $1' > /tmp/pick $ chmod +x /tmp/pick 一起使用,以选定顺序选择每个提交,并将其提交到新的master分支之上。

xargs

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

$ cat /tmp/hashlist | xargs -n 3 /tmp/pick

备注:

  • 您将获得线性历史记录。原始的分支和合并将不会重新创建到新的历史记录时间轴中。
  • 未合并的分支根本不会被复制。您可以使用$ rm /tmp/hashlist $ rm /tmp/pick 复制并将它们附加到新提交。
  • 即使您的回购没有分支机构,也仍然很可能在樱桃精选上引起冲突;这取决于新顺序中的提交所引入的许多更改。
  • 如果不起作用,您可以随时删除新的存储库并重新开始(或退出尝试);旧的存储库未更改。

0
投票

通过交互式变基点重新排序

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

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

master

创建所有提交的列表。此命令将按照作者时间(最早的时间)对其进行排序。

git checkout -b master2 master

输出文件看起来像:

git log --pretty='%H %at' | sort -k2 -n | awk '{ print "pick "$1 }' > /tmp/rebase.list

一直运行交互式资源库,直到存储库的根目录

pick <hash of C1>
pick <hash of A1>
pick <hash of A2>
pick <hash of B1>
..

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

解决了冲突之后,您应该以:r /tmp/rebase.list分支结束,并重新排列所有提交。

© www.soinside.com 2019 - 2024. All rights reserved.