The problem

We have two git repositories “AlphaBeta_iOS” and “AlphaBeta_Android” that we would like to merge them into one new repository “AlphaBeta”. Each existing repository should get its own sub folder named “iOS” and “Android”. The history of both repositories should be preserved.

    |--AlphaBeta             |             |--iOS             |             |--Android

The recipe

  1. Clone the git repos “AlphaBeta_iOS” and “AlphaBeta_Android” to “/path/to/projects”

    cd /path/to/projects
    git clone https://<...>/AlphaBeta_iOS
    git clone https://<...>/AlphaBeta_Android 

  2. Rewrite the file paths (rename root folder “AlphaBeta” to “iOS” and “Android”)
    Case 1: There is a single root folder in the repositories named “AlphaBeta”
    We rename them to “iOS” and “Android”:

    cd /path/to/projects/AlphaBeta_iOS
    git filter-branch --force --tree-filter 'mv AlphaBeta/ iOS/ || true' --tag-name-filter cat -- --all
    
    cd /path/to/projects/AlphaBeta_Android
    git filter-branch --force --tree-filter 'mv AlphaBeta/ Android/ || true' --tag-name-filter cat -- --all
    Case 2: There is not a single root folder but multiple files or folders on the root level.
    We have to insert a root folder “iOS” and “Android”:
    cd /path/to/projects/AlphaBeta_iOS
    git filter-branch --index-filter \
    'git ls-files -s | sed "s-\t\"*-&iOS/-" |
     GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
     git update-index --index-info &&
     mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
    
    cd /path/to/projects/AlphaBeta_Android
    git filter-branch --index-filter \
    'git ls-files -s | sed "s-\t\"*-&Android/-" |
     GIT_INDEX_FILE=$GIT_INDEX_FILE.new \
     git update-index --index-info &&
     mv "$GIT_INDEX_FILE.new" "$GIT_INDEX_FILE"' HEAD
    NOTE: if you are using macos you have to replace the “\t” in the sed command with ctrl+v, TAB

  3. Create a new git repo “AlphaBeta”

    git init AlphaBeta

  4. Add the two repos as remote repos and fetch their content

    cd AlphaBeta
    git remote add --fetch iOS ../AlphaBeta_iOS/
    git remote add --fetch Android ../AlphaBeta_Android/

  5. Merge the commit histories of the two remote repos into the new “AlphaBeta” repo

    git merge iOS/master --allow-unrelated-histories
    git merge Android/master --allow-unrelated-histories

That’s it.