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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (hide annotations) (download)
Thu Sep 19 09:37:14 2013 UTC (9 months, 3 weeks ago) by mgorny
Branch: MAIN
Changes since 1.5: +5 -3 lines
Do not even create shallow repository when EGIT_NONSHALLOW is set. Otherwise, the eclass tries to unshallow it and that breaks broken git servers like Google Code.

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

  ViewVC Help
Powered by ViewVC 1.1.20