My situation is that I have two Git repositories that I need to merge into a single repository (there are actually more repos, but I can start with two).
The two repositories are:
- The main repository, A.
- The second repository, B.
The code in repository B has dependencies on the code in repository A (but not vice versa), and the histories of both repositories follow each other in a chronological fashion - roughly (i.e. a specific commit in repo B will typically require a commit from repo A with a very similar commit time).
There are conflicting branch and tag names in both repositories (there are no guarantees that they belong together), but only the refs from A need to be preserved.
The requirements for the new repository, C, are:
- All refs (branches and tags) from A need to be preserved.
- Only the master branch commits from B need to be preserved (i.e. the commits that are reported by
git log --first-parent master
). - The files from each source repository should be put into subfolders of the new repository (i.e. the files from A shall go into
A/
, and the files form B shall go intoB/
). - When checking out a specific commit (including commits done before the merge) in repository C (e.g. a release tag) compatible files form both source repositories should be found in the directories
A/
andB/
(at least within a commit or two).
So far I have tried several approaches, including this and git-stitch-repo, without success (they did not fulfill the above requirements).
At this point, I have managed to:
- Move all files in each repo to a subdirectory using git filter-branch. E.g. for repo A:
mkdir A mv * .gitignore A/ 2> /dev/null git commit -a -m 'DROPME' > /dev/null git filter-branch --tag-name-filter cat --index-filter 'git ls-files -s | sed "s-\t\"*-&A/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new git update-index --index-info && mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE" ||:' -- --all git reset --hard origin/master git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d
- Import repo B into A using git fast-export/fast-import.
- Device a method for generating a mapping such that for a given SHA in A, there is a list of zero, one or more SHA:s that should be inserted from B.
What I would expect now, is that some clever usage of git filter-branch should enable me to insert the selected commits from B into the master branch of A. But how?