- init submodule
- update submodule
- revert changes in submodule
- submodule update history
- list submodules
- working with submodule
- remove submodule
[!TIP|label:reference:]
init submodule
$ git submodule add --name <NAME> -b <BRANCH> <REPO_URL> </path/in/repo>
$ git submodule init
$ git submodule update --init
- i.e.:
$ git submodule add --name ansible-completion \ -b master \ https://github.com/dysosmus/ansible-completion.git \ confs/home/.marslo/.completion/ansible-completion $ git submodule add --name bash-completion \ -b master \ https://github.com/scop/bash-completion.git \ confs/home/.marslo/bin/bash-completion $ git submodule init $ git submodule update --init
update submodule
# update branch
$ git config -f .gitmodules submodule.<NAME>.branch <NEW_BRANCH>
$ git submodule update --remote
revert changes in submodule
$ git submodule deinit -f .
$ git submodule update --init
- or
$ git submodule foreach --recursive git clean -dffx $ git submodule foreach --recursive git reset --hard
submodule update history
$ git log --oneline [--name-only] -- /path/to/submodule
# list all
$ git config --blob HEAD:.gitmodules --get-regexp path |
awk '{print $NF}' |
xargs -I{} bash -c "echo -e \"\\n~~> {}:\"; git log -1 --oneline -- {}"
list submodules
[!TIP|label:references:]
- git plumbing command to get submodule remote
- Get submodule hash from bare repository
- How to make shallow git submodules?
example:
$ git config --blob HEAD:.gitmodules --get-regexp [url|branch|path] # or $ git config --blob HEAD:.gitmodules --get-regexp ^submodule.\(.+\).\(path\|url\|branch\)
HEAD:.gitmodules
$ git config --blob HEAD:.gitmodules --list
# or
$ git show HEAD:.gitmodules | git config --file - --list
get dynamic refs
$ git cat-file -p <refs>:.gitmodules # or $ git show -p <refs>:.gitmodules
get name
$ git submodule foreach --quiet 'echo $name'
# or
$ git submodule foreach --quiet 'echo $name' |
xargs -I{} bash -c "git ls-tree -z -d HEAD -- {}; echo ''"
get path
$ git show HEAD:.gitmodules | git config --file - --get-regexp path
# or
$ git --no-pager config \
--file \$(git rev-parse --show-toplevel)/.gitmodules \
--get-regexp ^submodule.\\(.+\\).path
get url
$ git show HEAD:.gitmodules | git config --file - --get-regexp url
# or
$ git --no-pager config \
--file \$(git rev-parse --show-toplevel)/.gitmodules \
--get-regexp ^submodule.\\(.+\\).url
# or
$ git submodule foreach -q git config remote.origin.url
# or
$ find .git/modules/ -name config -exec grep url {} \;
# or
$ git config --list | grep -E ^submodule.*.url
get branch
$ git config --blob HEAD:.gitmodules --get-regexp branch
working with submodule
pull from remote
- update submodule only
$ git submodule update --remote --recursive --force --rebase
- update both super and submodule
$ git pull [--rebase] --recurse-submodules
push to remote
- push submodule only
$ cd ./path/to/submodule $ git push --recurse-submodule=on-demand
push for both super and submodule
$ cd ./path/to/submodule $ git add --all $ git commit -am ".. comments here .." $ git push --recurse-submodule=on-demand $ cd $(git rev-parse --show-superproject-working-tree) # or: https://stackoverflow.com/a/7359782/2940319 $ cd $(git rev-parse --show-superproject-working-tree --show-toplevel | head -1) $ git add --all $ git commit -am ".. comments here .." $ git push origin $(git rev-parse --abbrev-ref HEAD)
remove submodule
$ git submodule deinit -f <NAME> ### operational
$ git rm --cached <NAME>
$ rm -rf <submodulePath>
$ rm -rf .git/modules/<NAME>
$ git config -f .gitmodules --remove-section submodule.<NAME> ### or $ rm -rf .gitmodules
$ git config -f .git/config --remove-section submodule.<NAME> ### or $ vim .git/config