You write:
One important fact in my scenario is that both branches are completely unrelated. No commit of either branch affects patches of the other branches' commits => There will be no conflicts.
Of course, the "splicing" operation you suggest is probably a bad idea if you anticipate that many conflicts will arise. Let's assume that, indeed, nothing bad will happen.
If, at the beginning, your repo looks like this
A---B------C--D [branch1]
X---Y--Z [branch2]
you can follow the procedure outlined below to automatically "splice" commits from both branches into a single branch, while maintaining chronological order.
"Splicing" two unrelated branches
Make sure you're in a clean working state; then check out branch1 and merge branch2 into it:
git checkout branch1
git merge branch2
That will yield
A---B------C--D---E [HEAD=branch1]
/
X---Y--Z------- [branch2]
Now, I know that's not what you want, but bear with me for a second. We will use merge commit E to have access to "the ancestry on both sides" at once.
Check out branch2 and reset it to commit A.
git checkout branch2
git reset --hard A
You'll be in the following situation:
A [HEAD=branch2]
\
---B------C--D---E [branch1]
/
X---Y--Z-------
Generate a list (in chronological order) of all the non-merge commits reachable from branch1 but not from branch2:
git rev-list --no-merges --reverse branch2..branch1
This should yield the following list of commits: X, B, Y, Z, C, D; commit E, which was created in Step 1 will not be in that list, because we used the --no-merges flag.
Cherry-pick those commits on top of branch2 (A).
git cherry-pick `git rev-list --no-merges --reverse branch2..branch1`
Your repo will then look as follows:
A--X'--B'--Y'--Z'--C'--D' [HEAD=branch2]
\
---B-----C-D---E [branch1]
/
X---Y-Z------
Delete branch1:
git branch -D branch1
Edit: As you correctly remarked, because branch1 is not fully merged into the current branch (branch2), using just -d won't do, here; you need to use the -D flag instead.
Your repo will then simply be
A--X'--B'--Y'--Z'--C'--D' [HEAD=branch2]
(Optionally) Rename branch2:
git branch -m branch2 <more_meaningful_name>
Generalization to more than two branches
Let's assume you have n completely unrelated branches: branch1, branch2, ..., branchn, where branch1 corresponds to the branch whose root commit is the oldest commit in the entire repository; Let's call that commit A.
A ----- o ---- o [branch1]
o ----- o ---- o -- o [branch2]
...
o ----- o - o [branchn]
If you don't know which commit is A, you can identify it by running
git rev-list --reverse --max-parents=0 --all
The commit ID of A will be the first listed in the output of that command. And you can identify which branch is branch1 by running:
git branch -r --contains `git rev-list --reverse --max-parents=0 --all | head -1`
Then the procedure outlines in the two-branch case becomes:
Create a commit that has access to the ancestry of all branches, by merging all branches other than branch1 into branch1.
(same as in two-branch case)
- (same as in two-branch case)
- (same as in two-branch case)
- Delete all branches other than
branch2.
- (same as in two-branch case)