1

My "real" .git folder is in /var/www. I want to push the whole folder to github. Unfortunately, a few git sub modules are excluded.

For example the folder w/extensions/Lingo is excluded. But w/extensions/Lingo/.git isn't "my" git sub module. Git was only used to download w/extensions/Lingo and will be used to update that folder. No own development planed.

How can I tell my "real" git /var/www/.git to ignore any sub modules such as w/extensions/Lingo/.git?

In other words, what I want to tell git is "just treat any file in /var/www/* as normal file".

Anshul Goyal
  • 73,278
  • 37
  • 149
  • 186
adrelanos
  • 1,453
  • 2
  • 16
  • 27

3 Answers3

2

www/extensions/Lingo should not be ignored: what you will push is the gitlink (special entry, mode 16000) which represents (in the working tree of the main repo) the SHA1 currently checked out in www/extensions/Lingo.

You can check that by doing a git log (without trailing slash):

cd /var/www
git log -- extensions/Lingo
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • I don't want to ignore it, but to treat it as normal folder. How to do that? – adrelanos Apr 29 '14 at 11:40
  • 1
    @adrelanos it is a submodule: it isn't meant to be treated as a normal folder, but as a marker to the content of another repo: once you clone what you pushed to GitHub, a simple `git submodule update --init` will restore the content of that folder. – VonC Apr 29 '14 at 11:42
  • I pushed it to github. When someone clones it, they end up with an empty `/www/w/extensions/Lingo`. Not what I want. – adrelanos Apr 29 '14 at 11:43
  • 1
    @adrelanos yes, it is what you can expect from a submodule: it isn't an empty folder, but a special icon: http://stackoverflow.com/a/19585206/6309 It is the marker (the gitlink) I mention in my answer. – VonC Apr 29 '14 at 11:44
  • This is over complicating things. Hence I want to treat them as normal folders. I am using many such submodules (not on purpose, they just happen to be). Now when I run `git submodule update --init`, I get `No submodule mapping found in .gitmodules for path 'w/extensions/BreadCrumbs2'`. – adrelanos Apr 29 '14 at 11:47
  • @adrelanos no, it doesn't add complexity; it does what a submodule is supposed to do: a simple light-weight marker to remember a repo content. And your error message has nothing to do with `Lingo`, but with another submodule which, apparently, isn't declared in your .gitmodules. – VonC Apr 29 '14 at 11:49
  • 1
    @adrelanos remember, this isn't just about treating a submodule "like a regular folder": it is about storing the *exact version* if that folder content. – VonC Apr 29 '14 at 11:51
  • @adrelanos for your error message, see: http://stackoverflow.com/a/4162672/6309. `git rm` + `git submodule add`. – VonC Apr 29 '14 at 11:51
  • Git submodules open up to a whole new learning curve and chain of new issues. Next one after creating the .gitmodules file with ~15 sub modules, I end up getting `fatal: reference is not a tree: 19e577ac3b16eba79a0d4519d18a1306e95d4e49`. It is probably because of a minor change (optimized image with optipng script), that can not be found in upstream's repository. The simple task "just get /var/www folder published on github" extends to multiple hours of work. Ironically, svn could get this specific job done easier, because it ignores .git folders. That's what I meant with added complexity. – adrelanos Apr 29 '14 at 12:41
  • @adrelanos not multiple hours of work: if you modify anything in a submodule, you must push it (before going back to the parent repo, add, commit and push). I didn't mention it because you said in your question "No own development planed.". But I explain more on submodules at http://stackoverflow.com/a/1979194/6309 – VonC Apr 29 '14 at 12:43
  • "No own development planed", I forgot, that a simple image optimization script was run over that folder. I don't consider this development. So for this change in the submodule, to push it somewhere, I would have to create a separate remote repository for the submodule? – adrelanos Apr 29 '14 at 12:52
  • @adrelanos yes, if you don't have write access to the original repo of that submodule, you would have to fork it (http://stackoverflow.com/a/9257901/6309), change the remote origin, and push to your fork (http://stackoverflow.com/a/13025673/6309). – VonC Apr 29 '14 at 12:55
  • I understand. This seems overkill for the real task ("just get /var/www folder published on github") at hand. Maybe a workaround could be to no let the parent `/var/www/.git` see `w/extensions/Lingo/.git` etc. by using file permissions can be used. – adrelanos Apr 29 '14 at 13:01
  • @adrelanos no it isn't overkill: it is called component approach (http://stackoverflow.com/a/7322295/6309), in which you register in your main repo the exact configuration you need for said parent repo to work, as in http://stackoverflow.com/a/2897157/6309. – VonC Apr 29 '14 at 13:03
