I know many people store their .vimrc on GitHub to make it easier to get right to work on new machines, and that makes complete sense to me. Including plugins, however, is problematic, because the plugins I use are already git repositories. How does one create a repo that will track both their .vimrc and any plugins that might be installed?
-
I feel like this might be too opinion-oriented; there's no objective "best" and there are a lot of good options, each with their own pros and cons. Also the bit specifically about nested repositories brings the question more into the "using git" category and less about vim. Perhaps if you focused instead on a specific problem you had with vim or vim plugins while trying to store your configuration on github?– user72Feb 6, 2015 at 18:20
-
3I can edit it to take out the best if you like; my intention was to ask more of a "how do I do this?" question, while acknowledging that the way I was thinking about going about the problem might not be ideal.– TomFeb 6, 2015 at 18:21
-
That may help, but that may just make it a "list of things" question (there are, again, lots of different ways to do this effectively). There's currently a topic on meta about such questions if you'd like to contribute to the discussion about how we should treat this sort of question.– user72Feb 6, 2015 at 18:24
-
2Edited. I hope I've made it more clear that I'm asking "how do I do this?"– TomFeb 6, 2015 at 18:29
-
1Just use a plugin manager like neobundle.– PhilipMar 9, 2015 at 15:12
5 Answers
How to deal with repositories-within-repositories has been an ongoing question with git. Git's submodules are one way of addressing the situation, at the expense of adding a little more complexity to keep track of. The git site has an introduction to submodules.
The basic idea is to keep a reference to another git repository associated with a path on your repository. These references are stored in a file .gitmodules
in the root of your repository (which is managed by git, so leave it alone). Some of the complexity comes in to play when cloning a repo which has submodules: you must explicitly git submodule init
to create the .gitmodules
file, and then git submodule update
to clone the submodules.
Here's a walkthrough of how I'll add a new vim plugin to my dotfiles repository (I have ~/.vim/
aliased to this repo's .vim/
) using a submodule:
$ cd dotfiles/
$ git submodule add https://github.com/elixir-lang/vim-elixir.git .vim/bundle/vim-elixir
After the submodule add
, a git status
would show that you've modified (or created) the .gitmodules
file, with something like this:
[submodule ".vim/bundle/vim-elixir"]
path = .vim/bundle/vim-elixir
url = https://github.com/elixir-lang/vim-elixir.git
It should also show .vim/bundle/vim-elixir
as a new file. Git treats that path specially now: it's a normal directory on your file system (so vim loads it up normally), but git diff
will treat it as a specific commit from its repository. When looking at diffs or logs for that path (e.g. git log -1 -u .vim/bundle/vim-elixir
), git will show it as a one-line string like this:
Subproject commit 2d59d1d52a9bcf9342d42fa7d6b59e6a1aaa7b9e
Updating to the latest version of the plugin corresponds to going into the submodule's repository and checking out a new commit, and then committing that to your repository:
$ cd .vim/bundle/vim-elixir
$ git remote -v # note: the submodule repo's origin, not my repo's
origin https://github.com/elixir-lang/vim-elixir.git (fetch)
origin https://github.com/elixir-lang/vim-elixir.git (push)
$ git pull
# ...
$ cd - # back to my repository's root
$ git status
# ...
modified: .vim/bundle/vim-elixir (new commits)
$ git diff .vim/bundle/vim-elixir
# ...
-Subproject commit 2d59d1d52a9bcf9342d42fa7d6b59e6a1aaa7b9e
+Subproject commit d59784e7afbd0d55c501e40c43b57cbe6f6e04c2
$ git commit -m "update vim-elixir" .vim/bundle/vim-elixir
-
-
Ah, I didn't notice your answer had been posted, since I was editing mine for some time.– muruFeb 6, 2015 at 19:29
You don't need to store plugins in your VCS; you can also use a Vim package manager. Since yesterday, I use vim-plug:
You can define plugins in your vimrc like so:
call plug#begin('~/.vim/plugged')
Plug 'embear/vim-localvimrc'
Plug 'kchmck/vim-coffee-script'
" ... etc
call plug#end()
Then restart Vim, and then install plugins with:
:PlugInstall
Or, you can add this snippet from the FAQ to your vimrc file before the plug#begin()
call:
if empty(glob('~/.vim/autoload/plug.vim'))
silent !curl -fLo ~/.vim/autoload/plug.vim --create-dirs
\ https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim
autocmd VimEnter * PlugInstall
endif
This will put the plugins in ~/.vim/plugged
. You do not need to keep this file in your VCS. If you want to use this vimrc on another machine, just call :PlugInstall
on that machine.
to remove a plugin, remove it from the vimrc file and run:
:PlugClean
Note that vim-plug doesn't support installing scripts from the Vim scripts website, but those scripts are mirrored on GitHub, so there's no need to do so.
There are also some additional advantages to this such as easier updating of plugin, and on-demand loading for better performance. You're also not running the risk of violating the license terms of the plugins you're distributing with your vimrc files.
See also:
I store my vimrc in github and the plugins as submodules of my repository.
In the readme.md file I put a one liner that pulls the repository then runs the setup script, this way I can copy one line into an editor and it sets up everything. It does a bit more than just vim (but not much).
https://github.com/Loki-Astari/UnixConfig
To use it:
cd
git clone [email protected]:Loki-Astari/UnixConfig.git ~/.config
cd .config
git submodule init
git submodule update
chmod +x init
./init
cd
PS. Willing to take any advice (as I did this ages ago and have not touched it since).
Note: My favorite part is that it sets up git as well and sets it up to use vim as the diff tool for git. Vimdiff is the the best diff tool.
If you would like to stick with Pathogen, one way could be to use Git submodules. When you add a submodule, git recognizes it as from another repository and leaves its contents alone (unless it has been changed, in which case, it will show up as having untracked content when you do git status
). If you all your Github-based plugins are in bundle/
, then adding them as submodules is a fairly simple task with a good shell:
for f in bundle/*/
do
git submodule add $(awk '/url =/{print $3}' "$f/.git/config") "$f"
done
You can have a look at how submodules show up at my vimrc repo.
If you add a file to a submodule, or make some changes that don't affect the repository, git status
will still complain about the submodule having uncommitted changes or untracked files. You can make git ignore such changes by adding ignore = dirty
to the submodule configuration in the .gitmodules
file. For example:
[submodule "bundle/LaTeX-Box"]
path = bundle/syntastic
url = https://github.com/scrooloose/syntastic.git
ignore = dirty
One benefit of submodules is that revision of the submodule is added to the git repository, so that a git init
automatically takes care of checking out up that particular revision. You can throw that away and tell git to ignore submodules once you have added them by adding ignore = all
to their configuration in the .gitmodules
file. For example:
[submodule "bundle/LaTeX-Box"]
path = bundle/LaTeX-Box
url = https://github.com/LaTeX-Box-Team/LaTeX-Box.git
ignore = all
Lastly, one command to update them all!
git submodule foreach git pull
Word of caution: I am new to submodules. I am not really sure how they behave.
-
vim-pandemic is another way to enhance Pathogen without needing to use submodules. Pandemic handles the remote repositories leaving Pathogen to handle the runtimepath. This does mean one needs two tools, but for disparate tasks which "should" be handled separately.– jalanbFeb 9, 2015 at 10:43
-
Can anyone comment on why tpope in the pathogen readme might say why submodules are not the way to go? I don't know submodules either (and my solution works great for me without even a plugin manager) but I'm guessing the anti-submodule crowd has something interesting to say. Feb 22, 2016 at 18:11
-
1@dash-tom-bang I don't read that bit as him saying that you shouldn't use submodules. I think he's just saying it's not his preferred method.– RichMar 13, 2018 at 15:27
-
1TBH after a couple of years of using them, I got annoyed with submodules. I would now recommend against using them. I use vim-plug now and it's only made my life easier.– muruMar 13, 2018 at 15:40
You can just add this line to your .gitignore
to ignore all your plugins and not commit them:
vim/bundle
Also, you said that it's problematic that it would include the plugin code because they're already github repos. I guess you mean that you don't want to duplicate the code, but I've heard it said that you should go ahead and duplicate code that's a dependency so that you can always go back to a particular point in your code and know that it will work. Here are some articles by James Shore that talk about that: http://www.letscodejavascript.com/v3/blog/2014/12/the_reliable_build, http://www.letscodejavascript.com/v3/blog/2014/03/the_npm_debacle. He's talking about programming code and npm (as opposed to vim), but I think the argument still applies, you want a reliable environment to code or write in.
-
1"You can just add this line to your .vimrc..." did you mean .gitignore?– user72Feb 6, 2015 at 19:38