There\'re few question about \"flattening merge\" on StackOverflow, with an answer usually being \"git rebase\". These answers though miss one crucial point - order of commi
After some thinking, I figured out how to do How do I run git rebase --interactive in non-interactive manner? , which also provides completely scripted solution for this question.
1. Bring 2 branches from different repositories into one repository (git remote add + git fetch)
2. Rebase (non-interactively) one branch on top of another (order matters, consider first commit of which branch you'd like to have as first commit of consolidated branch).
3. Prepare following script (rebase-reoder-by-date
):
#!/bin/sh
awk '
/^pick/ {
printf "%s %s ", $1, $2;
system("echo -n `git show --format='%ai' -s " $2 "`");
for (i = 3; i <= NF; i++) printf " %s", $i; printf "\n";
}
' $1 | sort -k3 > $1.tmp
mv $1.tmp $1
4. Run: GIT_SEQUENCE_EDITOR=./rebase-reoder-by-date git rebase -i <initial commit>
Disclaimer: all these operations should happen on copies of original repositories, review/validate/test combined branch to make sure it is what you expected and contains what you expect, keep backups handy.
[See my another answer for completely automated solution. I'd leave this as an example of path which led for ultimate solution, in case someone will face similar not-so-obvious to solve task.]
Ok, this is not real answer to the question (fully scripted, automated solution), but thinking and example how (interactive rebase based) processing can be automated.
Well, first of all, for the ultimate solution git filter-branch --parent-filter
looks like exactly what's needed. Except that my git-fu doesn't allow me to wrote, 1-, 2-, or 3-liner with it, and approach to write standalone script to parse thru all revisions is not cool and more effortful than rebase -i.
So, rebase -i could be used efficiently if author dates of commit were visible. My first thought was to temporarily patch commit messages to start with author date using git filter-branch --msg-filter
, run rebase -i, then unpatch messages back.
Second thought though was: why bother, better to patch rebase commit list as used by rebase -i. So, the process would be:
git rebase -i
awk '/^pick/ {printf "%s %s ", $1, $2; system("echo -n git show --format='%ai' -s " $2 "
"); for (i = 3; i <= NF; i++) printf " %s", $i; printf "\n"; }' git-rebase-todo > git-rebase-todo.new; mv git-rebase-todo.new git-rebase-todo
sort -k3 git-rebase-todo >git-rebase-todo.new; mv git-rebase-todo.new git-rebase-todo
Voila! Actually, this could be completely scripted if git rebase -i
could work in "non-interactive" mode, I submitted How do I run git rebase --interactive in non-interactive manner? for that.
Actually, If I understand correctly, you can achieve this easily with git-stitch-repo.
What is the problem with leaving seperate development in seperate lines up until they were merged? If they were seperate, then they were seperate.
There are many ways to view the history in chronological order without hacking the history as you're trying. Have you tried git log --pretty --date-order
?