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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.5 - (hide annotations) (download)
Fri Sep 13 15:08:37 2013 UTC (15 months, 2 weeks ago) by mgorny
Branch: MAIN
Changes since 1.4: +5 -2 lines
Fail early on unreachable URLs. If ls-remote fails due to server being unreachable, there is no point in attempting to fetch.

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

  ViewVC Help
Powered by ViewVC 1.1.20