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