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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.30 - (hide annotations) (download)
Sun Mar 2 11:46:42 2014 UTC (17 months ago) by mgorny
Branch: MAIN
Changes since 1.29: +23 -1 lines
Support using a local git mirror.

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

  ViewVC Help
Powered by ViewVC 1.1.20