Search code examples
gitmigrationgit-submoduleshistory

git - Copy History of A project with submodules to existing single project


I have a git project contains 10 submodules project. I migrated this project to another as a single project. (All submodules are just a folder in the new project now)

Is there anyway to migrate the history data of files in the submodules to new one?


Solution

  • For each submodule, you would need to import their history into the main Git project repository.

    You have an example in the 2013 article "Integrating a submodule into the parent repository" from Lucas Jenß.

    The idea is to clone the submodule repository beside the main parent one:

    •
    ├── parent/
    └── sub/
    

    Remove the submodule declaration in the parent repo:

    git submodule deinit -f -- path/to/submodule
    rm -rf .git/modules/path/to/submodule
    git rm -f path/to/submodule
    

    Rewrite the sub/ repository history in order to move each element to the right path (the path/to/submodule one it was in the parent repository as a submodule)

    However, Lucas is using a (now 2022) old obsolete git filter-branch command in order to move each submodule element to the path it needs to have in the parent repository:

    CMD="git ls-files -s | sed \"s/${TAB}/${TAB}$TARGET_PATH\//\" | \
    GIT_INDEX_FILE=\${GIT_INDEX_FILE}.new \
    git update-index --index-info && mv \${GIT_INDEX_FILE}.new \${GIT_INDEX_FILE}"
    

    It was valid (but cumbersome and not fool-proofed against corner case, like empty commits) in 2013.
    These days (2022), it is achieved with git filter-repo (after installation, as it is python-based)

    cd sub
    git filter-repo --to-subdirectory-filter path/to/submodule
    # done!
    

    Finally, merge the sub history into the parent one:

    $ git remote add sub ../sub/
    $ git fetch sub
    $ git merge --allow-unrelated-histories --no-commit sub/master
    Automatic merge went well; stopped before committing as requested
    

    Repeat that for all 10 submodules.
    And you get one single Git project, with each submodule history preserved.