This is just an idea, I have not tested it for this scenario , but I used it (in a different way) to attach two Git repositories and keep the original commit dates .
If there are branches and merges in the story, I think it is impossible to reorder them and preserve the structure, even the manual one. The best you can get is a linear story.
Save the commit hashes and timestamps ( %ct = commit date, %at = author date) to a file, sort them by author date:
$ git log --pretty='%H %at %ct' --author-date-order --reverse > /tmp/hashlist
If the order specified in the above command does not satisfy you, then force the result using its second field (author date):
$ git log --pretty='%H %at %ct' | sort -k 2 > /tmp/hashlist
Create a new repository to store the story, sorted by author date. Create an initial commit commit commit date in the past (before the oldest commit in your repository):
$ GIT_COMMITTER_DATE='2010-01-01 12:00:00' GIT_AUTHOR_DATE='2010-01-01 12:00:00' git commit --allow-empty
Put your own date on the above command.
Add the old repository as a remote to the new one, extract all its commits. DO NOT set the master branch of the new repo to track one of the old repos.
Create a script in which the cherry selects the provided commit and applies it on top of the current branch, saving the date of the original author and the date of fixation:
$ echo ' GIT_AUTHOR_DATE=@ $2 GIT_COMMITTER_DATE=@ $3 git cherry-pick $1' > /tmp/pick $ chmod +x /tmp/pick
If you do not want to save the date of the original author or the date of the committer (or both), simply remove the corresponding assignment from the command line above.
Use a new script with xargs to select each commit in the selected order and move it over the new main branch.
$ cat /tmp/hashlist | xargs -n 3 /tmp/pick
If all goes well, delete the temporary files created during the process.
$ rm /tmp/hashlist $ rm /tmp/pick
Notes:
- You will get a linear story. Source branches and merges will not be recreated into a new history chronology.
- Unarmed branches will not be copied at all. You can use
git rebase to copy and attach them to new commits. - Even if your repo has no branches, there is still a high probability of conflicts when choosing a cherry; it depends on many changes made by commits to the new order.
- If it does not work, you can always delete a new repository and start from it (or exit it); The old repository does not change.