/[gentoo-x86]/eclass/git-r3.eclass
Gentoo

Diff of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.2 Revision 1.3
1# Copyright 1999-2013 Gentoo Foundation 1# Copyright 1999-2013 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.2 2013/09/05 22:40:12 mgorny Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.3 2013/09/09 16:01:17 mgorny Exp $
4 4
5# @ECLASS: git-r3.eclass 5# @ECLASS: git-r3.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# Michał Górny <mgorny@gentoo.org> 7# Michał Górny <mgorny@gentoo.org>
8# @BLURB: Eclass for fetching and unpacking git repositories. 8# @BLURB: Eclass for fetching and unpacking git repositories.
245 submodule."${subname}".path)" 245 submodule."${subname}".path)"
246 ) 246 )
247 done < <(echo "${data}" | git config -f /dev/fd/0 -l) 247 done < <(echo "${data}" | git config -f /dev/fd/0 -l)
248} 248}
249 249
250# @FUNCTION: _git-r3_smart_fetch
251# @USAGE: <git-fetch-args>...
252# @DESCRIPTION:
253# Try fetching without '--depth' and switch to '--depth 1' if that
254# will involve less objects fetched.
255_git-r3_smart_fetch() {
256 debug-print-function ${FUNCNAME} "$@"
257
258 local sed_regexp='.*Counting objects: \([0-9]*\), done\..*'
259
260 # start the main fetch
261 local cmd=( git fetch --progress "${@}" )
262 echo "${cmd[@]}" >&2
263
264 # we copy the output to the 'sed' pipe for parsing. whenever sed finds
265 # the process count, it quits quickly to avoid delays in writing it.
266 # then, we start a dummy 'cat' to keep the pipe alive
267
268 "${cmd[@]}" 2>&1 \
269 | tee >(
270 sed -n -e "/${sed_regexp}/{s/${sed_regexp}/\1/p;q}" \
271 > "${T}"/git-r3_main.count
272 exec cat >/dev/null
273 ) &
274 local main_pid=${!}
275
276 # start the helper process
277 _git-r3_sub_fetch() {
278 # wait for main fetch to get object count; if the server doesn't
279 # output it, we won't even launch the parallel process
280 while [[ ! -s ${T}/git-r3_main.count ]]; do
281 sleep 0.25
282 done
283
284 # ok, let's see if parallel fetch gives us smaller count
285 # --dry-run will prevent it from writing to the local clone
286 # and sed should terminate git with SIGPIPE
287 local sub_count=$(git fetch --progress --dry-run --depth 1 "${@}" 2>&1 \
288 | sed -n -e "/${sed_regexp}/{s/${sed_regexp}/\1/p;q}")
289 local main_count=$(<"${T}"/git-r3_main.count)
290
291 # let's be real sure that '--depth 1' will be good for us.
292 # note that we have purely objects counts, and '--depth 1'
293 # may involve much bigger objects
294 if [[ ${main_count} && ${main_count} -ge $(( sub_count * 3/2 )) ]]
295 then
296 # signal that we want shallow fetch instead,
297 # and terminate the non-shallow fetch process
298 touch "${T}"/git-r3_want_shallow || die
299 kill ${main_pid} &>/dev/null
300 exit 0
301 fi
302
303 exit 1
304 }
305 _git-r3_sub_fetch "${@}" &
306 local sub_pid=${!}
307
308 # wait for main process to terminate, either of its own
309 # or by signal from subprocess
310 wait ${main_pid}
311 local main_ret=${?}
312
313 # wait for subprocess to terminate, killing it if necessary.
314 # if main fetch finished before it, there's no point in keeping
315 # it alive. if main fetch was killed by it, it's done anyway
316 kill ${sub_pid} &>/dev/null
317 wait ${sub_pid}
318
319 # now see if subprocess wanted to tell us something...
320 if [[ -f ${T}/git-r3_want_shallow ]]; then
321 rm "${T}"/git-r3_want_shallow || die
322
323 # if fetch finished already (wasn't killed), ignore it
324 [[ ${main_ret} -eq 0 ]] && return 0
325
326 # otherwise, restart as shallow fetch
327 einfo "Restarting fetch using --depth 1 to save bandwidth ..."
328 local cmd=( git fetch --progress --depth 1 "${@}" )
329 echo "${cmd[@]}" >&2
330 "${cmd[@]}"
331 main_ret=${?}
332 fi
333
334 return ${main_ret}
335}
336
250# @FUNCTION: git-r3_fetch 337# @FUNCTION: git-r3_fetch
251# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]] 338# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]]
252# @DESCRIPTION: 339# @DESCRIPTION:
253# Fetch new commits to the local clone of repository. 340# Fetch new commits to the local clone of repository.
254# 341#
323 # we need to unshallow it explicitly. 410 # we need to unshallow it explicitly.
324 # 2. if we want a shallow clone, we just pass '--depth 1' 411 # 2. if we want a shallow clone, we just pass '--depth 1'
325 # to the first fetch in the repo. passing '--depth' 412 # to the first fetch in the repo. passing '--depth'
326 # to further requests usually results in more data being 413 # to further requests usually results in more data being
327 # downloaded than without it. 414 # downloaded than without it.
328 # 3. in any other case, we just do plain 'git fetch' and let 415 # 3. if we update a shallow clone, we try without '--depth'
329 # git to do its best (on top of shallow or non-shallow repo). 416 # first since that usually transfers less data. however,
417 # we use git-r3_smart_fetch that can switch into '--depth 1'
418 # if that looks beneficial.
330 419
420 local fetch_command=( git fetch )
331 if [[ ${EGIT_NONSHALLOW} ]]; then 421 if [[ ${EGIT_NONSHALLOW} ]]; then
332 if [[ -f ${GIT_DIR}/shallow ]]; then 422 if [[ -f ${GIT_DIR}/shallow ]]; then
333 ref_param+=( --unshallow ) 423 ref_param+=( --unshallow )
334 fi 424 fi
335 else 425 else
336 # 'git show-ref --heads' returns 1 when there are no branches 426 # 'git show-ref --heads' returns 1 when there are no branches
337 if ! git show-ref --heads -q; then 427 if ! git show-ref --heads -q; then
338 ref_param+=( --depth 1 ) 428 ref_param+=( --depth 1 )
429 else
430 fetch_command=( _git-r3_smart_fetch )
339 fi 431 fi
340 fi 432 fi
341 433
342 # now, another important thing. we may only fetch a remote 434 # now, another important thing. we may only fetch a remote
343 # branch directly to a local branch. Otherwise, we need to fetch 435 # branch directly to a local branch. Otherwise, we need to fetch
352 fi 444 fi
353 445
354 # if ${remote_ref} is branch or tag, ${ref[@]} will contain 446 # if ${remote_ref} is branch or tag, ${ref[@]} will contain
355 # the respective commit id. otherwise, it will be an empty 447 # the respective commit id. otherwise, it will be an empty
356 # array, so the following won't evaluate to a parameter. 448 # array, so the following won't evaluate to a parameter.
357 set -- git fetch --no-tags "${r}" "${ref_param[@]}" 449 set -- "${fetch_command[@]}" --no-tags "${r}" "${ref_param[@]}"
358 echo "${@}" >&2 450 echo "${@}" >&2
359 if "${@}"; then 451 if "${@}"; then
360 if [[ ! ${is_branch} ]]; then 452 if [[ ! ${is_branch} ]]; then
361 set -- git branch -f "${local_id}/__main__" \ 453 set -- git branch -f "${local_id}/__main__" \
362 "${ref[0]:-${remote_ref}}" 454 "${ref[0]:-${remote_ref}}"

Legend:
Removed from v.1.2  
changed lines
  Added in v.1.3

  ViewVC Help
Powered by ViewVC 1.1.20