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

Contents of /eclass/git-r3.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.31 - (hide annotations) (download)
Sun Mar 2 11:47:10 2014 UTC (10 months, 3 weeks ago) by mgorny
Branch: MAIN
Changes since 1.30: +22 -1 lines
Introduce EGIT_CLONE_TYPE for future use.

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

  ViewVC Help
Powered by ViewVC 1.1.20