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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (show annotations) (download)
Wed Sep 25 11:19:09 2013 UTC (9 months, 2 weeks ago) by mgorny
Branch: MAIN
Changes since 1.8: +22 -8 lines
Support EGIT_REPO_URI being an array. This is needed for tests.

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

  ViewVC Help
Powered by ViewVC 1.1.20