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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (show annotations) (download)
Fri Sep 27 16:22:28 2013 UTC (13 months, 4 weeks ago) by mgorny
Branch: MAIN
Changes since 1.11: +3 -1 lines
Always fetch all branches when doing non-shallow fetch.

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.11 2013/09/26 21:04: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. 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 # fetch all branches
449 ref_param+=( "refs/heads/*:refs/remotes/origin/*" )
450 else
451 # 'git show-ref --heads' returns 1 when there are no branches
452 if ! git show-ref --heads -q; then
453 ref_param+=( --depth 1 )
454 else
455 fetch_command=( _git-r3_smart_fetch )
456 fi
457 fi
458
459 # now, another important thing. we may only fetch a remote
460 # branch directly to a local branch. Otherwise, we need to fetch
461 # the commit and re-create the branch on top of it.
462
463 if [[ ${ref[0]} ]]; then
464 if [[ ${is_branch} ]]; then
465 ref_param+=( -f "${remote_ref}:${local_id}/__main__" )
466 else
467 ref_param+=( "refs/tags/${remote_ref}" )
468 fi
469 fi
470
471 # if ${remote_ref} is branch or tag, ${ref[@]} will contain
472 # the respective commit id. otherwise, it will be an empty
473 # array, so the following won't evaluate to a parameter.
474 set -- "${fetch_command[@]}" --no-tags "${r}" "${ref_param[@]}"
475 echo "${@}" >&2
476 if "${@}"; then
477 if [[ ! ${is_branch} ]]; then
478 set -- git branch -f "${local_id}/__main__" \
479 "${ref[0]:-${remote_ref}}"
480 echo "${@}" >&2
481 if ! "${@}"; then
482 die "Creating branch for ${remote_ref} failed (wrong ref?)."
483 fi
484 fi
485
486 success=1
487 break
488 fi
489 done
490 [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI"
491
492 # recursively fetch submodules
493 if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then
494 local submodules
495 _git-r3_set_submodules \
496 "$(git cat-file -p "${local_ref}":.gitmodules || die)"
497
498 while [[ ${submodules[@]} ]]; do
499 local subname=${submodules[0]}
500 local url=${submodules[1]}
501 local path=${submodules[2]}
502 local commit=$(git rev-parse "${local_ref}:${path}")
503
504 if [[ ! ${commit} ]]; then
505 die "Unable to get commit id for submodule ${subname}"
506 fi
507
508 git-r3_fetch "${url}" "${commit}" "${local_id}/${subname}"
509
510 submodules=( "${submodules[@]:3}" ) # shift
511 done
512 fi
513 }
514
515 # @FUNCTION: git-r3_checkout
516 # @USAGE: [<repo-uri> [<checkout-path> [<local-id>]]]
517 # @DESCRIPTION:
518 # Check the previously fetched tree to the working copy.
519 #
520 # <repo-uri> specifies the repository URIs, as a space-separated list.
521 # The first URI will be used as repository group identifier
522 # and therefore must be used consistently with git-r3_fetch.
523 # The remaining URIs are not used and therefore may be omitted.
524 # When not specified, defaults to ${EGIT_REPO_URI}.
525 #
526 # <checkout-path> specifies the path to place the checkout. It defaults
527 # to ${EGIT_CHECKOUT_DIR} if set, otherwise to ${WORKDIR}/${P}.
528 #
529 # <local-id> needs to specify the local identifier that was used
530 # for respective git-r3_fetch.
531 #
532 # The checkout operation will write to the working copy, and export
533 # the repository state into the environment. If the repository contains
534 # submodules, they will be checked out recursively.
535 git-r3_checkout() {
536 debug-print-function ${FUNCNAME} "$@"
537
538 local repos
539 if [[ ${1} ]]; then
540 repos=( ${1} )
541 elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
542 repos=( "${EGIT_REPO_URI[@]}" )
543 else
544 repos=( ${EGIT_REPO_URI} )
545 fi
546
547 local out_dir=${2:-${EGIT_CHECKOUT_DIR:-${WORKDIR}/${P}}}
548 local local_id=${3:-${CATEGORY}/${PN}/${SLOT}}
549
550 local -x GIT_DIR GIT_WORK_TREE
551 _git-r3_set_gitdir "${repos[0]}"
552 GIT_WORK_TREE=${out_dir}
553 mkdir -p "${GIT_WORK_TREE}"
554
555 einfo "Checking out ${repos[0]} to ${out_dir} ..."
556
557 if ! git cat-file -e refs/heads/"${local_id}"/__main__
558 then
559 if [[ ${EVCS_OFFLINE} ]]; then
560 die "No local clone of ${repos[0]}. Unable to work with EVCS_OFFLINE."
561 else
562 die "Logic error: no local clone of ${repos[0]}. git-r3_fetch not used?"
563 fi
564 fi
565
566 set -- git checkout -f "${local_id}"/__main__ .
567 echo "${@}" >&2
568 "${@}" || die "git checkout ${local_id}/__main__ failed"
569
570 # diff against previous revision (if any)
571 local new_commit_id=$(git rev-parse --verify "${local_id}"/__main__)
572 local old_commit_id=$(
573 git rev-parse --verify "${local_id}"/__old__ 2>/dev/null
574 )
575
576 if [[ ! ${old_commit_id} ]]; then
577 echo "GIT NEW branch -->"
578 echo " repository: ${repos[0]}"
579 echo " at the commit: ${new_commit_id}"
580 else
581 echo "GIT update -->"
582 echo " repository: ${repos[0]}"
583 # write out message based on the revisions
584 if [[ "${old_commit_id}" != "${new_commit_id}" ]]; then
585 echo " updating from commit: ${old_commit_id}"
586 echo " to commit: ${new_commit_id}"
587
588 git --no-pager diff --stat \
589 ${old_commit_id}..${new_commit_id}
590 else
591 echo " at the commit: ${new_commit_id}"
592 fi
593 fi
594 git branch -f "${local_id}"/{__old__,__main__} || die
595
596 # recursively checkout submodules
597 if [[ -f ${GIT_WORK_TREE}/.gitmodules ]]; then
598 local submodules
599 _git-r3_set_submodules \
600 "$(<"${GIT_WORK_TREE}"/.gitmodules)"
601
602 while [[ ${submodules[@]} ]]; do
603 local subname=${submodules[0]}
604 local url=${submodules[1]}
605 local path=${submodules[2]}
606
607 git-r3_checkout "${url}" "${GIT_WORK_TREE}/${path}" \
608 "${local_id}/${subname}"
609
610 submodules=( "${submodules[@]:3}" ) # shift
611 done
612 fi
613
614 # keep this *after* submodules
615 export EGIT_DIR=${GIT_DIR}
616 export EGIT_VERSION=${new_commit_id}
617 }
618
619 # @FUNCTION: git-r3_peek_remote_ref
620 # @USAGE: [<repo-uri> [<remote-ref>]]
621 # @DESCRIPTION:
622 # Peek the reference in the remote repository and print the matching
623 # (newest) commit SHA1.
624 #
625 # <repo-uri> specifies the repository URIs to fetch from, as a space-
626 # -separated list. When not specified, defaults to ${EGIT_REPO_URI}.
627 #
628 # <remote-ref> specifies the remote ref to peek. It is preferred to use
629 # 'refs/heads/<branch-name>' for branches and 'refs/tags/<tag-name>'
630 # for tags. Alternatively, 'HEAD' may be used for upstream default
631 # branch. Defaults to the first of EGIT_COMMIT, EGIT_BRANCH or literal
632 # 'HEAD' that is set to a non-null value.
633 #
634 # The operation will be done purely on the remote, without using local
635 # storage. If commit SHA1 is provided as <remote-ref>, the function will
636 # fail due to limitations of git protocol.
637 #
638 # On success, the function returns 0 and writes hexadecimal commit SHA1
639 # to stdout. On failure, the function returns 1.
640 git-r3_peek_remote_ref() {
641 debug-print-function ${FUNCNAME} "$@"
642
643 local repos
644 if [[ ${1} ]]; then
645 repos=( ${1} )
646 elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
647 repos=( "${EGIT_REPO_URI[@]}" )
648 else
649 repos=( ${EGIT_REPO_URI} )
650 fi
651
652 local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}}
653 local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
654
655 [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
656
657 local r success
658 for r in "${repos[@]}"; do
659 einfo "Peeking ${remote_ref} on ${r} ..." >&2
660
661 local is_branch lookup_ref
662 if [[ ${remote_ref} == refs/heads/* || ${remote_ref} == HEAD ]]
663 then
664 is_branch=1
665 lookup_ref=${remote_ref}
666 else
667 # ls-remote by commit is going to fail anyway,
668 # so we may as well pass refs/tags/ABCDEF...
669 lookup_ref=refs/tags/${remote_ref}
670 fi
671
672 # split on whitespace
673 local ref=(
674 $(git ls-remote "${r}" "${lookup_ref}")
675 )
676
677 if [[ ${ref[0]} ]]; then
678 echo "${ref[0]}"
679 return 0
680 fi
681 done
682
683 return 1
684 }
685
686 git-r3_src_fetch() {
687 debug-print-function ${FUNCNAME} "$@"
688
689 [[ ${EVCS_OFFLINE} ]] && return
690
691 if [[ ! ${EGIT3_STORE_DIR} && ${EGIT_STORE_DIR} ]]; then
692 ewarn "You have set EGIT_STORE_DIR but not EGIT3_STORE_DIR. Please consider"
693 ewarn "setting EGIT3_STORE_DIR for git-r3.eclass. It is recommended to use"
694 ewarn "a different directory than EGIT_STORE_DIR to ease removing old clones"
695 ewarn "when git-2 eclass becomes deprecated."
696 fi
697
698 _git-r3_env_setup
699 git-r3_fetch
700 }
701
702 git-r3_src_unpack() {
703 debug-print-function ${FUNCNAME} "$@"
704
705 _git-r3_env_setup
706 git-r3_src_fetch
707 git-r3_checkout
708 }
709
710 # https://bugs.gentoo.org/show_bug.cgi?id=482666
711 git-r3_pkg_outofdate() {
712 debug-print-function ${FUNCNAME} "$@"
713
714 local new_commit_id=$(git-r3_peek_remote_ref)
715 ewarn "old: ${EGIT_VERSION}"
716 ewarn "new: ${new_commit_id}"
717 [[ ${new_commit_id} && ${old_commit_id} ]] || return 2
718
719 [[ ${EGIT_VERSION} != ${new_commit_id} ]]
720 }
721
722 _GIT_R3=1
723 fi

  ViewVC Help
Powered by ViewVC 1.1.20