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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations) (download)
Thu Sep 19 09:42:32 2013 UTC (13 months ago) by mgorny
Branch: MAIN
Changes since 1.6: +4 -1 lines
Strip trailing slashes from repo URI when determining local copy directory.

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

  ViewVC Help
Powered by ViewVC 1.1.20