1#!/bin/sh 2# 3# git-submodules.sh: init, update or list git submodules 4# 5# Copyright (c) 2007 Lars Hjemli 6 7USAGE='[--quiet] [--cached] [status|init|update] [--] [<path>...]' 8. git-sh-setup 9require_work_tree 10 11init= 12update= 13status= 14quiet= 15cached= 16 17# 18# print stuff on stdout unless -q was specified 19# 20say() 21{ 22iftest -z"$quiet" 23then 24echo"$@" 25fi 26} 27 28 29# 30# Clone a submodule 31# 32module_clone() 33{ 34 path=$1 35 url=$2 36 37# If there already is a directory at the submodule path, 38# expect it to be empty (since that is the default checkout 39# action) and try to remove it. 40# Note: if $path is a symlink to a directory the test will 41# succeed but the rmdir will fail. We might want to fix this. 42iftest -d"$path" 43then 44rmdir"$path"2>/dev/null || 45 die "Directory '$path' exist, but is neither empty nor a git repository" 46fi 47 48test -e"$path"&& 49 die "A file already exist at path '$path'" 50 51 git-clone -n"$url""$path"|| 52 die "Clone of submodule '$path' failed" 53} 54 55# 56# Run clone + checkout on missing submodules 57# 58# $@ = requested paths (default to all) 59# 60modules_init() 61{ 62 git ls-files --stage --"$@"|grep-e'^160000 '| 63whileread mode sha1 stage path 64do 65# Skip submodule paths that already contain a .git directory. 66# This will also trigger if $path is a symlink to a git 67# repository 68test -d"$path"/.git &&continue 69 70 url=$(GIT_CONFIG=.gitmodules git-config module."$path".url) 71test -z"$url"&& 72 die "No url found for submodule '$path' in .gitmodules" 73 74# MAYBE FIXME: this would be the place to check GIT_CONFIG 75# for a preferred url for this submodule, possibly like this: 76# 77# modname=$(GIT_CONFIG=.gitmodules git-config module."$path".name) 78# alturl=$(git-config module."$modname".url) 79# 80# This would let the versioned .gitmodules file use the submodule 81# path as key, while the unversioned GIT_CONFIG would use the 82# logical modulename (if present) as key. But this would need 83# another fallback mechanism if the module wasn't named. 84 85 module_clone "$path""$url"||exit 86 87(unset GIT_DIR &&cd"$path"&& git-checkout -q"$sha1") || 88 die "Checkout of submodule '$path' failed" 89 90 say "Submodule '$path' initialized" 91done 92} 93 94# 95# Checkout correct revision of each initialized submodule 96# 97# $@ = requested paths (default to all) 98# 99modules_update() 100{ 101 git ls-files --stage --"$@"|grep-e'^160000 '| 102whileread mode sha1 stage path 103do 104if!test -d"$path"/.git 105then 106# Only mention uninitialized submodules when its 107# path have been specified 108test"$#"!="0"&& 109 say "Submodule '$path' not initialized" 110continue; 111fi 112 subsha1=$(unset GIT_DIR &&cd"$path"&& 113 git-rev-parse --verify HEAD) || 114 die "Unable to find current revision of submodule '$path'" 115 116iftest"$subsha1"!="$sha1" 117then 118(unset GIT_DIR &&cd"$path"&& git-fetch&& 119 git-checkout -q"$sha1") || 120 die "Unable to checkout '$sha1' in submodule '$path'" 121 122 say "Submodule '$path': checked out '$sha1'" 123fi 124done 125} 126 127# 128# List all registered submodules, prefixed with: 129# - submodule not initialized 130# + different revision checked out 131# 132# If --cached was specified the revision in the index will be printed 133# instead of the currently checked out revision. 134# 135# $@ = requested paths (default to all) 136# 137modules_list() 138{ 139 git ls-files --stage --"$@"|grep-e'^160000 '| 140whileread mode sha1 stage path 141do 142if!test -d"$path"/.git 143then 144 say "-$sha1$path" 145continue; 146fi 147 revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1) 148if git diff-files --quiet --"$path" 149then 150 say "$sha1$path($revname)" 151else 152iftest -z"$cached" 153then 154 sha1=$(unset GIT_DIR && cd "$path" && git-rev-parse --verify HEAD) 155 revname=$(unset GIT_DIR && cd "$path" && git-describe $sha1) 156fi 157 say "+$sha1$path($revname)" 158fi 159done 160} 161 162while case"$#"in0)break;;esac 163do 164case"$1"in 165 init) 166 init=1 167;; 168 update) 169 update=1 170;; 171 status) 172 status=1 173;; 174-q|--quiet) 175 quiet=1 176;; 177--cached) 178 cached=1 179;; 180--) 181break 182;; 183-*) 184 usage 185;; 186*) 187break 188;; 189esac 190shift 191done 192 193case"$init,$update,$status,$cached"in 1941,,,) 195 modules_init "$@" 196;; 197,1,,) 198 modules_update "$@" 199;; 200,,*,*) 201 modules_list "$@" 202;; 203*) 204 usage 205;; 206esac