Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

switching a subdirectory managed by git to a submodule

We used to have a local hack of delayed_job in a Rails app, in vendor/plugins/delayed_job. It was installed as a one-time event and checked into git in the main app repo.

Now we decided to fork delayed_job on github and replace the subdirectory by a git submodule, as described e.g. here:

http://doblock.com/articles/using-git-submodules-to-manage-plugins-in-rails

Before doing that, I simply removed vendor/plugins/delayed_job, without checking it in. Now, despite adding the submodule, git status in the main repo still shows new files in vendor/plugins/delayed_job.

How should we handle the situation where a subdirectory which was a part of the repo is deleted and made to hold a git submodule? Should we first delete it with git rm, or obliterate it even more thoroughly, before cloning a submodule into its place?

like image 224
Alexy Avatar asked Jun 30 '11 00:06

Alexy


People also ask

Is using git submodules a good idea?

Git submodules may look powerful or cool upfront, but for all the reasons above it is a bad idea to share code using submodules, especially when the code changes frequently. It will be much worse when you have more and more developers working on the same repos.

How do I move a submodule to a different directory?

gitmodules and change the path of the submodule appropriately, and put it in the index with git add . gitmodules . If needed, create the parent directory of the new location of the submodule ( mkdir -p new/path/to ). Move all content from the old to the new directory ( mv -vi old/path/to/module new/path/to/submodule ).

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.


1 Answers

Assuming that you do not care about the current contents of vendor/plugins/delayed_job in your working tree (i.e. the content that will be checked out as a submodule is already a suitable replacement for the content in your working tree), the normal procedure for converting a directory into a submodule looks like this:

git rm -r vendor/plugins/delayed_job
git submodule add github.com:account/delayed_job.git vendor/plugins/delayed_job

Of course, the GitHub repository URL may vary; for example, you may want to use an HTTP URL instead of the above SSH URL.

But, it seems like you did something a bit different. As best I can tell, you did something like this:

rm -rf vendor/plugins/delayed_job
git clone github.com:account/delayed_job.git vendor/plugins/delayed_job

There are two flaws with this procedure:

  1. The plain rm leaves the old files in your Git index.
  2. Directly cloning gives you a “subrepository”, but not an official submodule.

Assuming that you do not have any intentionally staged changes in vendor/plugins/delayed_job (you probably do not, since you are replacing it with a submodule), you can clean up the situation with these commands:

git rm --cached -r vendor/plugins/delayed_job
git submodule add github.com:account/delayed_job.git vendor/plugins/delayed_job

Cleaning out all the vendor/plugins/delayed_job entries from the index should fix your “still shows new files” problem. Using git submodule add will create the .gitmodules file which turns the “subrepository” into a true submodule.

like image 51
Chris Johnsen Avatar answered Oct 27 '22 04:10

Chris Johnsen