2

If you insist including the content of a submodule in your repo, you can do a:

git submodule deinit Lingo 
git rm -r --cached extensions/Lingo
rm -R extensions/Lingo/.git # (if it is still there)
git add extensions/Lingo

(As I detail in "How do I remove a Git submodule?")

The --cached make sure you don't remove the content of that folder in your working tree.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • This would probably work, but then the ability to update extension/Lingo using a simple `git fetch` + `git merge origin/master` is lost. – adrelanos Apr 29 '14 at 12:13
  • 1
    @adrelanos of course, that is why it is a submodule! The last alternative is to make it a subtree: http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/ (beware of http://stackoverflow.com/a/14448784/6309 though) – VonC Apr 29 '14 at 12:14
  • @adrelanos other alternative: http://jayunit100.blogspot.fr/2013/12/git-submodules-are-to-hot-subtrees-are.html But I would simply keep submodules ;) – VonC Apr 29 '14 at 12:17
  • I feel like there are valid reasons to kill the submodule triggers in git. I just added a new ember.js project in a folder inside of a larger client project. Since running 'ember new my-ember-project' created a .git folder inside of the 'my-ember-project' folder, the primary repo for the project wanted to pick it up as a submodule. It wasn't actually a submodule, but was generated by the ember cli as a convenience. In order to have the parent repo actually track this as a set of files, the above commands (mainly the rm -R my-ember-project/.git part) was very helpful in fixing the problem. – JiuJitsuCoder Aug 06 '15 at 13:38
  • @MySpecialPurpose well done: that would indeed make the content of that repo visible, instead of being part of a nested repo. – VonC Aug 06 '15 at 13:39
0

I do not recommend doing this, but it sounds like you're dead-set... Note that this will cause files from your "submodule" to be committed in two places, and keeping them in sync will be an additional challenge.

My opinion is that this is at least as complicated as submodules, and since it's a weird thing to do other developers who want to contribute will likely be confused.

You could move the .git directory out of your submodule directory so that

  1. your main Git repository does not view the "submodule" directory as a submodule, and
  2. you can still fetch from upstream.

Here is a short example:

  1. Clone something (your "inner repository") into a subdirectory of your main repository:

    ~ $ cd repo
    ~/repo/ $ git clone git://some-other-repo.git/
    
  2. Create a directory to hold the .git directory from your inner repository somewhere outside of your main repository, and move your inner .git directory there:

    ~/repo/ $ cd ..
    ~ $ mkdir -p fake-submodules/some-other-repo/
    ~ $ mv ~/repo/some-other-repo/.git fake-submodules/some-other-repo/
    
  3. Now, from your main repository you can add all of the files and commit as usual:

    ~ $ cd repo
    ~/repo/ $ git add some-other-repo
    ~/repo/ $ git commit -m "Add some other repo"
    
  4. And you can fetch updates from your upstream repository using Git's --work-tree option:

    ~/repo/ $ cd ../fake-submodules/some-other-repo
    ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo status
    ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo fetch
    ~/fake-submodules/some-other-repo/ $ git --work-tree ../../repo/some-other-repo merge origin/master
    

Note that you would have to perform all Git operations for your inner repository from its fake-submodules directory. You will probably want to do something like git config core.worktree ../../repo/some-other-repo to avoid having to type the --work-tree option in each time.

Again, please reconsider doing this. Git's submodules may not be perfect, but at least they're widely used and understood. As VonC says, there are other more appropriate options as well, like subtrees.

ChrisGPT was on strike
  • 127,765
  • 105
  • 273
  • 257