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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.13 - (hide annotations) (download)
Sat Oct 5 16:48:25 2013 UTC (11 months, 2 weeks ago) by mgorny
Branch: MAIN
Changes since 1.12: +3 -1 lines
Add missing git DEPEND wrt bug #487026.

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

  ViewVC Help
Powered by ViewVC 1.1.20