2 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
7 # We do *not* source any other files as this is meant to be used as a
8 # standalone helper script with no other dependencies. So please do
9 # not try to refactor this to rely on anything else.
13 MANIFEST_URL_EXT='https://chromium.googlesource.com/chromiumos/manifest.git'
14 MANIFEST_URL_INT='https://chrome-internal.googlesource.com/chromeos/manifest-internal.git'
15 REPO_URL='https://chromium.googlesource.com/external/repo.git'
16 # When we make commits to manifest git repos, we want the owner info to be the
17 # same, and we want it to map to info that end users are unlikely to use. That
18 # way when the local repo rebase runs, it handles the update gracefully.
19 export GIT_AUTHOR_NAME='Elmur Fudsicle' GIT_AUTHOR_EMAIL='<baba@booya.bizzle>'
27 if [[ -z ${QUIET} ]]; then
41 _pushd() { pushd "$@" >/dev/null; }
42 _popd() { popd "$@" >/dev/null; }
49 Create or maintain a mirror of the ChromiumOS repository.
51 Usage: ${ARGV0} [options] --root <dir>
54 --external Pull the external ChromiumOS manifest
55 --internal Pull the internal ChromeOS manifest (note: Googler-only)
56 -j, --jobs Number of fetch jobs to run in parallel (default ${JOBS})
58 -r, --root The directory to hold all mirroring information
59 -u, --url The URL that people will use to pull from this mirror
60 -m, --manifest The repo manifest to use as a basis (default default.xml)
63 You must specify the --url option at least once so that all of the paths can
64 be rewritten for external users. After that, it should be automatically saved
65 and restored at runtime by this script.
68 # Create a full mirror in \${PWD} and have users fetch from the local machine.
69 \$ ${ARGV0} -r . -u git://$(hostname -f)
70 # Update the mirror (put this into a cronjob).
71 \$ ${ARGV0} -q -r ${ROOT:-${PWD}}
73 See this page for more information:
74 http://dev.chromium.org/chromium-os/how-tos-and-troubleshooting/creating-local-mirrors
79 JOBS=$(getconf _NPROCESSORS_ONLN 2>/dev/null || echo 4)
81 MANIFEST_NAME=default.xml
85 while [[ $# -gt 0 ]]; do
87 --external) MANIFEST_URL=${MANIFEST_URL_EXT};;
88 --internal) MANIFEST_URL=${MANIFEST_URL_INT};;
89 -j|--jobs) JOBS=$2; shift;;
90 -q|--quiet) QUIET="-q";;
91 -r|--root) ROOT=$2; shift;;
92 -u|--url) URL=$2; shift;;
93 -m|--manifest) MANIFEST_NAME=$2; shift;;
101 if [[ -z ${ROOT} ]]; then
102 die "need to specify root dir with --root"
104 if [[ ! -d ${ROOT} ]]; then
105 die "specified root dir does not exist; please run: mkdir '${ROOT}'"
111 # Make sure our tools are up-to-date.
113 if ! which repo >/dev/null; then
114 die "you must have repo installed and in your \$PATH; please see:" \
115 "http://dev.chromium.org/developers/how-tos/install-depot-tools"
117 # This has been tested against 1.7.7.x, so require at least that.
118 if ! gver=$(git --version); then
119 die "you must have git installed!"
124 local ver=( $(echo $(IFS=.; echo $*)) )
126 : $(( i = (i << 8) | ${ver[v]} ))
130 if [[ $(ver_to_int "${bver}") -gt $(ver_to_int "${gver##* }") ]]; then
131 die "your git version is too old (${gver}); we require at least git ${bver}"
136 # Initialize the whole tree mirror style.
139 repo init -u "${MANIFEST_URL}" -m "${MANIFEST_NAME}" \
140 --repo-url="${REPO_URL}" ${QUIET} "$@"
142 if [[ ! -d .repo ]]; then
143 # Default to external manifest.
144 : ${MANIFEST_URL:=${MANIFEST_URL_EXT}}
147 # Allow people to change manifests on the fly (internal<->external).
148 CURRENT_URL=$(git --git-dir=.repo/manifests.git config remote.origin.url)
149 # Find the previously defined manifest name by following the symbolic link.
150 CURRENT_NAME=$(readlink .repo/manifest.xml)
151 # Strip off the "manifests/" prefix.
152 CURRENT_NAME=${CURRENT_NAME#manifests/}
153 # If no manifest was selected, default to the current one.
154 : ${MANIFEST_URL:=${CURRENT_URL}}
155 if [[ "${CURRENT_URL}" != "${MANIFEST_URL}" || \
156 "${CURRENT_NAME}" != "${MANIFEST_NAME}" ]]; then
157 info "re-initing due to URL or manifest change: \
158 ${CURRENT_URL} -> ${MANIFEST_URL}, ${CURRENT_NAME} -> ${MANIFEST_NAME}"
162 if [[ ! -e git ]]; then
167 # Pull down any updates.
169 info "syncing the whole tree"
170 repo sync -j${JOBS} ${QUIET}
173 # Setup our local manifests repo which we'll hack on to point
174 # to our local mirror. We can't modify the repo in place as
175 # we want to make sure updates are atomic -- don't want other
176 # people to be able to accidentally pull in an unmodified repo.
180 local checkout=${git_repo##*/}
181 checkout=${checkout%.git}
183 if [[ ${MANIFEST_URL} == "${MANIFEST_URL_INT}" ]]; then
184 # Try to head off leakage of Google data.
186 ssh://* | file://*) ;;
188 die "You *must* use a secure channel like ssh:// or file://" \
189 "when mirroring internal Google repositories."
194 if [[ ! -d ${checkout} ]]; then
195 info "cloning ${checkout}"
196 git clone ${QUIET} ./${git_repo} ${checkout}
197 # Make the path relative so the whole tree can be moved w/out breaking.
198 git --git-dir=${checkout}/.git config remote.origin.url ../${git_repo}
201 info "updating ${checkout}"
204 if [[ -z ${URL} ]]; then
205 # Extract the local URI if they didn't specify one.
206 URL=$(eval $(grep -h fetch= *.xml); echo ${fetch})
207 if [[ ${URL} == "https://chromium.googlesource.com" ]]; then
208 # Guess they want the current system.
209 URL="git://$(hostname -f)"
213 # Setup the fetch= field of the manifest to point to our local mirror.
215 $(git ls-remote | sed 's:.*/::' | egrep -v '\<(HEAD|^master)$')
218 info "rewriting ${checkout} branches to ${URL}"
219 for b in "${branches[@]}"; do
220 git checkout -q -f -B ${b} origin/${b} >/dev/null
221 find -name '*.xml' -type f \
222 -exec sed -i "s|fetch=\"[^\"]*\"|fetch=\"${URL}\"|" {} +
223 git commit -q -a -m 'set fetch references to local mirror'
226 # Push out our updates.
227 local pub="../${git_repo%.git}-mirror.git"
228 if [[ ! -e ${pub} ]]; then
229 git --git-dir="${pub}" init ${QUIET}
231 git push ${QUIET} -f "${pub}" 'refs/heads/*:refs/heads/*'
234 update_manifests chromiumos/manifest.git
235 if [[ ${MANIFEST_URL} == "${MANIFEST_URL_INT}" ]]; then
236 update_manifests chromeos/manifest-internal.git
242 if [[ -z ${QUIET} ]]; then
243 if [[ ${MANIFEST_URL} == "${MANIFEST_URL_EXT}" ]]; then
246 You can now serve this tree with:
247 git daemon --base-path=${ROOT} --export-all
249 Your users can pull from this mirror with:
250 repo init -u ${URL}/chromiumos/manifest-mirror.git --repo-url=${URL}/external/repo.git
255 You must only serve these resources over encrypted channels like ssh://.
257 Your users can pull from this mirror with:
258 repo init -u ${URL}/chromeos/manifest-internal-mirror.git --repo-url=${URL}/external/repo.git