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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (show annotations) (download)
Thu Sep 26 21:04:42 2013 UTC (11 months ago) by mgorny
Branch: MAIN
Changes since 1.10: +22 -10 lines
Fix parsing EGIT_REPO_URI. Bug #486080.

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

  ViewVC Help
Powered by ViewVC 1.1.20