Skip to content

Instantly share code, notes, and snippets.

@OleksiyRudenko
Last active October 29, 2018 07:42
Show Gist options
  • Save OleksiyRudenko/3324acdab15fff52955979522c878a3e to your computer and use it in GitHub Desktop.
Save OleksiyRudenko/3324acdab15fff52955979522c878a3e to your computer and use it in GitHub Desktop.
Git: merging, rebasing

Merging a repo into another one

Initial situation:

  1. Repository A we want to become a part of another repository.
  2. Repository B we want repo A to be merged into.

Targets:

  1. We want source code from repo A to be located under a sub-directory in repo B and repo A history stored in a dedicated repo B branch.
  2. We do not want original repo A be changed or corrupted.

Inspirations:

  1. http://gbayer.com/development/moving-files-from-one-git-repository-to-another-preserving-history/
  2. https://stackoverflow.com/questions/10603671/how-to-add-a-local-repo-and-treat-it-as-a-remote-repo
  3. https://stackoverflow.com/questions/18667308/move-file-and-directory-into-a-sub-directory-along-with-commit-history

Solution:

  1. Clone repo A into A' and unbind it from original source to avoid corruption thereof.
  2. Restructure repo A' so it looks like it is already a part of repo B.
  3. Clone repo B into B'.
  4. Pull branch from repo A' into repo B'.
  5. Check if B' looks as it is expected to be and push it if OK.
  6. Remove temporary repos.

NB #1. Repo A' won't be pushed anywhere.

NB #2. Repo B should not contain a directory where codebase from A' will be placed, as it may result in merger conflicts.

Step 1 - Cloning repo A into A'

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

Step 2 - Restructuring repo A'

# 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 ..."

Step 3 - Cloning repo B into B'

cd <sandboxDirectory>
git clone <repo B .git> <repo B name>--tmp
cd <repo B' directory>

Step 4 - Merging repo A' into repo B'

# 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

Step 5 - Checking things are OK

# 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.

Step 6 - Removing temporary repos A' and B'

Do so in your favourite way.

@OleksiyRudenko
Copy link
Author

Thank you for your comment. Good point. Besides that it is also not a good idea to remove any files that are under version control. Just removed the lines with poor instructions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment