I recently wanted to merge two git repositories together again. TL;DR for the intent behind this, the two repos were so closely related that a change in one repo meant a change / bump in the other one. To me it made sense to just put them together as it makes no sense adding artificial boundaries that make development harder and more error-prone.
How I did it ?
Well, I came across a nifty tool called Josh (Just a Single History ; see here).
It is a tool that does things similar to git filter-branch
if you ever dove
into this rabbit hole.
See here an example to filter a repo.
In my case I had a repo A that I wanted to integrate into repo B.
I needed to rewrite repo B into a subfolder b
and repo A in subfolder a
.
I used the following in repo B :
First let's move B into subfolder b
.
# puts branch into FETCH_HEAD
git fetch origin main
# Puts rewritten branch into FILTERED_HEAD
josh-filter ':prefix=b' FETCH_HEAD
# Let's check this out
git switch FILTERED_HEAD --detach
# Let's save this branch and use it as new main
git switch main
# Save old branch
git branch old-main
git switch FILTERED_HEAD
# Delete main
git branch -d main
# Create main from current branch
git switch -b main
And tada! We have our first repo rewrite.
For the merge of the A
repo, it is quite similar.
In repo B.
git remote add A https://$ADDR
git fetch A main
josh-filter ':prefix=a' FETCH_HEAD
# Now the merge part
git switch FETCH_HEAD
git switch -b new-a
# I use rebase to get a linear history
git rebase main
# Merge it to main
git switch main
git merge --ff-only new-a
And voilà, we get our repo with the history of both repo!
Some problems with this :
- Signatures are not kept since we modify the commits. This may be a problem for you.
- We sometimes need to force-push the main branch which should be done cautiously (I recommend creating a backup branch just in case).
Changelog
<2023-04-13 jeu.> : fix example link, add --detach
flag that's needed in the
git command. I don't use it since I've been using git longer than this option
has existed. Interestingly, I use git restore
because I think this one makes
way more sense >:).