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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.8 - (hide annotations) (download)
Wed Sep 25 10:49:11 2013 UTC (12 months, 3 weeks ago) by mgorny
Branch: MAIN
Changes since 1.7: +3 -1 lines
Update git URI stripping for gnome.org.

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

  ViewVC Help
Powered by ViewVC 1.1.20