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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.31 - (show annotations) (download)
Sun Mar 2 11:47:10 2014 UTC (9 months, 2 weeks ago) by mgorny
Branch: MAIN
Changes since 1.30: +22 -1 lines
Introduce EGIT_CLONE_TYPE for future use.

1 # Copyright 1999-2014 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.30 2014/03/02 11:46:42 mgorny Exp $
4
5 # @ECLASS: git-r3.eclass
6 # @MAINTAINER:
7 # Michał Górny <mgorny@gentoo.org>
8 # @BLURB: Eclass for fetching and unpacking git repositories.
9 # @DESCRIPTION:
10 # Third generation eclass for easing maitenance of live ebuilds using
11 # git as remote repository.
12
13 case "${EAPI:-0}" in
14 0|1|2|3|4|5)
15 ;;
16 *)
17 die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}"
18 ;;
19 esac
20
21 if [[ ! ${_GIT_R3} ]]; then
22
23 inherit eutils
24
25 fi
26
27 EXPORT_FUNCTIONS src_unpack
28
29 if [[ ! ${_GIT_R3} ]]; then
30
31 if [[ ! ${_INHERITED_BY_GIT_2} ]]; then
32 DEPEND="dev-vcs/git"
33 fi
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'.
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 : ${EGIT_CLONE_TYPE:=mirror}
47
48 # @ECLASS-VARIABLE: EGIT3_STORE_DIR
49 # @DESCRIPTION:
50 # Storage directory for git sources.
51 #
52 # This is intended to be set by user in make.conf. Ebuilds must not set
53 # it.
54 #
55 # EGIT3_STORE_DIR=${DISTDIR}/git3-src
56
57 # @ECLASS-VARIABLE: EGIT_MIRROR_URI
58 # @DEFAULT_UNSET
59 # @DESCRIPTION:
60 # 'Top' URI to a local git mirror. If specified, the eclass will try
61 # to fetch from the local mirror instead of using the remote repository.
62 #
63 # The mirror needs to follow EGIT3_STORE_DIR structure. The directory
64 # created by eclass can be used for that purpose.
65 #
66 # Example:
67 # @CODE
68 # EGIT_MIRROR_URI="git://mirror.lan/"
69 # @CODE
70
71 # @ECLASS-VARIABLE: EGIT_REPO_URI
72 # @REQUIRED
73 # @DESCRIPTION:
74 # URIs to the repository, e.g. git://foo, https://foo. If multiple URIs
75 # are provided, the eclass will consider them as fallback URIs to try
76 # if the first URI does not work.
77 #
78 # It can be overriden via env using ${PN}_LIVE_REPO variable.
79 #
80 # Can be a whitespace-separated list or an array.
81 #
82 # Example:
83 # @CODE
84 # EGIT_REPO_URI="git://a/b.git https://c/d.git"
85 # @CODE
86
87 # @ECLASS-VARIABLE: EVCS_OFFLINE
88 # @DEFAULT_UNSET
89 # @DESCRIPTION:
90 # If non-empty, this variable prevents any online operations.
91
92 # @ECLASS-VARIABLE: EGIT_BRANCH
93 # @DEFAULT_UNSET
94 # @DESCRIPTION:
95 # The branch name to check out. If unset, the upstream default (HEAD)
96 # will be used.
97 #
98 # It can be overriden via env using ${PN}_LIVE_BRANCH variable.
99
100 # @ECLASS-VARIABLE: EGIT_COMMIT
101 # @DEFAULT_UNSET
102 # @DESCRIPTION:
103 # The tag name or commit identifier to check out. If unset, newest
104 # commit from the branch will be used. If set, EGIT_BRANCH will
105 # be ignored.
106 #
107 # It can be overriden via env using ${PN}_LIVE_COMMIT variable.
108
109 # @ECLASS-VARIABLE: EGIT_CHECKOUT_DIR
110 # @DESCRIPTION:
111 # The directory to check the git sources out to.
112 #
113 # EGIT_CHECKOUT_DIR=${WORKDIR}/${P}
114
115 # @FUNCTION: _git-r3_env_setup
116 # @INTERNAL
117 # @DESCRIPTION:
118 # Set the eclass variables as necessary for operation. This can involve
119 # setting EGIT_* to defaults or ${PN}_LIVE_* variables.
120 _git-r3_env_setup() {
121 debug-print-function ${FUNCNAME} "$@"
122
123 # check the clone type
124 case "${EGIT_CLONE_TYPE}" in
125 mirror)
126 ;;
127 *)
128 die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}"
129 esac
130
131 local esc_pn livevar
132 esc_pn=${PN//[-+]/_}
133
134 livevar=${esc_pn}_LIVE_REPO
135 EGIT_REPO_URI=${!livevar:-${EGIT_REPO_URI}}
136 [[ ${!livevar} ]] \
137 && ewarn "Using ${livevar}, no support will be provided"
138
139 livevar=${esc_pn}_LIVE_BRANCH
140 EGIT_BRANCH=${!livevar:-${EGIT_BRANCH}}
141 [[ ${!livevar} ]] \
142 && ewarn "Using ${livevar}, no support will be provided"
143
144 livevar=${esc_pn}_LIVE_COMMIT
145 EGIT_COMMIT=${!livevar:-${EGIT_COMMIT}}
146 [[ ${!livevar} ]] \
147 && ewarn "Using ${livevar}, no support will be provided"
148
149 # Migration helpers. Remove them when git-2 is removed.
150
151 if [[ ${EGIT_SOURCEDIR} ]]; then
152 eerror "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR. While updating"
153 eerror "your ebuild, please check whether the variable is necessary at all"
154 eerror "since the default has been changed from \${S} to \${WORKDIR}/\${P}."
155 eerror "Therefore, proper setting of S may be sufficient."
156 die "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR."
157 fi
158
159 if [[ ${EGIT_MASTER} ]]; then
160 eerror "EGIT_MASTER has been removed. Instead, the upstream default (HEAD)"
161 eerror "is used by the eclass. Please remove the assignment or use EGIT_BRANCH"
162 eerror "as necessary."
163 die "EGIT_MASTER has been removed."
164 fi
165
166 if [[ ${EGIT_HAS_SUBMODULES} ]]; then
167 eerror "EGIT_HAS_SUBMODULES has been removed. The eclass no longer needs"
168 eerror "to switch the clone type in order to support submodules and therefore"
169 eerror "submodules are detected and fetched automatically."
170 die "EGIT_HAS_SUBMODULES is no longer necessary."
171 fi
172
173 if [[ ${EGIT_PROJECT} ]]; then
174 eerror "EGIT_PROJECT has been removed. Instead, the eclass determines"
175 eerror "the local clone path using path in canonical EGIT_REPO_URI."
176 eerror "If the current algorithm causes issues for you, please report a bug."
177 die "EGIT_PROJECT is no longer necessary."
178 fi
179
180 if [[ ${EGIT_BOOTSTRAP} ]]; then
181 eerror "EGIT_BOOTSTRAP has been removed. Please create proper src_prepare()"
182 eerror "instead."
183 die "EGIT_BOOTSTRAP has been removed."
184 fi
185
186 if [[ ${EGIT_NOUNPACK} ]]; then
187 eerror "EGIT_NOUNPACK has been removed. The eclass no longer calls default"
188 eerror "unpack function. If necessary, please declare proper src_unpack()."
189 die "EGIT_NOUNPACK has been removed."
190 fi
191 }
192
193 # @FUNCTION: _git-r3_set_gitdir
194 # @USAGE: <repo-uri>
195 # @INTERNAL
196 # @DESCRIPTION:
197 # Obtain the local repository path and set it as GIT_DIR. Creates
198 # a new repository if necessary.
199 #
200 # <repo-uri> may be used to compose the path. It should therefore be
201 # a canonical URI to the repository.
202 _git-r3_set_gitdir() {
203 debug-print-function ${FUNCNAME} "$@"
204
205 local repo_name=${1#*://*/}
206
207 # strip the trailing slash
208 repo_name=${repo_name%/}
209
210 # strip common prefixes to make paths more likely to match
211 # e.g. git://X/Y.git vs https://X/git/Y.git
212 # (but just one of the prefixes)
213 case "${repo_name}" in
214 # gnome.org... who else?
215 browse/*) repo_name=${repo_name#browse/};;
216 # cgit can proxy requests to git
217 cgit/*) repo_name=${repo_name#cgit/};;
218 # pretty common
219 git/*) repo_name=${repo_name#git/};;
220 # gentoo.org
221 gitroot/*) repo_name=${repo_name#gitroot/};;
222 # google code, sourceforge
223 p/*) repo_name=${repo_name#p/};;
224 # kernel.org
225 pub/scm/*) repo_name=${repo_name#pub/scm/};;
226 esac
227 # ensure a .git suffix, same reason
228 repo_name=${repo_name%.git}.git
229 # now replace all the slashes
230 repo_name=${repo_name//\//_}
231
232 local distdir=${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}}
233 : ${EGIT3_STORE_DIR:=${distdir}/git3-src}
234
235 GIT_DIR=${EGIT3_STORE_DIR}/${repo_name}
236
237 if [[ ! -d ${EGIT3_STORE_DIR} ]]; then
238 (
239 addwrite /
240 mkdir -m0755 -p "${EGIT3_STORE_DIR}" || die
241 ) || die "Unable to create ${EGIT3_STORE_DIR}"
242 fi
243
244 addwrite "${EGIT3_STORE_DIR}"
245 if [[ -e ${GIT_DIR}/shallow ]]; then
246 einfo "${GIT_DIR} was a shallow clone, recreating..."
247 rm -r "${GIT_DIR}" || die
248 fi
249 if [[ ! -d ${GIT_DIR} ]]; then
250 mkdir "${GIT_DIR}" || die
251 git init --bare || die
252 fi
253 }
254
255 # @FUNCTION: _git-r3_set_submodules
256 # @USAGE: <file-contents>
257 # @INTERNAL
258 # @DESCRIPTION:
259 # Parse .gitmodules contents passed as <file-contents>
260 # as in "$(cat .gitmodules)"). Composes a 'submodules' array that
261 # contains in order (name, URL, path) for each submodule.
262 _git-r3_set_submodules() {
263 debug-print-function ${FUNCNAME} "$@"
264
265 local data=${1}
266
267 # ( name url path ... )
268 submodules=()
269
270 local l
271 while read l; do
272 # submodule.<path>.path=<path>
273 # submodule.<path>.url=<url>
274 [[ ${l} == submodule.*.url=* ]] || continue
275
276 l=${l#submodule.}
277 local subname=${l%%.url=*}
278
279 # skip modules that have 'update = none', bug #487262.
280 local upd=$(echo "${data}" | git config -f /dev/fd/0 \
281 submodule."${subname}".update)
282 [[ ${upd} == none ]] && continue
283
284 submodules+=(
285 "${subname}"
286 "$(echo "${data}" | git config -f /dev/fd/0 \
287 submodule."${subname}".url || die)"
288 "$(echo "${data}" | git config -f /dev/fd/0 \
289 submodule."${subname}".path || die)"
290 )
291 done < <(echo "${data}" | git config -f /dev/fd/0 -l || die)
292 }
293
294 # @FUNCTION: _git-r3_is_local_repo
295 # @USAGE: <repo-uri>
296 # @INTERNAL
297 # @DESCRIPTION:
298 # Determine whether the given URI specifies a local (on-disk)
299 # repository.
300 _git-r3_is_local_repo() {
301 debug-print-function ${FUNCNAME} "$@"
302
303 local uri=${1}
304
305 [[ ${uri} == file://* || ${uri} == /* ]]
306 }
307
308 # @FUNCTION: _git-r3_update_head
309 # @USAGE: <remote-head-ref>
310 # @INTERNAL
311 # @DESCRIPTION:
312 # Given a ref to which remote HEAD was fetched, try to match
313 # a local branch and update symbolic HEAD appropriately.
314 _git-r3_update_head()
315 {
316 debug-print-function ${FUNCNAME} "$@"
317
318 local head_ref=${1}
319 local head_hash=$(git rev-parse --verify "${1}" || die)
320 local matching_ref
321
322 # TODO: some transports support peeking at symbolic remote refs
323 # find a way to use that rather than guessing
324
325 # (based on guess_remote_head() in git-1.9.0/remote.c)
326 local h ref
327 while read h ref; do
328 # look for matching head
329 if [[ ${h} == ${head_hash} ]]; then
330 # either take the first matching ref, or master if it is there
331 if [[ ! ${matching_ref} || ${ref} == refs/heads/master ]]; then
332 matching_ref=${ref}
333 fi
334 fi
335 done < <(git show-ref --heads || die)
336
337 if [[ ! ${matching_ref} ]]; then
338 die "Unable to find a matching branch for remote HEAD (${head_hash})"
339 fi
340
341 git symbolic-ref HEAD "${matching_ref}" || die
342 }
343
344 # @FUNCTION: git-r3_fetch
345 # @USAGE: [<repo-uri> [<remote-ref> [<local-id>]]]
346 # @DESCRIPTION:
347 # Fetch new commits to the local clone of repository.
348 #
349 # <repo-uri> specifies the repository URIs to fetch from, as a space-
350 # -separated list. The first URI will be used as repository group
351 # identifier and therefore must be used consistently. When not
352 # specified, defaults to ${EGIT_REPO_URI}.
353 #
354 # <remote-ref> specifies the remote ref or commit id to fetch.
355 # It is preferred to use 'refs/heads/<branch-name>' for branches
356 # and 'refs/tags/<tag-name>' for tags. Other options are 'HEAD'
357 # for upstream default branch and hexadecimal commit SHA1. Defaults
358 # to the first of EGIT_COMMIT, EGIT_BRANCH or literal 'HEAD' that
359 # is set to a non-null value.
360 #
361 # <local-id> specifies the local branch identifier that will be used to
362 # locally store the fetch result. It should be unique to multiple
363 # fetches within the repository that can be performed at the same time
364 # (including parallel merges). It defaults to ${CATEGORY}/${PN}/${SLOT%/*}.
365 # This default should be fine unless you are fetching multiple trees
366 # from the same repository in the same ebuild.
367 #
368 # The fetch operation will affect the EGIT_STORE only. It will not touch
369 # the working copy, nor export any environment variables.
370 # If the repository contains submodules, they will be fetched
371 # recursively.
372 git-r3_fetch() {
373 debug-print-function ${FUNCNAME} "$@"
374
375 [[ ${EVCS_OFFLINE} ]] && return
376
377 local repos
378 if [[ ${1} ]]; then
379 repos=( ${1} )
380 elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
381 repos=( "${EGIT_REPO_URI[@]}" )
382 else
383 repos=( ${EGIT_REPO_URI} )
384 fi
385
386 local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}}
387 local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
388 local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}}
389 local local_ref=refs/git-r3/${local_id}/__main__
390
391 [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
392
393 local -x GIT_DIR
394 _git-r3_set_gitdir "${repos[0]}"
395
396 # prepend the local mirror if applicable
397 if [[ ${EGIT_MIRROR_URI} ]]; then
398 repos=(
399 "${EGIT_MIRROR_URI%/}/${GIT_DIR##*/}"
400 "${repos[@]}"
401 )
402 fi
403
404 # try to fetch from the remote
405 local r success
406 for r in "${repos[@]}"; do
407 einfo "Fetching ${r} ..."
408
409 local fetch_command=(
410 git fetch --prune "${r}"
411 # mirror the remote branches as local branches
412 "refs/heads/*:refs/heads/*"
413 # pull tags explicitly in order to prune them properly
414 "refs/tags/*:refs/tags/*"
415 # notes in case something needs them
416 "refs/notes/*:refs/notes/*"
417 # and HEAD in case we need the default branch
418 # (we keep it in refs/git-r3 since otherwise --prune interferes)
419 HEAD:refs/git-r3/HEAD
420 )
421
422 set -- "${fetch_command[@]}"
423 echo "${@}" >&2
424 if "${@}"; then
425 # find remote HEAD and update our HEAD properly
426 _git-r3_update_head refs/git-r3/HEAD
427
428 # now let's see what the user wants from us
429 local full_remote_ref=$(
430 git rev-parse --verify --symbolic-full-name "${remote_ref}"
431 )
432
433 if [[ ${full_remote_ref} ]]; then
434 # when we are given a ref, create a symbolic ref
435 # so that we preserve the actual argument
436 set -- git symbolic-ref "${local_ref}" "${full_remote_ref}"
437 else
438 # otherwise, we were likely given a commit id
439 set -- git update-ref --no-deref "${local_ref}" "${remote_ref}"
440 fi
441
442 echo "${@}" >&2
443 if ! "${@}"; then
444 die "Referencing ${remote_ref} failed (wrong ref?)."
445 fi
446
447 success=1
448 break
449 fi
450 done
451 [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI"
452
453 # recursively fetch submodules
454 if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then
455 local submodules
456 _git-r3_set_submodules \
457 "$(git cat-file -p "${local_ref}":.gitmodules || die)"
458
459 while [[ ${submodules[@]} ]]; do
460 local subname=${submodules[0]}
461 local url=${submodules[1]}
462 local path=${submodules[2]}
463 local commit=$(git rev-parse "${local_ref}:${path}")
464
465 if [[ ! ${commit} ]]; then
466 die "Unable to get commit id for submodule ${subname}"
467 fi
468 if [[ ${url} == ./* || ${url} == ../* ]]; then
469 local subrepos=( "${repos[@]/%//${url}}" )
470 else
471 local subrepos=( "${url}" )
472 fi
473
474 git-r3_fetch "${subrepos[*]}" "${commit}" "${local_id}/${subname}"
475
476 submodules=( "${submodules[@]:3}" ) # shift
477 done
478 fi
479 }
480
481 # @FUNCTION: git-r3_checkout
482 # @USAGE: [<repo-uri> [<checkout-path> [<local-id>]]]
483 # @DESCRIPTION:
484 # Check the previously fetched tree to the working copy.
485 #
486 # <repo-uri> specifies the repository URIs, as a space-separated list.
487 # The first URI will be used as repository group identifier
488 # and therefore must be used consistently with git-r3_fetch.
489 # The remaining URIs are not used and therefore may be omitted.
490 # When not specified, defaults to ${EGIT_REPO_URI}.
491 #
492 # <checkout-path> specifies the path to place the checkout. It defaults
493 # to ${EGIT_CHECKOUT_DIR} if set, otherwise to ${WORKDIR}/${P}.
494 #
495 # <local-id> needs to specify the local identifier that was used
496 # for respective git-r3_fetch.
497 #
498 # The checkout operation will write to the working copy, and export
499 # the repository state into the environment. If the repository contains
500 # submodules, they will be checked out recursively.
501 git-r3_checkout() {
502 debug-print-function ${FUNCNAME} "$@"
503
504 local repos
505 if [[ ${1} ]]; then
506 repos=( ${1} )
507 elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
508 repos=( "${EGIT_REPO_URI[@]}" )
509 else
510 repos=( ${EGIT_REPO_URI} )
511 fi
512
513 local out_dir=${2:-${EGIT_CHECKOUT_DIR:-${WORKDIR}/${P}}}
514 local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}}
515
516 local -x GIT_DIR
517 _git-r3_set_gitdir "${repos[0]}"
518
519 einfo "Checking out ${repos[0]} to ${out_dir} ..."
520
521 if ! git cat-file -e refs/git-r3/"${local_id}"/__main__; then
522 if [[ ${EVCS_OFFLINE} ]]; then
523 die "No local clone of ${repos[0]}. Unable to work with EVCS_OFFLINE."
524 else
525 die "Logic error: no local clone of ${repos[0]}. git-r3_fetch not used?"
526 fi
527 fi
528 local remote_ref=$(
529 git symbolic-ref --quiet refs/git-r3/"${local_id}"/__main__
530 )
531 local new_commit_id=$(
532 git rev-parse --verify refs/git-r3/"${local_id}"/__main__
533 )
534
535 git-r3_sub_checkout() {
536 local orig_repo=${GIT_DIR}
537 local -x GIT_DIR=${out_dir}/.git
538 local -x GIT_WORK_TREE=${out_dir}
539
540 mkdir -p "${out_dir}" || die
541
542 # use git init+fetch instead of clone since the latter doesn't like
543 # non-empty directories.
544
545 git init --quiet || die
546 # setup 'alternates' to avoid copying objects
547 echo "${orig_repo}/objects" > "${GIT_DIR}"/objects/info/alternates || die
548 # now copy the refs
549 # [htn]* safely catches heads, tags, notes without complaining
550 # on non-existing ones, and omits internal 'git-r3' ref
551 cp -R "${orig_repo}"/refs/[htn]* "${GIT_DIR}"/refs/ || die
552
553 # (no need to copy HEAD, we will set it via checkout)
554
555 set -- git checkout --quiet
556 if [[ ${remote_ref} ]]; then
557 set -- "${@}" "${remote_ref#refs/heads/}"
558 else
559 set -- "${@}" "${new_commit_id}"
560 fi
561 echo "${@}" >&2
562 "${@}" || die "git checkout ${remote_ref:-${new_commit_id}} failed"
563 }
564 git-r3_sub_checkout
565
566 local old_commit_id=$(
567 git rev-parse --quiet --verify refs/git-r3/"${local_id}"/__old__
568 )
569 if [[ ! ${old_commit_id} ]]; then
570 echo "GIT NEW branch -->"
571 echo " repository: ${repos[0]}"
572 echo " at the commit: ${new_commit_id}"
573 else
574 # diff against previous revision
575 echo "GIT update -->"
576 echo " repository: ${repos[0]}"
577 # write out message based on the revisions
578 if [[ "${old_commit_id}" != "${new_commit_id}" ]]; then
579 echo " updating from commit: ${old_commit_id}"
580 echo " to commit: ${new_commit_id}"
581
582 git --no-pager diff --stat \
583 ${old_commit_id}..${new_commit_id}
584 else
585 echo " at the commit: ${new_commit_id}"
586 fi
587 fi
588 git update-ref --no-deref refs/git-r3/"${local_id}"/{__old__,__main__} || die
589
590 # recursively checkout submodules
591 if [[ -f ${out_dir}/.gitmodules ]]; then
592 local submodules
593 _git-r3_set_submodules \
594 "$(<"${out_dir}"/.gitmodules)"
595
596 while [[ ${submodules[@]} ]]; do
597 local subname=${submodules[0]}
598 local url=${submodules[1]}
599 local path=${submodules[2]}
600
601 if [[ ${url} == ./* || ${url} == ../* ]]; then
602 url=${repos[0]%%/}/${url}
603 fi
604
605 git-r3_checkout "${url}" "${out_dir}/${path}" \
606 "${local_id}/${subname}"
607
608 submodules=( "${submodules[@]:3}" ) # shift
609 done
610 fi
611
612 # keep this *after* submodules
613 export EGIT_DIR=${GIT_DIR}
614 export EGIT_VERSION=${new_commit_id}
615 }
616
617 # @FUNCTION: git-r3_peek_remote_ref
618 # @USAGE: [<repo-uri> [<remote-ref>]]
619 # @DESCRIPTION:
620 # Peek the reference in the remote repository and print the matching
621 # (newest) commit SHA1.
622 #
623 # <repo-uri> specifies the repository URIs to fetch from, as a space-
624 # -separated list. When not specified, defaults to ${EGIT_REPO_URI}.
625 #
626 # <remote-ref> specifies the remote ref to peek. It is preferred to use
627 # 'refs/heads/<branch-name>' for branches and 'refs/tags/<tag-name>'
628 # for tags. Alternatively, 'HEAD' may be used for upstream default
629 # branch. Defaults to the first of EGIT_COMMIT, EGIT_BRANCH or literal
630 # 'HEAD' that is set to a non-null value.
631 #
632 # The operation will be done purely on the remote, without using local
633 # storage. If commit SHA1 is provided as <remote-ref>, the function will
634 # fail due to limitations of git protocol.
635 #
636 # On success, the function returns 0 and writes hexadecimal commit SHA1
637 # to stdout. On failure, the function returns 1.
638 git-r3_peek_remote_ref() {
639 debug-print-function ${FUNCNAME} "$@"
640
641 local repos
642 if [[ ${1} ]]; then
643 repos=( ${1} )
644 elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
645 repos=( "${EGIT_REPO_URI[@]}" )
646 else
647 repos=( ${EGIT_REPO_URI} )
648 fi
649
650 local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}}
651 local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
652
653 [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
654
655 local r success
656 for r in "${repos[@]}"; do
657 einfo "Peeking ${remote_ref} on ${r} ..." >&2
658
659 local is_branch lookup_ref
660 if [[ ${remote_ref} == refs/heads/* || ${remote_ref} == HEAD ]]
661 then
662 is_branch=1
663 lookup_ref=${remote_ref}
664 else
665 # ls-remote by commit is going to fail anyway,
666 # so we may as well pass refs/tags/ABCDEF...
667 lookup_ref=refs/tags/${remote_ref}
668 fi
669
670 # split on whitespace
671 local ref=(
672 $(git ls-remote "${r}" "${lookup_ref}")
673 )
674
675 if [[ ${ref[0]} ]]; then
676 echo "${ref[0]}"
677 return 0
678 fi
679 done
680
681 return 1
682 }
683
684 git-r3_src_fetch() {
685 debug-print-function ${FUNCNAME} "$@"
686
687 if [[ ! ${EGIT3_STORE_DIR} && ${EGIT_STORE_DIR} ]]; then
688 ewarn "You have set EGIT_STORE_DIR but not EGIT3_STORE_DIR. Please consider"
689 ewarn "setting EGIT3_STORE_DIR for git-r3.eclass. It is recommended to use"
690 ewarn "a different directory than EGIT_STORE_DIR to ease removing old clones"
691 ewarn "when git-2 eclass becomes deprecated."
692 fi
693
694 _git-r3_env_setup
695 git-r3_fetch
696 }
697
698 git-r3_src_unpack() {
699 debug-print-function ${FUNCNAME} "$@"
700
701 _git-r3_env_setup
702 git-r3_src_fetch
703 git-r3_checkout
704 }
705
706 # https://bugs.gentoo.org/show_bug.cgi?id=482666
707 git-r3_pkg_outofdate() {
708 debug-print-function ${FUNCNAME} "$@"
709
710 local new_commit_id=$(git-r3_peek_remote_ref)
711 ewarn "old: ${EGIT_VERSION}"
712 ewarn "new: ${new_commit_id}"
713 [[ ${new_commit_id} && ${old_commit_id} ]] || return 2
714
715 [[ ${EGIT_VERSION} != ${new_commit_id} ]]
716 }
717
718 _GIT_R3=1
719 fi

  ViewVC Help
Powered by ViewVC 1.1.20