Last active
August 12, 2022 19:16
-
-
Save gitcos/2219596b4445b9b26dc8406bcbd0fd3c to your computer and use it in GitHub Desktop.
Splitting or Combining Repositories Preserving Change History
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| git-filter-repo is a tool that makes it easy to select subsets of commits in a Git repository and rewrite their paths, | |
| which makes it easy to move folders between repos while preserving their commit histories. | |
| https://github.com/newren/git-filter-repo | |
| It is a single-file python script which can be installed with pip or brew; for more installation info, see the documentation. | |
| # Splitting a subdirectory into a separate repo | |
| Scenario: You want to take subdirectory some_project/ out of repo orgname/oldrepo and create a new repo orgname/some_project. | |
| * Create a new local clone of the source repo and enter the top level directory. | |
| cd /tmp | |
| git clone [email protected]:username/oldrepo | |
| cd oldrepo | |
| * Filter this clone to include only the subdirectory you want, | |
| and rewrite paths to move that subdirectory to the root directory. | |
| git filter-repo --path some_project/ --path-rename some_project/:'' | |
| * Create a new empty repo named some_project on GitHub. | |
| * Clone the new repo locally and enter it. | |
| cd /tmp | |
| git clone [email protected]:username/some_project | |
| cd some_project | |
| * Add the filtered repo as a remote for the new repo, pull its main branch, then force-push back to GHE. | |
| git remote add oldrepo /tmp/oldrepo/ | |
| git pull oldrepo [master|main] --tags | |
| git push origin [master|main] -f --tags | |
| * Delete your filtered local clone of oldrepo. | |
| Optionally, in an un-filtered clode of oldrepo, run 'git rm some_project' and commit that. | |
| # Combining two repos into one | |
| Scenario: You want make a new repo orgname/combined with two subdirectories named proj1 and proj2, | |
| from two existing repos named orgname/proj1 and orgname/proj2 | |
| * Create new local clones of the two existing repos | |
| cd /tmp | |
| git clone [email protected]:username/proj1 | |
| git clone [email protected]:username/proj2 | |
| * Filter each repo's commit history to rewrite the root directory to a subdirectory. | |
| Also, rewrite tag names to a namespace for each repo, | |
| so that tags of the same name from the two repos will not collide when combined. | |
| cd /tmp/proj1; git filter-repo --path '' --path-rename '':proj1/ --tag-rename '':'proj1-' | |
| cd /tmp/proj2; git filter-repo --path '' --path-rename '':proj2/ --tag-rename '':'proj2-' | |
| * Create a new repo named combined on GitHub, optionally with a README and .gitignore. | |
| You don't need to start with an empty root directory because all the commits you will pull | |
| into the repo will only affect subdirectories, not the repo root. | |
| * Clone the new repo locally, and add the two pre-existing repos as remotes: | |
| cd /tmp | |
| git clone [email protected]:username/combined | |
| cd combined | |
| git remote add proj1 /tmp/proj1/ | |
| git remote add proj2 /tmp/proj2/ | |
| * Pull the two pre-existing repos' main branches into this new repo, then force-push to GHE: | |
| git pull proj1 [master|main] --tags | |
| git pull proj2 [master|main] --tags | |
| git push origin [master|main] -f --tags |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment