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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20