Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save oliver-la/18dbba007f6adef45fcf530be8820de0 to your computer and use it in GitHub Desktop.
Save oliver-la/18dbba007f6adef45fcf530be8820de0 to your computer and use it in GitHub Desktop.
Git: Convert submodule into subdirectory with keeping the history on macOS

Git: Convert submodule into subdirectory with keeping the history on macOS

DO NOT COPY PASTE THIS WHOLE SCRIPT WITHOUT READING IT

YOU NEED TO MAKE VARIOUS ADJUSTMENTS. EXECUTE THESE COMMANDS STEP BY STEP!!

Prepare submodule

Create new working directory

cd ~
mkdir -p repo-merge-directory && cd repo-merge-directory

Clone submodule first

git clone submodule.git submodule

Change to submodule repo

cd submodule

Remove origin

git remote rm origin

Rewrite history to move the source files

The new path should be the path you used the submodule in your actual repo (replace "submodule_path")

git filter-branch --tree-filter \
  'shopt -s dotglob nullglob extglob; mkdir -p ../tmp; mv * ../tmp; mkdir -p submodule_path; mv ../tmp/* submodule_path/' \
  --tag-name-filter cat --prune-empty -- --all

Garbage collect to delete old refs of paths

git gc

Prepare repo

Exit submodule repo

cd ~/repo-merge-directory

Clone your actual repo

git clone repo.git repo

Change to repo folder

cd ~/repo-merge-directory/repo

Remove remote for safety

git remote rm origin

Remove submodule from git history

This is where you saved the submodule (replace "submodule_path")

git filter-branch --force --index-filter \
  'git rm --cached --ignore-unmatch -r submodule_path' \
  --prune-empty --tag-name-filter cat -- --all

Garbage collect

git gc

Add remote for our prepared submodule so we can merge it in

git remote add submodule ~/repo-merge-directory/submodule

Merge submodule in

git pull submodule master --allow-unrelated-histories

Now push your changes to a NEW repository

This is very distructive to existing repositories. Never, for the love of god, use force push.

git remote add origin new_repo.git
git push -u origin master
@sandrowuermli
Copy link

❤️

@Nickmiste
Copy link

This is very useful! One quick note for anyone reading this in the future - you need to change into the repo directory (cd repo) after cloning the main repo (git clone repo.git repo).

@oliver-la
Copy link
Author

@Nickmiste Thanks for your feedback, I'm glad it was useful! Yes, you're absolutely right, I missed to include that step. I have updated the instructions.

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