See below the solid line for my original question.
I have a folder in my local directory that is untracked. When I run git status, I get:
Changed but not updated:
modified: vendor/plugins/open_flash_chart_2 (modified content, untracked content)
When I type git add vendor/plugins/open_flash_chart_2 then try git status again, it still says untracked. What’s going on?
Here is a simple summary of my latest half hour:
-
Discovered that my Github repo is not tracking my
vendor/plugins/open_flash_chart_2plugin. Specifically, there’s no content and it’s showing a green arrow on the folder icon. -
Tried
git submodule initNo submodule mapping found in .gitmodules for path 'vendor/plugins/open_flash_chart_2' -
Tried
git submodule add git://github.com/korin/open_flash_chart_2_plugin.git vendor/plugins/open_flash_chart_2vendor/plugins/open_flash_chart_2 already exists in the index -
git statusmodified: vendor/plugins/open_flash_chart_2 (untracked content) -
Hunted for any file named
.gitmodulesin my repository/local directory but couldn’t find one.
What do I have to do to get my submodules working so git can start tracking properly?
This may be unrelated (I include it in case it helps), but every time I type git commit -a rather than my usual git commit -m "my comments", it throws up an error:
E325: ATTENTION
Found a swap file by the name ".git\.COMMIT-EDITMSG.swp"
dated: Thu Nov 11 19:45:05 2010
file name: c:/san/project/.git/COMMIT_EDITMSG
modified: YES
user name: San host name: San-PC
process ID: 4268
While opening file ".git\COMMIT_EDITMSG"
dated: Thu Nov 11 20:56:09 2010
NEWER than swap file!
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
Swap file ".git\.COMMIT_EDITMSG.swp" already exists!
[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:
I am a complete newbie at Github and despite trying to go through the documentation, I’m a bit stumped by these particular problems. Thank you.
You have added
vendor/plugins/open_flash_chart_2as “gitlink” entry, but never defined it as a submodule. Effectively you are using the internal feature that git submodule uses (gitlink entries) but you are not using the submodule feature itself.You probably did something like this:
This last command is the problem. The directory
vendor/plugins/open_flash_chart_2starts out as an independent Git repository. Usually such sub-repositories are ignored, but if you tell git add to explicitly add it, then it will create an gitlink entry that points to the sub-repository’s HEAD commit instead of adding the contents of the directory. It might be nice if git add would refuse to create such “semi-submodules”.Normal directories are represented as tree objects in Git; tree objects give names, and permissions to the objects they contain (usually other tree and blob objects—directories and files, respectively). Submodules are represented as “gitlink” entries; gitlink entries only contain the object name (hash) of the HEAD commit of the submodule. The “source repository” for a gitlink’s commit is specified in the
.gitmodulesfile (and the.git/configfile once the submodule has been initialized).What you have is an entry that points to a particular commit, without recording the source repository for that commit. You can fix this by either making your gitlink into a proper submodule, or by removing the gitlink and replacing it with “normal” content (plain files and directories).
Turn It into a Proper Submodule
The only bit you are missing to properly define
vendor/plugins/open_flash_chart_2as a submodule is a.gitmodulesfile. Normally (if you had not already added it as bare gitlink entry), you would just usegit submodule add:As you found, this will not work if the path already exists in the index. The solution is to temporarily remove the gitlink entry from the index and then add the submodule:
This will use your existing sub-repository (i.e. it will not re-clone the source repository) and stage a
.gitmodulesfile that looks like this:It will also make a similar entry in your main repository’s
.git/config(without thepathsetting).Commit that and you will have a proper submodule. When you clone the repository (or push to GitHub and clone from there), you should be able to re-initialize the submodule via
git submodule update --init.Replace It with Plain Content
The next step assumes that your sub-repository in
vendor/plugins/open_flash_chart_2does not have any local history that you want to preserve (i.e. all you care about is the current working tree of the sub-repository, not the history).If you have local history in the sub-repository that you care about, then you should backup the sub-repository’s
.gitdirectory before deleting it in the second command below. (Also consider the git subtree example below that preserves the history of the sub-repository’s HEAD).This time when adding the directory, it is not a sub-repository, so the files will be added normally. Unfortunately, since we deleted the
.gitdirectory there is no super-easy way to keep things up-to-date with the source repository.You might consider using a subtree merge instead. Doing so will let you easily pull in changes from the source repository while keeping the files “flat” in your repository (no submodules). The third-party git subtree command is a nice wrapper around the subtree merge functionality.
Later:
git subtree also has a
--squashoption that lets you avoid incorporating the source repository’s history into your history but still lets you pull in upstream changes.