Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 489100 | Differences between
and this patch

Collapse All | Expand All

(-)a/eclass/git-r3.eclass (-178 / +18 lines)
Lines 8-15 Link Here
8
# @BLURB: Eclass for fetching and unpacking git repositories.
8
# @BLURB: Eclass for fetching and unpacking git repositories.
9
# @DESCRIPTION:
9
# @DESCRIPTION:
10
# Third generation eclass for easing maitenance of live ebuilds using
10
# Third generation eclass for easing maitenance of live ebuilds using
11
# git as remote repository. The eclass supports lightweight (shallow)
11
# git as remote repository.
12
# clones and bare clones of submodules.
13
12
14
case "${EAPI:-0}" in
13
case "${EAPI:-0}" in
15
	0|1|2|3|4|5)
14
	0|1|2|3|4|5)
Lines 83-100 fi Link Here
83
#
82
#
84
# EGIT_CHECKOUT_DIR=${WORKDIR}/${P}
83
# EGIT_CHECKOUT_DIR=${WORKDIR}/${P}
85
84
86
# @ECLASS-VARIABLE: EGIT_NONSHALLOW
87
# @DEFAULT_UNSET
88
# @DESCRIPTION:
89
# Disable performing shallow fetches/clones. Shallow clones have
90
# a fair number of limitations. Therefore, if you'd like the eclass to
91
# perform complete clones instead, set this to a non-null value.
92
#
93
# This variable can be set in make.conf and ebuilds. The make.conf
94
# value specifies user-specific default, while ebuilds may use it
95
# to force deep clones when the server does not support shallow clones
96
# (e.g. Google Code).
97
98
# @FUNCTION: _git-r3_env_setup
85
# @FUNCTION: _git-r3_env_setup
99
# @INTERNAL
86
# @INTERNAL
100
# @DESCRIPTION:
87
# @DESCRIPTION:
Lines 217-230 _git-r3_set_gitdir() { Link Here
217
	fi
204
	fi
218
205
219
	addwrite "${EGIT3_STORE_DIR}"
206
	addwrite "${EGIT3_STORE_DIR}"
207
	if [[ -e ${GIT_DIR}/shallow ]]; then
208
		einfo "${GIT_DIR} was a shallow clone, recreating..."
209
		rm -r "${GIT_DIR}" || die
210
	fi
220
	if [[ ! -d ${GIT_DIR} ]]; then
211
	if [[ ! -d ${GIT_DIR} ]]; then
221
		mkdir "${GIT_DIR}" || die
212
		mkdir "${GIT_DIR}" || die
222
		git init --bare || die
213
		git init --bare || die
223
224
		if [[ ! ${EGIT_NONSHALLOW} ]]; then
225
			# avoid auto-unshallow :)
226
			touch "${GIT_DIR}"/shallow || die
227
		fi
228
	fi
214
	fi
229
}
215
}
230
216
Lines 267-359 _git-r3_set_submodules() { Link Here
267
	done < <(echo "${data}" | git config -f /dev/fd/0 -l || die)
253
	done < <(echo "${data}" | git config -f /dev/fd/0 -l || die)
268
}
254
}
269
255
270
# @FUNCTION: _git-r3_smart_fetch
271
# @USAGE: <git-fetch-args>...
272
# @DESCRIPTION:
273
# Try fetching without '--depth' and switch to '--depth 1' if that
274
# will involve less objects fetched.
275
_git-r3_smart_fetch() {
276
	debug-print-function ${FUNCNAME} "$@"
277
278
	local sed_regexp='.*Counting objects: \([0-9]*\), done\..*'
279
280
	# start the main fetch
281
	local cmd=( git fetch --progress "${@}" )
282
	echo "${cmd[@]}" >&2
283
284
	# we copy the output to the 'sed' pipe for parsing. whenever sed finds
285
	# the process count, it quits quickly to avoid delays in writing it.
286
	# then, we start a dummy 'cat' to keep the pipe alive
287
288
	"${cmd[@]}" 2>&1 \
289
		| tee >(
290
			sed -n -e "/${sed_regexp}/{s/${sed_regexp}/\1/p;q}" \
291
				> "${T}"/git-r3_main.count
292
			exec cat >/dev/null
293
		) &
294
	local main_pid=${!}
295
296
	# start the helper process
297
	_git-r3_sub_fetch() {
298
		# wait for main fetch to get object count; if the server doesn't
299
		# output it, we won't even launch the parallel process
300
		while [[ ! -s ${T}/git-r3_main.count ]]; do
301
			sleep 0.25
302
		done
303
304
		# ok, let's see if parallel fetch gives us smaller count
305
		# --dry-run will prevent it from writing to the local clone
306
		# and sed should terminate git with SIGPIPE
307
		local sub_count=$(git fetch --progress --dry-run --depth 1 "${@}" 2>&1 \
308
			| sed -n -e "/${sed_regexp}/{s/${sed_regexp}/\1/p;q}")
309
		local main_count=$(<"${T}"/git-r3_main.count)
310
311
		# let's be real sure that '--depth 1' will be good for us.
312
		# note that we have purely objects counts, and '--depth 1'
313
		# may involve much bigger objects
314
		if [[ ${main_count} && ${main_count} -ge $(( sub_count * 3/2 )) ]]
315
		then
316
			# signal that we want shallow fetch instead,
317
			# and terminate the non-shallow fetch process
318
			touch "${T}"/git-r3_want_shallow || die
319
			kill ${main_pid} &>/dev/null
320
			exit 0
321
		fi
322
323
		exit 1
324
	}
325
	_git-r3_sub_fetch "${@}" &
326
	local sub_pid=${!}
327
328
	# wait for main process to terminate, either of its own
329
	# or by signal from subprocess
330
	wait ${main_pid}
331
	local main_ret=${?}
332
333
	# wait for subprocess to terminate, killing it if necessary.
334
	# if main fetch finished before it, there's no point in keeping
335
	# it alive. if main fetch was killed by it, it's done anyway
336
	kill ${sub_pid} &>/dev/null
337
	wait ${sub_pid}
338
339
	# now see if subprocess wanted to tell us something...
340
	if [[ -f ${T}/git-r3_want_shallow ]]; then
341
		rm "${T}"/git-r3_want_shallow || die
342
343
		# if fetch finished already (wasn't killed), ignore it
344
		[[ ${main_ret} -eq 0 ]] && return 0
345
346
		# otherwise, restart as shallow fetch
347
		einfo "Restarting fetch using --depth 1 to save bandwidth ..."
348
		local cmd=( git fetch --progress --depth 1 "${@}" )
349
		echo "${cmd[@]}" >&2
350
		"${cmd[@]}"
351
		main_ret=${?}
352
	fi
353
354
	return ${main_ret}
355
}
356
357
# @FUNCTION: _git-r3_is_local_repo
256
# @FUNCTION: _git-r3_is_local_repo
358
# @USAGE: <repo-uri>
257
# @USAGE: <repo-uri>
359
# @INTERNAL
258
# @INTERNAL
Lines 425-431 git-r3_fetch() { Link Here
425
	for r in "${repos[@]}"; do
324
	for r in "${repos[@]}"; do
426
		einfo "Fetching ${remote_ref} from ${r} ..."
325
		einfo "Fetching ${remote_ref} from ${r} ..."
427
326
428
		local is_branch lookup_ref
327
		local lookup_ref
429
		if [[ ${remote_ref} == refs/heads/* || ${remote_ref} == HEAD ]]
328
		if [[ ${remote_ref} == refs/heads/* || ${remote_ref} == HEAD ]]
430
		then
329
		then
431
			is_branch=1
330
			is_branch=1
Lines 436-515 git-r3_fetch() { Link Here
436
			lookup_ref=refs/tags/${remote_ref}
335
			lookup_ref=refs/tags/${remote_ref}
437
		fi
336
		fi
438
337
439
		# first, try ls-remote to see if ${remote_ref} is a real ref
338
		local fetch_command=(
440
		# and not a commit id. if it succeeds, we can pass ${remote_ref}
339
			git fetch --prune "${r}"
441
		# to 'fetch'. otherwise, we will just fetch everything
340
			# mirror the remote branches as local branches
442
341
			"refs/heads/*:refs/heads/*"
443
		# split on whitespace
342
			# pull tags explicitly in order to prune them properly
444
		local ref=(
343
			"refs/tags/*:refs/tags/*"
445
			$(git ls-remote "${r}" "${lookup_ref}" || echo __FAIL__)
446
		)
344
		)
447
345
448
		# normally, ref[0] is a hash, so we can do magic strings here
346
		set -- "${fetch_command[@]}"
449
		[[ ${ref[0]} == __FAIL__ ]] && continue
450
451
		local nonshallow=${EGIT_NONSHALLOW}
452
		local ref_param=()
453
		if [[ ! ${ref[0]} ]]; then
454
			nonshallow=1
455
		fi
456
457
		# trying to do a shallow clone of a local repo makes git try to
458
		# write to the repo. we don't want that to happen.
459
		_git-r3_is_local_repo "${r}" && nonshallow=1
460
461
		# 1. if we need a non-shallow clone and we have a shallow one,
462
		#    we need to unshallow it explicitly.
463
		# 2. if we want a shallow clone, we just pass '--depth 1'
464
		#    to the first fetch in the repo. passing '--depth'
465
		#    to further requests usually results in more data being
466
		#    downloaded than without it.
467
		# 3. if we update a shallow clone, we try without '--depth'
468
		#    first since that usually transfers less data. however,
469
		#    we use git-r3_smart_fetch that can switch into '--depth 1'
470
		#    if that looks beneficial.
471
472
		local fetch_command=( git fetch )
473
		if [[ ${nonshallow} ]]; then
474
			if [[ -f ${GIT_DIR}/shallow ]]; then
475
				ref_param+=( --unshallow )
476
			fi
477
			# fetch all branches
478
			ref_param+=( "refs/heads/*:refs/remotes/origin/*" )
479
		else
480
			# 'git show-ref --heads' returns 1 when there are no branches
481
			if ! git show-ref --heads -q; then
482
				ref_param+=( --depth 1 )
483
			else
484
				fetch_command=( _git-r3_smart_fetch )
485
			fi
486
		fi
487
488
		# now, another important thing. we may only fetch a remote
489
		# branch directly to a local branch. Otherwise, we need to fetch
490
		# the commit and re-create the branch on top of it.
491
492
		if [[ ${ref[0]} ]]; then
493
			if [[ ${is_branch} ]]; then
494
				ref_param+=( -f "${remote_ref}:${local_id}/__main__" )
495
			else
496
				ref_param+=( "refs/tags/${remote_ref}" )
497
			fi
498
		fi
499
500
		# if ${remote_ref} is branch or tag, ${ref[@]} will contain
501
		# the respective commit id. otherwise, it will be an empty
502
		# array, so the following won't evaluate to a parameter.
503
		set -- "${fetch_command[@]}" --no-tags "${r}" "${ref_param[@]}"
504
		echo "${@}" >&2
347
		echo "${@}" >&2
505
		if "${@}"; then
348
		if "${@}"; then
506
			if [[ ! ${is_branch} ]]; then
349
			set -- git branch -f "${local_id}/__main__" \
507
				set -- git branch -f "${local_id}/__main__" \
350
				"${ref[0]:-${remote_ref}}"
508
					"${ref[0]:-${remote_ref}}"
351
			echo "${@}" >&2
509
				echo "${@}" >&2
352
			if ! "${@}"; then
510
				if ! "${@}"; then
353
				die "Creating branch for ${remote_ref} failed (wrong ref?)."
511
					die "Creating branch for ${remote_ref} failed (wrong ref?)."
512
				fi
513
			fi
354
			fi
514
355
515
			success=1
356
			success=1
516
- 

Return to bug 489100