Git migrations tools like GitHub Importer and even ghe-migrator are not able to update submodule urls. This small script solves that problem by updating all your .gitmodules
files recursively with a simple sed command.
You can run this script in any git repository and it will recursively itterate submodules and perform the following operations:
- Executes the sed command provided via
-s
on .gitmodules - Synchronizes submodules' remote URL configuration setting to the value specified in .gitmodules
- Updates(pulls) all submodules.
- Commits the changes to the branch provided via
-b
with the message provided via-m
- You must have read/write permission on the repositories you are modifying
- This script will not import repositories for you and assumes all required repositories have already been imported to your target. This means if you are replacing the url of a submodule, the new URL must be pointing to a valid repository.
This example is migrating the url from bitbucket.org
to github.com
.
Clone your repo that contains submodules and cd inside:
git clone https://austenstone@bitbucket.org/austenstone/main-test1.git
cd main-test1
Run the script:
migrate-submodules.sh -s 's/bitbucket.org/github.com/g' -b 'master'
Congratulations. Your submodules have been updated! 🎉
Check them out 👀
cat .gitmodules && git submodule foreach --recursive '[ -f .gitmodules ] && cat .gitmodules || true'
If you are happy with the results, push your changes to remote:
git submodule foreach --recursive git push origin master
git push origin master
TIP: You can automatically sync all branches with master by running the following command:
for BRANCH in `ls .git/refs/heads`; do git rebase master $BRANCH; done
git push --all origin
To see this example in action read the GitHub Actions workflow and also checkout the previous runs.
Simply add the script to your PATH.
cd /usr/local/bin
curl https://raw.githubusercontent.com/austenstone/migrate-submodules/main/migrate-submodules.sh > migrate-submodules.sh
chmod +x migrate-submodules.sh
Script tested on Ubuntu and MacOS.
bitbucket.org/austenstone/main-test1 is the root of a small set of repos and is used to test the functionality.
github.com/austenstone/main-test1 is the migrated repo.
graph TD;
main-test1-->child-test1;
child-test1-->child-test1-child ;
main-test1-->child-test2;
- Use
set-url [--] <path> <newurl>
instead of sed. - Sync all branches in the script
- Dynamically get the default branch using
git remote show origin | sed -n '/HEAD branch/s/.*: //p'