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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations) (download)
Thu Sep 26 21:04:42 2013 UTC (12 months ago) by mgorny
Branch: MAIN
Changes since 1.10: +22 -10 lines
Fix parsing EGIT_REPO_URI. Bug #486080.

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

  ViewVC Help
Powered by ViewVC 1.1.20