/[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.1 Revision 1.4
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.1 2013/09/05 20:24:10 mgorny Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.4 2013/09/13 15:04:36 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#
312 # split on whitespace 399 # split on whitespace
313 local ref=( 400 local ref=(
314 $(git ls-remote "${r}" "${lookup_ref}") 401 $(git ls-remote "${r}" "${lookup_ref}")
315 ) 402 )
316 403
404 local nonshallow=${EGIT_NONSHALLOW}
405 local ref_param=()
406 if [[ ! ${ref[0]} ]]; then
407 nonshallow=1
408 fi
409
410 # 1. if we need a non-shallow clone and we have a shallow one,
411 # we need to unshallow it explicitly.
412 # 2. if we want a shallow clone, we just pass '--depth 1'
413 # to the first fetch in the repo. passing '--depth'
414 # to further requests usually results in more data being
415 # downloaded than without it.
416 # 3. if we update a shallow clone, we try without '--depth'
417 # first since that usually transfers less data. however,
418 # we use git-r3_smart_fetch that can switch into '--depth 1'
419 # if that looks beneficial.
420
421 local fetch_command=( git fetch )
422 if [[ ${nonshallow} ]]; then
423 if [[ -f ${GIT_DIR}/shallow ]]; then
424 ref_param+=( --unshallow )
425 fi
426 else
427 # 'git show-ref --heads' returns 1 when there are no branches
428 if ! git show-ref --heads -q; then
429 ref_param+=( --depth 1 )
430 else
431 fetch_command=( _git-r3_smart_fetch )
432 fi
433 fi
434
317 # now, another important thing. we may only fetch a remote 435 # now, another important thing. we may only fetch a remote
318 # branch directly to a local branch. Otherwise, we need to fetch 436 # branch directly to a local branch. Otherwise, we need to fetch
319 # the commit and re-create the branch on top of it. 437 # the commit and re-create the branch on top of it.
320
321 local ref_param=()
322 if [[ ! ${ref[0]} ]]; then
323 local EGIT_NONSHALLOW=1
324 fi
325
326 if [[ ! -f ${GIT_DIR}/shallow ]]; then
327 # if it's a complete repo, fetch it as-is
328 :
329 elif [[ ${EGIT_NONSHALLOW} ]]; then
330 # if it's a shallow clone but we need complete,
331 # unshallow it
332 ref_param+=( --unshallow )
333 else
334 # otherwise, just fetch as shallow
335 ref_param+=( --depth 1 )
336 fi
337 438
338 if [[ ${ref[0]} ]]; then 439 if [[ ${ref[0]} ]]; then
339 if [[ ${is_branch} ]]; then 440 if [[ ${is_branch} ]]; then
340 ref_param+=( -f "${remote_ref}:${local_id}/__main__" ) 441 ref_param+=( -f "${remote_ref}:${local_id}/__main__" )
341 else 442 else
344 fi 445 fi
345 446
346 # if ${remote_ref} is branch or tag, ${ref[@]} will contain 447 # if ${remote_ref} is branch or tag, ${ref[@]} will contain
347 # the respective commit id. otherwise, it will be an empty 448 # the respective commit id. otherwise, it will be an empty
348 # array, so the following won't evaluate to a parameter. 449 # array, so the following won't evaluate to a parameter.
349 set -- git fetch --no-tags "${r}" "${ref_param[@]}" 450 set -- "${fetch_command[@]}" --no-tags "${r}" "${ref_param[@]}"
350 echo "${@}" >&2 451 echo "${@}" >&2
351 if "${@}"; then 452 if "${@}"; then
352 if [[ ! ${is_branch} ]]; then 453 if [[ ! ${is_branch} ]]; then
353 set -- git branch -f "${local_id}/__main__" \ 454 set -- git branch -f "${local_id}/__main__" \
354 "${ref[0]:-${remote_ref}}" 455 "${ref[0]:-${remote_ref}}"

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.4

  ViewVC Help
Powered by ViewVC 1.1.20