- Repository
A
we want to become a part of another repository. - Repository
B
we want repoA
to be merged into.
- We want source code from repo
A
to be located under a sub-directory in repoB
and repoA
history stored in a dedicated repoB
branch. - We do not want original repo
A
be changed or corrupted.
- http://gbayer.com/development/moving-files-from-one-git-repository-to-another-preserving-history/
- https://stackoverflow.com/questions/10603671/how-to-add-a-local-repo-and-treat-it-as-a-remote-repo
- https://stackoverflow.com/questions/18667308/move-file-and-directory-into-a-sub-directory-along-with-commit-history
- Clone repo
A
intoA'
and unbind it from original source to avoid corruption thereof. - Restructure repo
A'
so it looks like it is already a part of repoB
. - Clone repo
B
intoB'
. - Pull branch from repo
A'
into repoB'
. - Check if
B'
looks as it is expected to be and push it if OK. - Remove temporary repos.
NB #1. Repo
A'
won't be pushed anywhere.
NB #2. Repo
B
should not contain a directory where codebase fromA'
will be placed, as it may result in merger conflicts.
cd <sandboxDirectory>
# <repo A .git> can be a path to the local repo e.g. D:/myrepos/repoA/.git (under Windows make note of slashes!)
git clone <repo A .git> <repo A name>--tmp
cd <repo A' directory>
git remote rm origin
# Create a branch with a name as it will be in repo B
git checkout -b <target branch name>
# Remove files and directories that are not under version control if any. Check against '.gitignore'
rm node_modules <and/or other files/directories as appropriate>
# Patch history like your codebase has always been under target directory
git filter-branch --subdirectory-filter <target subdirectory name> -- --all
mkdir <target subdirectory name>
mv * <target subdirectory name>
git add .
git commit -m 'Move codebase to <target subdirectory name>'
Optional : squashing commits:
# reset to commit to be sqush root;
git reset --soft <hash>
# commit squashed
git commit -m "App version ..."
cd <sandboxDirectory>
git clone <repo B .git> <repo B name>--tmp
cd <repo B' directory>
# Under Windows make sure using regular slashes in pathnames!
git remote add import <repository A' .git directory>
git checkout -b <target branch name>
# Pull branch from repo A'
git fetch import <target branch name as remote source branch name>
git merge import/<target branch name> --allow-unrelated-histories -m 'Import branch <target branch name> from repo A'
git remote rm import
# Check your repo B' if it is OK then proceed.
git push -u origin <target branch name>
NB! If you cloned repo B'
from local repo (B
) then B'
will push back to your local repo B
.
You may need then to set branch tracking in repo B
appropriately associated with your ultimate remote.
Use git push -u...
again.
Do so in your favourite way.
It would probably make more sense to remove
node_modules
but to keeppackage.json
files in their respective directories, as different projects nested in our combined repo may have different dependencies. This way, after we finish the merge it's only a matter of running$ npm install
in each directory to automatically install their dependencies, specified in each respectivepackage.json
. And obviously it makes future maintaining of the repo easier, as we can safely delete individual projects with all their dependencies, without interfering with the rest of the repo.