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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.12 - (hide annotations) (download)
Fri Sep 27 16:22:28 2013 UTC (12 months, 3 weeks ago) by mgorny
Branch: MAIN
Changes since 1.11: +3 -1 lines
Always fetch all branches when doing non-shallow 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.12 # $Header: /var/cvsroot/gentoo-x86/eclass/git-r3.eclass,v 1.11 2013/09/26 21:04:42 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.12 # fetch all branches
449     ref_param+=( "refs/heads/*:refs/remotes/origin/*" )
450 mgorny 1.1 else
451 mgorny 1.2 # 'git show-ref --heads' returns 1 when there are no branches
452     if ! git show-ref --heads -q; then
453     ref_param+=( --depth 1 )
454 mgorny 1.3 else
455     fetch_command=( _git-r3_smart_fetch )
456 mgorny 1.2 fi
457 mgorny 1.1 fi
458    
459 mgorny 1.2 # now, another important thing. we may only fetch a remote
460     # branch directly to a local branch. Otherwise, we need to fetch
461     # the commit and re-create the branch on top of it.
462    
463 mgorny 1.1 if [[ ${ref[0]} ]]; then
464     if [[ ${is_branch} ]]; then
465     ref_param+=( -f "${remote_ref}:${local_id}/__main__" )
466     else
467     ref_param+=( "refs/tags/${remote_ref}" )
468     fi
469     fi
470    
471     # if ${remote_ref} is branch or tag, ${ref[@]} will contain
472     # the respective commit id. otherwise, it will be an empty
473     # array, so the following won't evaluate to a parameter.
474 mgorny 1.3 set -- "${fetch_command[@]}" --no-tags "${r}" "${ref_param[@]}"
475 mgorny 1.1 echo "${@}" >&2
476     if "${@}"; then
477     if [[ ! ${is_branch} ]]; then
478     set -- git branch -f "${local_id}/__main__" \
479     "${ref[0]:-${remote_ref}}"
480     echo "${@}" >&2
481     if ! "${@}"; then
482     die "Creating branch for ${remote_ref} failed (wrong ref?)."
483     fi
484     fi
485    
486     success=1
487     break
488     fi
489     done
490     [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI"
491    
492     # recursively fetch submodules
493     if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then
494     local submodules
495     _git-r3_set_submodules \
496     "$(git cat-file -p "${local_ref}":.gitmodules || die)"
497    
498     while [[ ${submodules[@]} ]]; do
499     local subname=${submodules[0]}
500     local url=${submodules[1]}
501     local path=${submodules[2]}
502     local commit=$(git rev-parse "${local_ref}:${path}")
503    
504     if [[ ! ${commit} ]]; then
505     die "Unable to get commit id for submodule ${subname}"
506     fi
507    
508     git-r3_fetch "${url}" "${commit}" "${local_id}/${subname}"
509    
510     submodules=( "${submodules[@]:3}" ) # shift
511     done
512     fi
513     }
514    
515     # @FUNCTION: git-r3_checkout
516     # @USAGE: [<repo-uri> [<checkout-path> [<local-id>]]]
517     # @DESCRIPTION:
518     # Check the previously fetched tree to the working copy.
519     #
520     # <repo-uri> specifies the repository URIs, as a space-separated list.
521     # The first URI will be used as repository group identifier
522     # and therefore must be used consistently with git-r3_fetch.
523     # The remaining URIs are not used and therefore may be omitted.
524     # When not specified, defaults to ${EGIT_REPO_URI}.
525     #
526     # <checkout-path> specifies the path to place the checkout. It defaults
527     # to ${EGIT_CHECKOUT_DIR} if set, otherwise to ${WORKDIR}/${P}.
528     #
529     # <local-id> needs to specify the local identifier that was used
530     # for respective git-r3_fetch.
531     #
532     # The checkout operation will write to the working copy, and export
533     # the repository state into the environment. If the repository contains
534     # submodules, they will be checked out recursively.
535     git-r3_checkout() {
536     debug-print-function ${FUNCNAME} "$@"
537    
538 mgorny 1.11 local repos
539     if [[ ${1} ]]; then
540     repos=( ${1} )
541     elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
542     repos=( "${EGIT_REPO_URI[@]}" )
543     else
544     repos=( ${EGIT_REPO_URI} )
545 mgorny 1.9 fi
546    
547 mgorny 1.1 local out_dir=${2:-${EGIT_CHECKOUT_DIR:-${WORKDIR}/${P}}}
548     local local_id=${3:-${CATEGORY}/${PN}/${SLOT}}
549    
550     local -x GIT_DIR GIT_WORK_TREE
551 mgorny 1.9 _git-r3_set_gitdir "${repos[0]}"
552 mgorny 1.1 GIT_WORK_TREE=${out_dir}
553     mkdir -p "${GIT_WORK_TREE}"
554    
555     einfo "Checking out ${repos[0]} to ${out_dir} ..."
556    
557     if ! git cat-file -e refs/heads/"${local_id}"/__main__
558     then
559     if [[ ${EVCS_OFFLINE} ]]; then
560     die "No local clone of ${repos[0]}. Unable to work with EVCS_OFFLINE."
561     else
562     die "Logic error: no local clone of ${repos[0]}. git-r3_fetch not used?"
563     fi
564     fi
565    
566     set -- git checkout -f "${local_id}"/__main__ .
567     echo "${@}" >&2
568     "${@}" || die "git checkout ${local_id}/__main__ failed"
569    
570     # diff against previous revision (if any)
571     local new_commit_id=$(git rev-parse --verify "${local_id}"/__main__)
572     local old_commit_id=$(
573     git rev-parse --verify "${local_id}"/__old__ 2>/dev/null
574     )
575    
576     if [[ ! ${old_commit_id} ]]; then
577     echo "GIT NEW branch -->"
578     echo " repository: ${repos[0]}"
579     echo " at the commit: ${new_commit_id}"
580     else
581     echo "GIT update -->"
582     echo " repository: ${repos[0]}"
583     # write out message based on the revisions
584     if [[ "${old_commit_id}" != "${new_commit_id}" ]]; then
585     echo " updating from commit: ${old_commit_id}"
586     echo " to commit: ${new_commit_id}"
587    
588     git --no-pager diff --stat \
589     ${old_commit_id}..${new_commit_id}
590     else
591     echo " at the commit: ${new_commit_id}"
592     fi
593     fi
594     git branch -f "${local_id}"/{__old__,__main__} || die
595    
596     # recursively checkout submodules
597     if [[ -f ${GIT_WORK_TREE}/.gitmodules ]]; then
598     local submodules
599     _git-r3_set_submodules \
600     "$(<"${GIT_WORK_TREE}"/.gitmodules)"
601    
602     while [[ ${submodules[@]} ]]; do
603     local subname=${submodules[0]}
604     local url=${submodules[1]}
605     local path=${submodules[2]}
606    
607     git-r3_checkout "${url}" "${GIT_WORK_TREE}/${path}" \
608     "${local_id}/${subname}"
609    
610     submodules=( "${submodules[@]:3}" ) # shift
611     done
612     fi
613    
614     # keep this *after* submodules
615     export EGIT_DIR=${GIT_DIR}
616     export EGIT_VERSION=${new_commit_id}
617     }
618    
619     # @FUNCTION: git-r3_peek_remote_ref
620     # @USAGE: [<repo-uri> [<remote-ref>]]
621     # @DESCRIPTION:
622     # Peek the reference in the remote repository and print the matching
623     # (newest) commit SHA1.
624     #
625     # <repo-uri> specifies the repository URIs to fetch from, as a space-
626     # -separated list. When not specified, defaults to ${EGIT_REPO_URI}.
627     #
628     # <remote-ref> specifies the remote ref to peek. It is preferred to use
629     # 'refs/heads/<branch-name>' for branches and 'refs/tags/<tag-name>'
630     # for tags. Alternatively, 'HEAD' may be used for upstream default
631     # branch. Defaults to the first of EGIT_COMMIT, EGIT_BRANCH or literal
632     # 'HEAD' that is set to a non-null value.
633     #
634     # The operation will be done purely on the remote, without using local
635     # storage. If commit SHA1 is provided as <remote-ref>, the function will
636     # fail due to limitations of git protocol.
637     #
638     # On success, the function returns 0 and writes hexadecimal commit SHA1
639     # to stdout. On failure, the function returns 1.
640     git-r3_peek_remote_ref() {
641     debug-print-function ${FUNCNAME} "$@"
642    
643 mgorny 1.11 local repos
644     if [[ ${1} ]]; then
645     repos=( ${1} )
646     elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then
647     repos=( "${EGIT_REPO_URI[@]}" )
648     else
649     repos=( ${EGIT_REPO_URI} )
650 mgorny 1.9 fi
651    
652 mgorny 1.1 local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}}
653     local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}}
654    
655     [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset"
656    
657     local r success
658 mgorny 1.9 for r in "${repos[@]}"; do
659 mgorny 1.1 einfo "Peeking ${remote_ref} on ${r} ..." >&2
660    
661     local is_branch lookup_ref
662     if [[ ${remote_ref} == refs/heads/* || ${remote_ref} == HEAD ]]
663     then
664     is_branch=1
665     lookup_ref=${remote_ref}
666     else
667     # ls-remote by commit is going to fail anyway,
668     # so we may as well pass refs/tags/ABCDEF...
669     lookup_ref=refs/tags/${remote_ref}
670     fi
671    
672     # split on whitespace
673     local ref=(
674     $(git ls-remote "${r}" "${lookup_ref}")
675     )
676    
677     if [[ ${ref[0]} ]]; then
678     echo "${ref[0]}"
679     return 0
680     fi
681     done
682    
683     return 1
684     }
685    
686     git-r3_src_fetch() {
687     debug-print-function ${FUNCNAME} "$@"
688    
689     [[ ${EVCS_OFFLINE} ]] && return
690    
691     if [[ ! ${EGIT3_STORE_DIR} && ${EGIT_STORE_DIR} ]]; then
692     ewarn "You have set EGIT_STORE_DIR but not EGIT3_STORE_DIR. Please consider"
693     ewarn "setting EGIT3_STORE_DIR for git-r3.eclass. It is recommended to use"
694     ewarn "a different directory than EGIT_STORE_DIR to ease removing old clones"
695     ewarn "when git-2 eclass becomes deprecated."
696     fi
697    
698     _git-r3_env_setup
699     git-r3_fetch
700     }
701    
702     git-r3_src_unpack() {
703     debug-print-function ${FUNCNAME} "$@"
704    
705     _git-r3_env_setup
706     git-r3_src_fetch
707     git-r3_checkout
708     }
709    
710     # https://bugs.gentoo.org/show_bug.cgi?id=482666
711     git-r3_pkg_outofdate() {
712     debug-print-function ${FUNCNAME} "$@"
713    
714     local new_commit_id=$(git-r3_peek_remote_ref)
715     ewarn "old: ${EGIT_VERSION}"
716     ewarn "new: ${new_commit_id}"
717     [[ ${new_commit_id} && ${old_commit_id} ]] || return 2
718    
719     [[ ${EGIT_VERSION} != ${new_commit_id} ]]
720     }
721    
722     _GIT_R3=1
723     fi

  ViewVC Help
Powered by ViewVC 1.1.20