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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.10 - (show annotations) (download)
Thu Sep 26 12:38:38 2013 UTC (11 months ago) by mgorny
Branch: MAIN
Changes since 1.9: +5 -3 lines
Update doc on EGIT_NONSHALLOW.

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

  ViewVC Help
Powered by ViewVC 1.1.20