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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.9 - (hide annotations) (download)
Wed Sep 25 11:19:09 2013 UTC (10 months ago) by mgorny
Branch: MAIN
Changes since 1.8: +22 -8 lines
Support EGIT_REPO_URI being an array. This is needed for tests.

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

  ViewVC Help
Powered by ViewVC 1.1.20