Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make part of an existing Git repository a submodule

I have this Git repository which contains two folders: binary-search and poker.

For example: https://github.com/soulnafein/code-katas

I would like to turn these folders into submodules and keep their change history.

How can I do that?

like image 882
soulnafein Avatar asked Oct 20 '09 10:10

soulnafein


People also ask

How do I create a submodule from an existing repo?

In order to add a Git submodule, use the “git submodule add” command and specify the URL of the Git remote repository to be included as a submodule. When adding a Git submodule, your submodule will be staged. As a consequence, you will need to commit your submodule by using the “git commit” command.

Can you make changes to a git submodule?

Pushing updates in the submodule. The submodule is just a separate repository. If you want to make changes to it, you should make the changes in its repository and push them like in a regular Git repository (just execute the git commands in the submodule's directory).


2 Answers

Today there's a better way of doing this: git subtree

See this answer.

like image 132
Roy Sharon Avatar answered Sep 20 '22 14:09

Roy Sharon


The general idea is to use 'git filter-branch' and the following steps:

1) Create a submodule using --subdirectory-filter of filter-branch (after cloning your repo).

$ git filter-branch --subdirectory-filter ABC HEAD -- --all 

See this SO question for more on this step.

2) Create a superproject using an index filter of filter-branch to delete the submodule.

$ git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch ABC" --prune-empty HEAD 

3) Commit the submodule to the latest version of the superproject.

See Detach subdirectory into separate git repository for a practical example.

Each submodule will keep its history.
But as said in this patch proposal, it would:

lose all the historical connections between the superproject and the submodule, breaking tools like 'git bisect', and making it difficult to recover old releases.

Ideally, each version of the newly created superproject would be linked to the correct version of the submodule (and all the .gitmodules entries would be set up correctly, too, throughout the project's history)

If you do not need to have previous history linked to the new submodules, you can follow the steps mentioned above.
But if you do need to branch from an older point while have references to your submodules (which are currently simple sub-directories), the you could consider trying the script mentioned in the patch I refer to. It is discussed in this thread, but integrated to Git yet, as Junio C Hamano says:

Unfortunately, I do not think we have designed fully (nor implemented at all) behaviour to check out different points of history that has the same submodule moved around in the superproject tree.

like image 32
VonC Avatar answered Sep 23 '22 14:09

VonC