/[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.28 Revision 1.35
1# Copyright 1999-2014 Gentoo Foundation 1# Copyright 1999-2014 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.28 2014/03/02 11:45:41 mgorny Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.35 2014/03/02 11:49:05 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.
27EXPORT_FUNCTIONS src_unpack 27EXPORT_FUNCTIONS src_unpack
28 28
29if [[ ! ${_GIT_R3} ]]; then 29if [[ ! ${_GIT_R3} ]]; then
30 30
31if [[ ! ${_INHERITED_BY_GIT_2} ]]; then 31if [[ ! ${_INHERITED_BY_GIT_2} ]]; then
32 DEPEND="dev-vcs/git" 32 DEPEND=">=dev-vcs/git-1.8.2.1"
33fi 33fi
34
35# @ECLASS-VARIABLE: EGIT_CLONE_TYPE
36# @DESCRIPTION:
37# Type of clone that should be used against the remote repository.
38# This can be either of: 'mirror', 'single', 'shallow'.
39#
40# The 'mirror' type clones all remote branches and tags with complete
41# history and all notes. EGIT_COMMIT can specify any commit hash.
42# Upstream-removed branches and tags are purged from the local clone
43# while fetching. This mode is suitable for cloning the local copy
44# for development or hosting a local git mirror. However, clones
45# of repositories with large diverged branches may quickly grow large.
46#
47# The 'single' type clones only the requested branch or tag. Tags
48# referencing commits throughout the branch history are fetched as well,
49# and all notes. EGIT_COMMIT can safely specify only hashes
50# in the current branch. No purging of old references is done (if you
51# often switch branches, you may need to remove stale branches
52# yourself). This mode is suitable for general use.
53#
54# The 'shallow' type clones only the newest commit on requested branch
55# or tag. EGIT_COMMIT can only specify tags, and since the history is
56# unavailable calls like 'git describe' will not reference prior tags.
57# No purging of old references is done. This mode is intended mostly for
58# embedded systems with limited disk space.
59: ${EGIT_CLONE_TYPE:=single}
60
61# @ECLASS-VARIABLE: EGIT_MIN_CLONE_TYPE
62# @DESCRIPTION:
63# 'Minimum' clone type supported by the ebuild. Takes same values
64# as EGIT_CLONE_TYPE. When user sets a type that's 'lower' (that is,
65# later on the list) than EGIT_MIN_CLONE_TYPE, the eclass uses
66# EGIT_MIN_CLONE_TYPE instead.
67#
68# A common case is to use 'single' whenever the build system requires
69# access to full branch history or the remote (Google Code) does not
70# support shallow clones. Please use sparingly, and to fix fatal errors
71# rather than 'non-pretty versions'.
72: ${EGIT_MIN_CLONE_TYPE:=shallow}
34 73
35# @ECLASS-VARIABLE: EGIT3_STORE_DIR 74# @ECLASS-VARIABLE: EGIT3_STORE_DIR
36# @DESCRIPTION: 75# @DESCRIPTION:
37# Storage directory for git sources. 76# Storage directory for git sources.
38# 77#
39# This is intended to be set by user in make.conf. Ebuilds must not set 78# This is intended to be set by user in make.conf. Ebuilds must not set
40# it. 79# it.
41# 80#
42# EGIT3_STORE_DIR=${DISTDIR}/git3-src 81# EGIT3_STORE_DIR=${DISTDIR}/git3-src
82
83# @ECLASS-VARIABLE: EGIT_MIRROR_URI
84# @DEFAULT_UNSET
85# @DESCRIPTION:
86# 'Top' URI to a local git mirror. If specified, the eclass will try
87# to fetch from the local mirror instead of using the remote repository.
88#
89# The mirror needs to follow EGIT3_STORE_DIR structure. The directory
90# created by eclass can be used for that purpose.
91#
92# Example:
93# @CODE
94# EGIT_MIRROR_URI="git://mirror.lan/"
95# @CODE
43 96
44# @ECLASS-VARIABLE: EGIT_REPO_URI 97# @ECLASS-VARIABLE: EGIT_REPO_URI
45# @REQUIRED 98# @REQUIRED
46# @DESCRIPTION: 99# @DESCRIPTION:
47# URIs to the repository, e.g. git://foo, https://foo. If multiple URIs 100# URIs to the repository, e.g. git://foo, https://foo. If multiple URIs
90# @DESCRIPTION: 143# @DESCRIPTION:
91# Set the eclass variables as necessary for operation. This can involve 144# Set the eclass variables as necessary for operation. This can involve
92# setting EGIT_* to defaults or ${PN}_LIVE_* variables. 145# setting EGIT_* to defaults or ${PN}_LIVE_* variables.
93_git-r3_env_setup() { 146_git-r3_env_setup() {
94 debug-print-function ${FUNCNAME} "$@" 147 debug-print-function ${FUNCNAME} "$@"
148
149 # check the clone type
150 case "${EGIT_CLONE_TYPE}" in
151 mirror|single|shallow)
152 ;;
153 *)
154 die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}"
155 esac
156 case "${EGIT_MIN_CLONE_TYPE}" in
157 shallow)
158 ;;
159 single)
160 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
161 einfo "git-r3: ebuild needs to be cloned in 'single' mode, adjusting"
162 EGIT_CLONE_TYPE=single
163 fi
164 ;;
165 mirror)
166 if [[ ${EGIT_CLONE_TYPE} != mirror ]]; then
167 einfo "git-r3: ebuild needs to be cloned in 'mirror' mode, adjusting"
168 EGIT_CLONE_TYPE=mirror
169 fi
170 ;;
171 *)
172 die "Invalid EGIT_MIN_CLONE_TYPE=${EGIT_MIN_CLONE_TYPE}"
173 esac
95 174
96 local esc_pn livevar 175 local esc_pn livevar
97 esc_pn=${PN//[-+]/_} 176 esc_pn=${PN//[-+]/_}
98 177
99 livevar=${esc_pn}_LIVE_REPO 178 livevar=${esc_pn}_LIVE_REPO
205 mkdir -m0755 -p "${EGIT3_STORE_DIR}" || die 284 mkdir -m0755 -p "${EGIT3_STORE_DIR}" || die
206 ) || die "Unable to create ${EGIT3_STORE_DIR}" 285 ) || die "Unable to create ${EGIT3_STORE_DIR}"
207 fi 286 fi
208 287
209 addwrite "${EGIT3_STORE_DIR}" 288 addwrite "${EGIT3_STORE_DIR}"
210 if [[ -e ${GIT_DIR}/shallow ]]; then
211 einfo "${GIT_DIR} was a shallow clone, recreating..."
212 rm -r "${GIT_DIR}" || die
213 fi
214 if [[ ! -d ${GIT_DIR} ]]; then 289 if [[ ! -d ${GIT_DIR} ]]; then
215 mkdir "${GIT_DIR}" || die 290 mkdir "${GIT_DIR}" || die
216 git init --bare || die 291 git init --bare || die
217 fi 292 fi
218} 293}
268 local uri=${1} 343 local uri=${1}
269 344
270 [[ ${uri} == file://* || ${uri} == /* ]] 345 [[ ${uri} == file://* || ${uri} == /* ]]
271} 346}
272 347
348# @FUNCTION: _git-r3_find_head
349# @USAGE: <head-ref>
350# @INTERNAL
351# @DESCRIPTION:
352# Given a ref to which remote HEAD was fetched, try to find
353# a branch matching the commit. Expects 'git show-ref'
354# or 'git ls-remote' output on stdin.
355_git-r3_find_head() {
356 debug-print-function ${FUNCNAME} "$@"
357
358 local head_ref=${1}
359 local head_hash=$(git rev-parse --verify "${1}" || die)
360 local matching_ref
361
362 # TODO: some transports support peeking at symbolic remote refs
363 # find a way to use that rather than guessing
364
365 # (based on guess_remote_head() in git-1.9.0/remote.c)
366 local h ref
367 while read h ref; do
368 # look for matching head
369 if [[ ${h} == ${head_hash} ]]; then
370 # either take the first matching ref, or master if it is there
371 if [[ ! ${matching_ref} || ${ref} == refs/heads/master ]]; then
372 matching_ref=${ref}
373 fi
374 fi
375 done
376
377 if [[ ! ${matching_ref} ]]; then
378 die "Unable to find a matching branch for remote HEAD (${head_hash})"
379 fi
380
381 echo "${matching_ref}"
382}
383
273# @FUNCTION: git-r3_fetch 384# @FUNCTION: git-r3_fetch
274# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]] 385# @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]]
275# @DESCRIPTION: 386# @DESCRIPTION:
276# Fetch new commits to the local clone of repository. 387# Fetch new commits to the local clone of repository.
277# 388#
320 [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset" 431 [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
321 432
322 local -x GIT_DIR 433 local -x GIT_DIR
323 _git-r3_set_gitdir "${repos[0]}" 434 _git-r3_set_gitdir "${repos[0]}"
324 435
436 # prepend the local mirror if applicable
437 if [[ ${EGIT_MIRROR_URI} ]]; then
438 repos=(
439 "${EGIT_MIRROR_URI%/}/${GIT_DIR##*/}"
440 "${repos[@]}"
441 )
442 fi
443
325 # try to fetch from the remote 444 # try to fetch from the remote
326 local r success 445 local r success
327 for r in "${repos[@]}"; do 446 for r in "${repos[@]}"; do
328 einfo "Fetching ${r} ..." 447 einfo "Fetching ${r} ..."
329 448
449 local fetch_command=( git fetch "${r}" )
450
451 if [[ ${EGIT_CLONE_TYPE} == mirror ]]; then
330 local fetch_command=( 452 fetch_command+=(
331 git fetch --prune "${r}" 453 --prune
332 # mirror the remote branches as local branches 454 # mirror the remote branches as local branches
333 "refs/heads/*:refs/heads/*" 455 "refs/heads/*:refs/heads/*"
334 # pull tags explicitly in order to prune them properly 456 # pull tags explicitly in order to prune them properly
335 "refs/tags/*:refs/tags/*" 457 "refs/tags/*:refs/tags/*"
336 # notes in case something needs them 458 # notes in case something needs them
337 "refs/notes/*:refs/notes/*" 459 "refs/notes/*:refs/notes/*"
460 # and HEAD in case we need the default branch
461 # (we keep it in refs/git-r3 since otherwise --prune interferes)
462 HEAD:refs/git-r3/HEAD
338 ) 463 )
464 else # single or shallow
465 local fetch_l fetch_r
466
467 if [[ ${remote_ref} == HEAD ]]; then
468 # HEAD
469 fetch_l=HEAD
470 elif [[ ${remote_ref} == refs/heads/* ]]; then
471 # regular branch
472 fetch_l=${remote_ref}
473 else
474 # tag or commit...
475 # let ls-remote figure it out
476 local tagref=$(git ls-remote "${r}" "refs/tags/${remote_ref}")
477
478 # if it was a tag, ls-remote obtained a hash
479 if [[ ${tagref} ]]; then
480 # tag
481 fetch_l=refs/tags/${remote_ref}
482 else
483 # commit
484 # so we need to fetch the branch
485 if [[ ${branch} ]]; then
486 fetch_l=${branch}
487 else
488 fetch_l=HEAD
489 fi
490
491 # fetching by commit in shallow mode? can't do.
492 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
493 local EGIT_CLONE_TYPE=single
494 fi
495 fi
496 fi
497
498 if [[ ${fetch_l} == HEAD ]]; then
499 fetch_r=refs/git-r3/HEAD
500 else
501 fetch_r=${fetch_l}
502 fi
503
504 fetch_command+=(
505 "${fetch_l}:${fetch_r}"
506 )
507 fi
508
509 if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then
510 # use '--depth 1' when fetching a new branch
511 if [[ ! $(git rev-parse --quiet --verify "${fetch_r}") ]]
512 then
513 fetch_command+=( --depth 1 )
514 fi
515 else # non-shallow mode
516 if [[ -f ${GIT_DIR}/shallow ]]; then
517 fetch_command+=( --unshallow )
518 fi
519 fi
339 520
340 set -- "${fetch_command[@]}" 521 set -- "${fetch_command[@]}"
341 echo "${@}" >&2 522 echo "${@}" >&2
342 if "${@}"; then 523 if "${@}"; then
524 if [[ ${EGIT_CLONE_TYPE} == mirror ]]; then
525 # find remote HEAD and update our HEAD properly
526 git symbolic-ref HEAD \
527 "$(_git-r3_find_head refs/git-r3/HEAD \
528 < <(git show-ref --heads || die))" \
529 || die "Unable to update HEAD"
530 else # single or shallow
531 if [[ ${fetch_l} == HEAD ]]; then
532 # find out what branch we fetched as HEAD
533 local head_branch=$(_git-r3_find_head \
534 refs/git-r3/HEAD \
535 < <(git ls-remote --heads "${r}" || die))
536
537 # and move it to its regular place
538 git update-ref --no-deref "${head_branch}" \
539 refs/git-r3/HEAD \
540 || die "Unable to sync HEAD branch ${head_branch}"
541 git symbolic-ref HEAD "${head_branch}" \
542 || die "Unable to update HEAD"
543 fi
544 fi
545
343 # now let's see what the user wants from us 546 # now let's see what the user wants from us
344 local full_remote_ref=$( 547 local full_remote_ref=$(
345 git rev-parse --verify --symbolic-full-name "${remote_ref}" 548 git rev-parse --verify --symbolic-full-name "${remote_ref}"
346 ) 549 )
347 550
464 # [htn]* safely catches heads, tags, notes without complaining 667 # [htn]* safely catches heads, tags, notes without complaining
465 # on non-existing ones, and omits internal 'git-r3' ref 668 # on non-existing ones, and omits internal 'git-r3' ref
466 cp -R "${orig_repo}"/refs/[htn]* "${GIT_DIR}"/refs/ || die 669 cp -R "${orig_repo}"/refs/[htn]* "${GIT_DIR}"/refs/ || die
467 670
468 # (no need to copy HEAD, we will set it via checkout) 671 # (no need to copy HEAD, we will set it via checkout)
672
673 if [[ -f ${orig_repo}/shallow ]]; then
674 cp "${orig_repo}"/shallow "${GIT_DIR}"/ || die
675 fi
469 676
470 set -- git checkout --quiet 677 set -- git checkout --quiet
471 if [[ ${remote_ref} ]]; then 678 if [[ ${remote_ref} ]]; then
472 set -- "${@}" "${remote_ref#refs/heads/}" 679 set -- "${@}" "${remote_ref#refs/heads/}"
473 else 680 else

Legend:
Removed from v.1.28  
changed lines
  Added in v.1.35

  ViewVC Help
Powered by ViewVC 1.1.20