From 0e47c51575652753615dc508fcd81dc710c6af33 Mon Sep 17 00:00:00 2001 From: "psyc://loupsycedyglgamf.onion/~lynX" Date: Wed, 4 Apr 1984 00:44:06 +0000 Subject: recreated Tor patch for git-r3.eclass and applied --- eclass/git-r3.eclass | 35 +- eclass/git-r3.tor.eclass | 1016 ---------------------------------------------- git-r3.eclass.patch | 99 +++++ 3 files changed, 128 insertions(+), 1022 deletions(-) delete mode 100644 eclass/git-r3.tor.eclass create mode 100644 git-r3.eclass.patch diff --git a/eclass/git-r3.eclass b/eclass/git-r3.eclass index a1ad0d2..5e4f57e 100644 --- a/eclass/git-r3.eclass +++ b/eclass/git-r3.eclass @@ -9,6 +9,15 @@ # @DESCRIPTION: # Third generation eclass for easing maintenance of live ebuilds using # git as remote repository. +# +# Patched by symlynX to allow for gits via Tor. Why Tor? Because +# unlike HTTPS it provides end-to-end authenticity which is not +# susceptible to man-in-the-middle attacks, so all gits should +# migrate to Tor, cjdns or gnunet-vpn. But the latter two do +# not need custom changes to this file to do their job. +# +# @FIXME: Should we automatically define EGIT_SOCKS="torsocks" +# when we see that /etc/tor/torsocks.conf exists? case "${EAPI:-0}" in 0|1|2|3) @@ -655,7 +664,18 @@ git-r3_fetch() { if [[ ! ${EVCS_OFFLINE} ]]; then einfo "Fetching \e[1m${r}\e[22m ..." - local fetch_command=( git fetch "${r}" ) + if [[ ${r} == https?://* ]]; then + # if we're not using git protocol, web proxy takes care of things + EGIT_SOCKS = "" + elif [[ ! ${EGIT_SOCKS} ]] && [[ ${r} == git://*.onion/* ]]; then + if ROOT=/ has_version 'net-proxy/torsocks'; then + EGIT_SOCKS="torsocks" + else + die "Properly configured net-proxy/torsocks required to fetch git from onion." + fi + fi + + local fetch_command=( ${EGIT_SOCKS} git fetch "${r}" ) local clone_type=${EGIT_CLONE_TYPE} if [[ ${clone_type} == mirror ]]; then @@ -683,7 +703,7 @@ git-r3_fetch() { else # tag or commit id... # let ls-remote figure it out - local tagref=$(git ls-remote "${r}" "refs/tags/${remote_ref}") + local tagref=$(${EGIT_SOCKS} git ls-remote "${r}" "refs/tags/${remote_ref}") # if it was a tag, ls-remote obtained a hash if [[ ${tagref} ]]; then @@ -770,7 +790,7 @@ git-r3_fetch() { fi else local full_remote_ref=$( - git rev-parse --verify --symbolic-full-name "${remote_ref}" + ${EGIT_SOCKS} git rev-parse --verify --symbolic-full-name "${remote_ref}" ) if [[ ${full_remote_ref} ]]; then @@ -805,6 +825,9 @@ git-r3_fetch() { fi [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI" + # consistency check, in case we got man-in-the-middle't --lynX + git fsck + # submodules can reference commits in any branch # always use the 'mirror' mode to accomodate that, bug #503332 local EGIT_CLONE_TYPE=mirror @@ -813,7 +836,7 @@ git-r3_fetch() { if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then local submodules _git-r3_set_submodules \ - "$(git cat-file -p "${local_ref}":.gitmodules || die)" + "$(${EGIT_SOCKS} git cat-file -p "${local_ref}":.gitmodules || die)" while [[ ${submodules[@]} ]]; do local subname=${submodules[0]} @@ -825,7 +848,7 @@ git-r3_fetch() { # note: git cat-file does not work for submodules if [[ $(git ls-tree -d "${local_ref}" "${path}") ]] then - local commit=$(git rev-parse "${local_ref}:${path}" || die) + local commit=$(${EGIT_SOCKS} git rev-parse "${local_ref}:${path}" || die) if [[ ! ${commit} ]]; then die "Unable to get commit id for submodule ${subname}" @@ -1051,7 +1074,7 @@ git-r3_peek_remote_ref() { # split on whitespace local ref=( - $(git ls-remote "${r}" "${lookup_ref}") + $(${EGIT_SOCKS} git ls-remote "${r}" "${lookup_ref}") ) if [[ ${ref[0]} ]]; then diff --git a/eclass/git-r3.tor.eclass b/eclass/git-r3.tor.eclass deleted file mode 100644 index e3e6717..0000000 --- a/eclass/git-r3.tor.eclass +++ /dev/null @@ -1,1016 +0,0 @@ -# Copyright 1999-2015 Gentoo Authors -# Distributed under the terms of the GNU General Public License v2 -# $Id$ - -# @ECLASS: git-r3.eclass -# @MAINTAINER: -# Michał Górny -# @BLURB: Eclass for fetching and unpacking git repositories. -# @DESCRIPTION: -# Third generation eclass for easing maintenance of live ebuilds using -# git as remote repository. -# -# Patched by symlynX to allow for gits via Tor. Why Tor? Because -# unlike HTTPS it provides end-to-end authenticity which is not -# susceptible to man-in-the-middle attacks, so all gits should -# migrate to Tor, cjdns or gnunet-vpn. But the latter two do -# not need custom changes to this file to do their job. -# -# @FIXME: Should we automatically define EGIT_SOCKS="torsocks" -# when we see that /etc/tor/torsocks.conf exists? - -case "${EAPI:-0}" in - 0|1|2|3|4|5|6) - ;; - *) - die "Unsupported EAPI=${EAPI} (unknown) for ${ECLASS}" - ;; -esac - -if [[ ! ${_GIT_R3} ]]; then - -inherit eutils - -fi - -EXPORT_FUNCTIONS src_unpack - -if [[ ! ${_GIT_R3} ]]; then - -if [[ ! ${_INHERITED_BY_GIT_2} ]]; then - DEPEND=">=dev-vcs/git-1.8.2.1" -fi - -# @ECLASS-VARIABLE: EGIT_CLONE_TYPE -# @DESCRIPTION: -# Type of clone that should be used against the remote repository. -# This can be either of: 'mirror', 'single', 'shallow'. -# -# This is intended to be set by user in make.conf. Ebuilds are supposed -# to set EGIT_MIN_CLONE_TYPE if necessary instead. -# -# The 'mirror' type clones all remote branches and tags with complete -# history and all notes. EGIT_COMMIT can specify any commit hash. -# Upstream-removed branches and tags are purged from the local clone -# while fetching. This mode is suitable for cloning the local copy -# for development or hosting a local git mirror. However, clones -# of repositories with large diverged branches may quickly grow large. -# -# The 'single+tags' type clones the requested branch and all tags -# in the repository. All notes are fetched as well. EGIT_COMMIT -# can safely specify hashes throughout the current branch and all tags. -# No purging of old references is done (if you often switch branches, -# you may need to remove stale branches yourself). This mode is intended -# mostly for use with broken git servers such as Google Code that fail -# to fetch tags along with the branch in 'single' mode. -# -# The 'single' type clones only the requested branch or tag. Tags -# referencing commits throughout the branch history are fetched as well, -# and all notes. EGIT_COMMIT can safely specify only hashes -# in the current branch. No purging of old references is done (if you -# often switch branches, you may need to remove stale branches -# yourself). This mode is suitable for general use. -# -# The 'shallow' type clones only the newest commit on requested branch -# or tag. EGIT_COMMIT can only specify tags, and since the history is -# unavailable calls like 'git describe' will not reference prior tags. -# No purging of old references is done. This mode is intended mostly for -# embedded systems with limited disk space. -: ${EGIT_CLONE_TYPE:=single} - -# @ECLASS-VARIABLE: EGIT_MIN_CLONE_TYPE -# @DESCRIPTION: -# 'Minimum' clone type supported by the ebuild. Takes same values -# as EGIT_CLONE_TYPE. When user sets a type that's 'lower' (that is, -# later on the list) than EGIT_MIN_CLONE_TYPE, the eclass uses -# EGIT_MIN_CLONE_TYPE instead. -# -# This variable is intended to be used by ebuilds only. Users are -# supposed to set EGIT_CLONE_TYPE instead. -# -# A common case is to use 'single' whenever the build system requires -# access to full branch history, or 'single+tags' when Google Code -# or a similar remote is used that does not support shallow clones -# and fetching tags along with commits. Please use sparingly, and to fix -# fatal errors rather than 'non-pretty versions'. -: ${EGIT_MIN_CLONE_TYPE:=shallow} - -# @ECLASS-VARIABLE: EGIT3_STORE_DIR -# @DESCRIPTION: -# Storage directory for git sources. -# -# This is intended to be set by user in make.conf. Ebuilds must not set -# it. -# -# EGIT3_STORE_DIR=${DISTDIR}/git3-src - -# @ECLASS-VARIABLE: EGIT_MIRROR_URI -# @DEFAULT_UNSET -# @DESCRIPTION: -# 'Top' URI to a local git mirror. If specified, the eclass will try -# to fetch from the local mirror instead of using the remote repository. -# -# The mirror needs to follow EGIT3_STORE_DIR structure. The directory -# created by eclass can be used for that purpose. -# -# Example: -# @CODE -# EGIT_MIRROR_URI="git://mirror.lan/" -# @CODE - -# @ECLASS-VARIABLE: EGIT_REPO_URI -# @REQUIRED -# @DESCRIPTION: -# URIs to the repository, e.g. git://foo, https://foo. If multiple URIs -# are provided, the eclass will consider them as fallback URIs to try -# if the first URI does not work. For supported URI syntaxes, read up -# the manpage for git-clone(1). -# -# It can be overriden via env using ${PN}_LIVE_REPO variable. -# -# Can be a whitespace-separated list or an array. -# -# Example: -# @CODE -# EGIT_REPO_URI="git://a/b.git https://c/d.git" -# @CODE - -# @ECLASS-VARIABLE: EVCS_OFFLINE -# @DEFAULT_UNSET -# @DESCRIPTION: -# If non-empty, this variable prevents any online operations. - -# @ECLASS-VARIABLE: EVCS_UMASK -# @DEFAULT_UNSET -# @DESCRIPTION: -# Set this variable to a custom umask. This is intended to be set by -# users. By setting this to something like 002, it can make life easier -# for people who do development as non-root (but are in the portage -# group), and then switch over to building with FEATURES=userpriv. -# Or vice-versa. Shouldn't be a security issue here as anyone who has -# portage group write access already can screw the system over in more -# creative ways. - -# @ECLASS-VARIABLE: EGIT_BRANCH -# @DEFAULT_UNSET -# @DESCRIPTION: -# The branch name to check out. If unset, the upstream default (HEAD) -# will be used. -# -# It can be overriden via env using ${PN}_LIVE_BRANCH variable. - -# @ECLASS-VARIABLE: EGIT_COMMIT -# @DEFAULT_UNSET -# @DESCRIPTION: -# The tag name or commit identifier to check out. If unset, newest -# commit from the branch will be used. If set, EGIT_BRANCH will -# be ignored. -# -# It can be overriden via env using ${PN}_LIVE_COMMIT variable. - -# @ECLASS-VARIABLE: EGIT_CHECKOUT_DIR -# @DESCRIPTION: -# The directory to check the git sources out to. -# -# EGIT_CHECKOUT_DIR=${WORKDIR}/${P} - -# @FUNCTION: _git-r3_env_setup -# @INTERNAL -# @DESCRIPTION: -# Set the eclass variables as necessary for operation. This can involve -# setting EGIT_* to defaults or ${PN}_LIVE_* variables. -_git-r3_env_setup() { - debug-print-function ${FUNCNAME} "$@" - - # check the clone type - case "${EGIT_CLONE_TYPE}" in - mirror|single+tags|single|shallow) - ;; - *) - die "Invalid EGIT_CLONE_TYPE=${EGIT_CLONE_TYPE}" - esac - case "${EGIT_MIN_CLONE_TYPE}" in - shallow) - ;; - single) - if [[ ${EGIT_CLONE_TYPE} == shallow ]]; then - einfo "git-r3: ebuild needs to be cloned in '\e[1msingle\e[22m' mode, adjusting" - EGIT_CLONE_TYPE=single - fi - ;; - single+tags) - if [[ ${EGIT_CLONE_TYPE} == shallow || ${EGIT_CLONE_TYPE} == single ]]; then - einfo "git-r3: ebuild needs to be cloned in '\e[1msingle+tags\e[22m' mode, adjusting" - EGIT_CLONE_TYPE=single+tags - fi - ;; - mirror) - if [[ ${EGIT_CLONE_TYPE} != mirror ]]; then - einfo "git-r3: ebuild needs to be cloned in '\e[1mmirror\e[22m' mode, adjusting" - EGIT_CLONE_TYPE=mirror - fi - ;; - *) - die "Invalid EGIT_MIN_CLONE_TYPE=${EGIT_MIN_CLONE_TYPE}" - esac - - local esc_pn livevar - esc_pn=${PN//[-+]/_} - - livevar=${esc_pn}_LIVE_REPO - EGIT_REPO_URI=${!livevar:-${EGIT_REPO_URI}} - [[ ${!livevar} ]] \ - && ewarn "Using ${livevar}, no support will be provided" - - livevar=${esc_pn}_LIVE_BRANCH - EGIT_BRANCH=${!livevar:-${EGIT_BRANCH}} - [[ ${!livevar} ]] \ - && ewarn "Using ${livevar}, no support will be provided" - - livevar=${esc_pn}_LIVE_COMMIT - EGIT_COMMIT=${!livevar:-${EGIT_COMMIT}} - [[ ${!livevar} ]] \ - && ewarn "Using ${livevar}, no support will be provided" - - # Migration helpers. Remove them when git-2 is removed. - - if [[ ${EGIT_SOURCEDIR} ]]; then - eerror "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR. While updating" - eerror "your ebuild, please check whether the variable is necessary at all" - eerror "since the default has been changed from \${S} to \${WORKDIR}/\${P}." - eerror "Therefore, proper setting of S may be sufficient." - die "EGIT_SOURCEDIR has been replaced by EGIT_CHECKOUT_DIR." - fi - - if [[ ${EGIT_MASTER} ]]; then - eerror "EGIT_MASTER has been removed. Instead, the upstream default (HEAD)" - eerror "is used by the eclass. Please remove the assignment or use EGIT_BRANCH" - eerror "as necessary." - die "EGIT_MASTER has been removed." - fi - - if [[ ${EGIT_HAS_SUBMODULES} ]]; then - eerror "EGIT_HAS_SUBMODULES has been removed. The eclass no longer needs" - eerror "to switch the clone type in order to support submodules and therefore" - eerror "submodules are detected and fetched automatically." - die "EGIT_HAS_SUBMODULES is no longer necessary." - fi - - if [[ ${EGIT_PROJECT} ]]; then - eerror "EGIT_PROJECT has been removed. Instead, the eclass determines" - eerror "the local clone path using path in canonical EGIT_REPO_URI." - eerror "If the current algorithm causes issues for you, please report a bug." - die "EGIT_PROJECT is no longer necessary." - fi - - if [[ ${EGIT_BOOTSTRAP} ]]; then - eerror "EGIT_BOOTSTRAP has been removed. Please create proper src_prepare()" - eerror "instead." - die "EGIT_BOOTSTRAP has been removed." - fi - - if [[ ${EGIT_NOUNPACK} ]]; then - eerror "EGIT_NOUNPACK has been removed. The eclass no longer calls default" - eerror "unpack function. If necessary, please declare proper src_unpack()." - die "EGIT_NOUNPACK has been removed." - fi -} - -# @FUNCTION: _git-r3_set_gitdir -# @USAGE: -# @INTERNAL -# @DESCRIPTION: -# Obtain the local repository path and set it as GIT_DIR. Creates -# a new repository if necessary. -# -# may be used to compose the path. It should therefore be -# a canonical URI to the repository. -_git-r3_set_gitdir() { - debug-print-function ${FUNCNAME} "$@" - - local repo_name=${1#*://*/} - - # strip the trailing slash - repo_name=${repo_name%/} - - # strip common prefixes to make paths more likely to match - # e.g. git://X/Y.git vs https://X/git/Y.git - # (but just one of the prefixes) - case "${repo_name}" in - # gnome.org... who else? - browse/*) repo_name=${repo_name#browse/};; - # cgit can proxy requests to git - cgit/*) repo_name=${repo_name#cgit/};; - # pretty common - git/*) repo_name=${repo_name#git/};; - # gentoo.org - gitroot/*) repo_name=${repo_name#gitroot/};; - # google code, sourceforge - p/*) repo_name=${repo_name#p/};; - # kernel.org - pub/scm/*) repo_name=${repo_name#pub/scm/};; - esac - # ensure a .git suffix, same reason - repo_name=${repo_name%.git}.git - # now replace all the slashes - repo_name=${repo_name//\//_} - - local distdir=${PORTAGE_ACTUAL_DISTDIR:-${DISTDIR}} - : ${EGIT3_STORE_DIR:=${distdir}/git3-src} - - GIT_DIR=${EGIT3_STORE_DIR}/${repo_name} - - if [[ ! -d ${EGIT3_STORE_DIR} ]]; then - ( - addwrite / - mkdir -p "${EGIT3_STORE_DIR}" - ) || die "Unable to create ${EGIT3_STORE_DIR}" - fi - - addwrite "${EGIT3_STORE_DIR}" - if [[ ! -d ${GIT_DIR} ]]; then - local saved_umask - if [[ ${EVCS_UMASK} ]]; then - saved_umask=$(umask) - umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}" - fi - mkdir "${GIT_DIR}" || die - git init --bare || die - if [[ ${saved_umask} ]]; then - umask "${saved_umask}" || die - fi - fi -} - -# @FUNCTION: _git-r3_set_submodules -# @USAGE: -# @INTERNAL -# @DESCRIPTION: -# Parse .gitmodules contents passed as -# as in "$(cat .gitmodules)"). Composes a 'submodules' array that -# contains in order (name, URL, path) for each submodule. -_git-r3_set_submodules() { - debug-print-function ${FUNCNAME} "$@" - - local data=${1} - - # ( name url path ... ) - submodules=() - - local l - while read l; do - # submodule..path= - # submodule..url= - [[ ${l} == submodule.*.url=* ]] || continue - - l=${l#submodule.} - local subname=${l%%.url=*} - - # skip modules that have 'update = none', bug #487262. - local upd=$(echo "${data}" | git config -f /dev/fd/0 \ - submodule."${subname}".update) - [[ ${upd} == none ]] && continue - - # https://github.com/git/git/blob/master/refs.c#L39 - # for now, we just filter /. because of #572312 - local enc_subname=${subname//\/.//_} - [[ ${enc_subname} == .* ]] && enc_subname=_${enc_subname#.} - - submodules+=( - "${enc_subname}" - "$(echo "${data}" | git config -f /dev/fd/0 \ - submodule."${subname}".url || die)" - "$(echo "${data}" | git config -f /dev/fd/0 \ - submodule."${subname}".path || die)" - ) - done < <(echo "${data}" | git config -f /dev/fd/0 -l || die) -} - -# @FUNCTION: _git-r3_set_subrepos -# @USAGE: ... -# @INTERNAL -# @DESCRIPTION: -# Create 'subrepos' array containing absolute (canonical) submodule URIs -# for the given . If the URI is relative, URIs will be -# constructed using all s. Otherwise, this single URI -# will be placed in the array. -_git-r3_set_subrepos() { - debug-print-function ${FUNCNAME} "$@" - - local suburl=${1} - subrepos=( "${@:2}" ) - - if [[ ${suburl} == ./* || ${suburl} == ../* ]]; then - # drop all possible trailing slashes for consistency - subrepos=( "${subrepos[@]%%/}" ) - - while true; do - if [[ ${suburl} == ./* ]]; then - suburl=${suburl:2} - elif [[ ${suburl} == ../* ]]; then - suburl=${suburl:3} - - # XXX: correctness checking - - # drop the last path component - subrepos=( "${subrepos[@]%/*}" ) - # and then the trailing slashes, again - subrepos=( "${subrepos[@]%%/}" ) - else - break - fi - done - - # append the preprocessed path to the preprocessed URIs - subrepos=( "${subrepos[@]/%//${suburl}}") - else - subrepos=( "${suburl}" ) - fi -} - - -# @FUNCTION: _git-r3_is_local_repo -# @USAGE: -# @INTERNAL -# @DESCRIPTION: -# Determine whether the given URI specifies a local (on-disk) -# repository. -_git-r3_is_local_repo() { - debug-print-function ${FUNCNAME} "$@" - - local uri=${1} - - [[ ${uri} == file://* || ${uri} == /* ]] -} - -# @FUNCTION: _git-r3_find_head -# @USAGE: -# @INTERNAL -# @DESCRIPTION: -# Given a ref to which remote HEAD was fetched, try to find -# a branch matching the commit. Expects 'git show-ref' -# or 'git ls-remote' output on stdin. -_git-r3_find_head() { - debug-print-function ${FUNCNAME} "$@" - - local head_ref=${1} - local head_hash=$(git rev-parse --verify "${1}" || die) - local matching_ref - - # TODO: some transports support peeking at symbolic remote refs - # find a way to use that rather than guessing - - # (based on guess_remote_head() in git-1.9.0/remote.c) - local h ref - while read h ref; do - # look for matching head - if [[ ${h} == ${head_hash} ]]; then - # either take the first matching ref, or master if it is there - if [[ ! ${matching_ref} || ${ref} == refs/heads/master ]]; then - matching_ref=${ref} - fi - fi - done - - if [[ ! ${matching_ref} ]]; then - die "Unable to find a matching branch for remote HEAD (${head_hash})" - fi - - echo "${matching_ref}" -} - -# @FUNCTION: git-r3_fetch -# @USAGE: [ [ []]] -# @DESCRIPTION: -# Fetch new commits to the local clone of repository. -# -# specifies the repository URIs to fetch from, as a space- -# -separated list. The first URI will be used as repository group -# identifier and therefore must be used consistently. When not -# specified, defaults to ${EGIT_REPO_URI}. -# -# specifies the remote ref or commit id to fetch. -# It is preferred to use 'refs/heads/' for branches -# and 'refs/tags/' for tags. Other options are 'HEAD' -# for upstream default branch and hexadecimal commit SHA1. Defaults -# to the first of EGIT_COMMIT, EGIT_BRANCH or literal 'HEAD' that -# is set to a non-null value. -# -# specifies the local branch identifier that will be used to -# locally store the fetch result. It should be unique to multiple -# fetches within the repository that can be performed at the same time -# (including parallel merges). It defaults to ${CATEGORY}/${PN}/${SLOT%/*}. -# This default should be fine unless you are fetching multiple trees -# from the same repository in the same ebuild. -# -# The fetch operation will affect the EGIT_STORE only. It will not touch -# the working copy, nor export any environment variables. -# If the repository contains submodules, they will be fetched -# recursively. -git-r3_fetch() { - debug-print-function ${FUNCNAME} "$@" - - [[ ${EVCS_OFFLINE} ]] && return - - local repos - if [[ ${1} ]]; then - repos=( ${1} ) - elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then - repos=( "${EGIT_REPO_URI[@]}" ) - else - repos=( ${EGIT_REPO_URI} ) - fi - - local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}} - local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}} - local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}} - local local_ref=refs/git-r3/${local_id}/__main__ - - [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset" - - local -x GIT_DIR - _git-r3_set_gitdir "${repos[0]}" - - # prepend the local mirror if applicable - if [[ ${EGIT_MIRROR_URI} ]]; then - repos=( - "${EGIT_MIRROR_URI%/}/${GIT_DIR##*/}" - "${repos[@]}" - ) - fi - - # try to fetch from the remote - local r success saved_umask - if [[ ${EVCS_UMASK} ]]; then - saved_umask=$(umask) - umask "${EVCS_UMASK}" || die "Bad options to umask: ${EVCS_UMASK}" - fi - for r in "${repos[@]}"; do - einfo "Fetching \e[1m${r}\e[22m ..." - - if [[ ${r} == https?://* ]]; then - # if we're not using git protocol, web proxy takes care of things - EGIT_SOCKS = "" - elif [[ ! ${EGIT_SOCKS} ]] && [[ ${r} == git://*.onion/* ]]; then - if ROOT=/ has_version 'net-proxy/torsocks'; then - EGIT_SOCKS="torsocks" - else - die "Properly configured net-proxy/torsocks required to fetch git from onion." - fi - fi - - local fetch_command=( ${EGIT_SOCKS} git fetch "${r}" ) - local clone_type=${EGIT_CLONE_TYPE} - - if [[ ${r} == https://* ]] && ! ROOT=/ has_version 'dev-vcs/git[curl]'; then - eerror "git-r3: fetching from https:// requested. In order to support https," - eerror "dev-vcs/git needs to be built with USE=curl. Example solution:" - eerror - eerror " echo dev-vcs/git curl >> /etc/portage/package.use" - eerror " emerge -1v dev-vcs/git" - die "dev-vcs/git built with USE=curl required." - fi - - if [[ ${r} == https://code.google.com/* ]]; then - # Google Code has special magic on top of git that: - # 1) can't handle shallow clones at all, - # 2) fetches duplicately when tags are pulled in with branch - # so automatically switch to single+tags mode. - if [[ ${clone_type} == shallow ]]; then - einfo " Google Code does not support shallow clones" - einfo " using \e[1mEGIT_CLONE_TYPE=single+tags\e[22m" - clone_type=single+tags - elif [[ ${clone_type} == single ]]; then - einfo " git-r3: Google Code does not send tags properly in 'single' mode" - einfo " using \e[1mEGIT_CLONE_TYPE=single+tags\e[22m" - clone_type=single+tags - fi - fi - - if [[ ${clone_type} == mirror ]]; then - fetch_command+=( - --prune - # mirror the remote branches as local branches - "+refs/heads/*:refs/heads/*" - # pull tags explicitly in order to prune them properly - "+refs/tags/*:refs/tags/*" - # notes in case something needs them - "+refs/notes/*:refs/notes/*" - # and HEAD in case we need the default branch - # (we keep it in refs/git-r3 since otherwise --prune interferes) - "+HEAD:refs/git-r3/HEAD" - ) - else # single or shallow - local fetch_l fetch_r - - if [[ ${remote_ref} == HEAD ]]; then - # HEAD - fetch_l=HEAD - elif [[ ${remote_ref} == refs/* ]]; then - # regular branch, tag or some other explicit ref - fetch_l=${remote_ref} - else - # tag or commit id... - # let ls-remote figure it out - local tagref=$(${EGIT_SOCKS} git ls-remote "${r}" "refs/tags/${remote_ref}") - - # if it was a tag, ls-remote obtained a hash - if [[ ${tagref} ]]; then - # tag - fetch_l=refs/tags/${remote_ref} - else - # commit id - # so we need to fetch the whole branch - if [[ ${branch} ]]; then - fetch_l=${branch} - else - fetch_l=HEAD - fi - - # fetching by commit in shallow mode? can't do. - if [[ ${clone_type} == shallow ]]; then - clone_type=single - fi - fi - fi - - if [[ ${fetch_l} == HEAD ]]; then - fetch_r=refs/git-r3/HEAD - else - fetch_r=${fetch_l} - fi - - fetch_command+=( - "+${fetch_l}:${fetch_r}" - ) - - if [[ ${clone_type} == single+tags ]]; then - fetch_command+=( - # pull tags explicitly as requested - "+refs/tags/*:refs/tags/*" - ) - fi - fi - - if [[ ${clone_type} == shallow ]]; then - if _git-r3_is_local_repo; then - # '--depth 1' causes sandbox violations with local repos - # bug #491260 - clone_type=single - elif [[ ! $(git rev-parse --quiet --verify "${fetch_r}") ]] - then - # use '--depth 1' when fetching a new branch - fetch_command+=( --depth 1 ) - fi - else # non-shallow mode - if [[ -f ${GIT_DIR}/shallow ]]; then - fetch_command+=( --unshallow ) - fi - fi - - set -- "${fetch_command[@]}" - echo "${@}" >&2 - if "${@}"; then - if [[ ${clone_type} == mirror ]]; then - # find remote HEAD and update our HEAD properly - git symbolic-ref HEAD \ - "$(_git-r3_find_head refs/git-r3/HEAD \ - < <(git show-ref --heads || die))" \ - || die "Unable to update HEAD" - else # single or shallow - if [[ ${fetch_l} == HEAD ]]; then - # find out what branch we fetched as HEAD - local head_branch=$(_git-r3_find_head \ - refs/git-r3/HEAD \ - < <(${EGIT_SOCKS} git ls-remote --heads "${r}" || die)) - - # and move it to its regular place - git update-ref --no-deref "${head_branch}" \ - refs/git-r3/HEAD \ - || die "Unable to sync HEAD branch ${head_branch}" - git symbolic-ref HEAD "${head_branch}" \ - || die "Unable to update HEAD" - fi - fi - - # now let's see what the user wants from us - local full_remote_ref=$( - ${EGIT_SOCKS} git rev-parse --verify --symbolic-full-name "${remote_ref}" - ) - - if [[ ${full_remote_ref} ]]; then - # when we are given a ref, create a symbolic ref - # so that we preserve the actual argument - set -- git symbolic-ref "${local_ref}" "${full_remote_ref}" - else - # otherwise, we were likely given a commit id - set -- git update-ref --no-deref "${local_ref}" "${remote_ref}" - fi - - echo "${@}" >&2 - if ! "${@}"; then - die "Referencing ${remote_ref} failed (wrong ref?)." - fi - - success=1 - break - fi - done - if [[ ${saved_umask} ]]; then - umask "${saved_umask}" || die - fi - [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI" - - # consistency check, in case we got man-in-the-middle't --lynX - git fsck - - # submodules can reference commits in any branch - # always use the 'mirror' mode to accomodate that, bug #503332 - local EGIT_CLONE_TYPE=mirror - - # recursively fetch submodules - if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then - local submodules - _git-r3_set_submodules \ - "$(${EGIT_SOCKS} git cat-file -p "${local_ref}":.gitmodules || die)" - - while [[ ${submodules[@]} ]]; do - local subname=${submodules[0]} - local url=${submodules[1]} - local path=${submodules[2]} - - # use only submodules for which path does exist - # (this is in par with 'git submodule'), bug #551100 - # note: git cat-file does not work for submodules - if [[ $(git ls-tree -d "${local_ref}" "${path}") ]] - then - local commit=$(${EGIT_SOCKS} git rev-parse "${local_ref}:${path}" || die) - - if [[ ! ${commit} ]]; then - die "Unable to get commit id for submodule ${subname}" - fi - - local subrepos - _git-r3_set_subrepos "${url}" "${repos[@]}" - - git-r3_fetch "${subrepos[*]}" "${commit}" "${local_id}/${subname}" - fi - - submodules=( "${submodules[@]:3}" ) # shift - done - fi -} - -# @FUNCTION: git-r3_checkout -# @USAGE: [ [ []]] -# @DESCRIPTION: -# Check the previously fetched tree to the working copy. -# -# specifies the repository URIs, as a space-separated list. -# The first URI will be used as repository group identifier -# and therefore must be used consistently with git-r3_fetch. -# The remaining URIs are not used and therefore may be omitted. -# When not specified, defaults to ${EGIT_REPO_URI}. -# -# specifies the path to place the checkout. It defaults -# to ${EGIT_CHECKOUT_DIR} if set, otherwise to ${WORKDIR}/${P}. -# -# needs to specify the local identifier that was used -# for respective git-r3_fetch. -# -# The checkout operation will write to the working copy, and export -# the repository state into the environment. If the repository contains -# submodules, they will be checked out recursively. -git-r3_checkout() { - debug-print-function ${FUNCNAME} "$@" - - local repos - if [[ ${1} ]]; then - repos=( ${1} ) - elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then - repos=( "${EGIT_REPO_URI[@]}" ) - else - repos=( ${EGIT_REPO_URI} ) - fi - - local out_dir=${2:-${EGIT_CHECKOUT_DIR:-${WORKDIR}/${P}}} - local local_id=${3:-${CATEGORY}/${PN}/${SLOT%/*}} - - local -x GIT_DIR - _git-r3_set_gitdir "${repos[0]}" - - einfo "Checking out \e[1m${repos[0]}\e[22m to \e[1m${out_dir}\e[22m ..." - - if ! git cat-file -e refs/git-r3/"${local_id}"/__main__; then - if [[ ${EVCS_OFFLINE} ]]; then - die "No local clone of ${repos[0]}. Unable to work with EVCS_OFFLINE." - else - die "Logic error: no local clone of ${repos[0]}. git-r3_fetch not used?" - fi - fi - local remote_ref=$( - git symbolic-ref --quiet refs/git-r3/"${local_id}"/__main__ - ) - local new_commit_id=$( - git rev-parse --verify refs/git-r3/"${local_id}"/__main__ - ) - - git-r3_sub_checkout() { - local orig_repo=${GIT_DIR} - local -x GIT_DIR=${out_dir}/.git - local -x GIT_WORK_TREE=${out_dir} - - mkdir -p "${out_dir}" || die - - # use git init+fetch instead of clone since the latter doesn't like - # non-empty directories. - - git init --quiet || die - # setup 'alternates' to avoid copying objects - echo "${orig_repo}/objects" > "${GIT_DIR}"/objects/info/alternates || die - # now copy the refs - # [htn]* safely catches heads, tags, notes without complaining - # on non-existing ones, and omits internal 'git-r3' ref - cp -R "${orig_repo}"/refs/[htn]* "${GIT_DIR}"/refs/ || die - - # (no need to copy HEAD, we will set it via checkout) - - if [[ -f ${orig_repo}/shallow ]]; then - cp "${orig_repo}"/shallow "${GIT_DIR}"/ || die - fi - - set -- git checkout --quiet - if [[ ${remote_ref} ]]; then - set -- "${@}" "${remote_ref#refs/heads/}" - else - set -- "${@}" "${new_commit_id}" - fi - echo "${@}" >&2 - "${@}" || die "git checkout ${remote_ref:-${new_commit_id}} failed" - } - git-r3_sub_checkout - unset -f git-r3_sub_checkout - - local old_commit_id=$( - git rev-parse --quiet --verify refs/git-r3/"${local_id}"/__old__ - ) - if [[ ! ${old_commit_id} ]]; then - echo "GIT NEW branch -->" - echo " repository: ${repos[0]}" - echo " at the commit: ${new_commit_id}" - else - # diff against previous revision - echo "GIT update -->" - echo " repository: ${repos[0]}" - # write out message based on the revisions - if [[ "${old_commit_id}" != "${new_commit_id}" ]]; then - echo " updating from commit: ${old_commit_id}" - echo " to commit: ${new_commit_id}" - - git --no-pager diff --stat \ - ${old_commit_id}..${new_commit_id} - else - echo " at the commit: ${new_commit_id}" - fi - fi - git update-ref --no-deref refs/git-r3/"${local_id}"/{__old__,__main__} || die - - # recursively checkout submodules - if [[ -f ${out_dir}/.gitmodules ]]; then - local submodules - _git-r3_set_submodules \ - "$(<"${out_dir}"/.gitmodules)" - - while [[ ${submodules[@]} ]]; do - local subname=${submodules[0]} - local url=${submodules[1]} - local path=${submodules[2]} - - # use only submodules for which path does exist - # (this is in par with 'git submodule'), bug #551100 - if [[ -d ${out_dir}/${path} ]]; then - local subrepos - _git-r3_set_subrepos "${url}" "${repos[@]}" - - git-r3_checkout "${subrepos[*]}" "${out_dir}/${path}" \ - "${local_id}/${subname}" - fi - - submodules=( "${submodules[@]:3}" ) # shift - done - fi - - # keep this *after* submodules - export EGIT_DIR=${GIT_DIR} - export EGIT_VERSION=${new_commit_id} -} - -# @FUNCTION: git-r3_peek_remote_ref -# @USAGE: [ []] -# @DESCRIPTION: -# Peek the reference in the remote repository and print the matching -# (newest) commit SHA1. -# -# specifies the repository URIs to fetch from, as a space- -# -separated list. When not specified, defaults to ${EGIT_REPO_URI}. -# -# specifies the remote ref to peek. It is preferred to use -# 'refs/heads/' for branches and 'refs/tags/' -# for tags. Alternatively, 'HEAD' may be used for upstream default -# branch. Defaults to the first of EGIT_COMMIT, EGIT_BRANCH or literal -# 'HEAD' that is set to a non-null value. -# -# The operation will be done purely on the remote, without using local -# storage. If commit SHA1 is provided as , the function will -# fail due to limitations of git protocol. -# -# On success, the function returns 0 and writes hexadecimal commit SHA1 -# to stdout. On failure, the function returns 1. -git-r3_peek_remote_ref() { - debug-print-function ${FUNCNAME} "$@" - - local repos - if [[ ${1} ]]; then - repos=( ${1} ) - elif [[ $(declare -p EGIT_REPO_URI) == "declare -a"* ]]; then - repos=( "${EGIT_REPO_URI[@]}" ) - else - repos=( ${EGIT_REPO_URI} ) - fi - - local branch=${EGIT_BRANCH:+refs/heads/${EGIT_BRANCH}} - local remote_ref=${2:-${EGIT_COMMIT:-${branch:-HEAD}}} - - [[ ${repos[@]} ]] || die "No URI provided and EGIT_REPO_URI unset" - - local r success - for r in "${repos[@]}"; do - einfo "Peeking \e[1m${remote_ref}\e[22m on \e[1m${r}\e[22m ..." >&2 - - local lookup_ref - if [[ ${remote_ref} == refs/* || ${remote_ref} == HEAD ]] - then - lookup_ref=${remote_ref} - else - # ls-remote by commit is going to fail anyway, - # so we may as well pass refs/tags/ABCDEF... - lookup_ref=refs/tags/${remote_ref} - fi - - # split on whitespace - local ref=( - $(git ls-remote "${r}" "${lookup_ref}") - ) - - if [[ ${ref[0]} ]]; then - echo "${ref[0]}" - return 0 - fi - done - - return 1 -} - -git-r3_src_fetch() { - debug-print-function ${FUNCNAME} "$@" - - if [[ ! ${EGIT3_STORE_DIR} && ${EGIT_STORE_DIR} ]]; then - ewarn "You have set EGIT_STORE_DIR but not EGIT3_STORE_DIR. Please consider" - ewarn "setting EGIT3_STORE_DIR for git-r3.eclass. It is recommended to use" - ewarn "a different directory than EGIT_STORE_DIR to ease removing old clones" - ewarn "when git-2 eclass becomes deprecated." - fi - - _git-r3_env_setup - git-r3_fetch -} - -git-r3_src_unpack() { - debug-print-function ${FUNCNAME} "$@" - - _git-r3_env_setup - git-r3_src_fetch - git-r3_checkout -} - -# https://bugs.gentoo.org/show_bug.cgi?id=482666 -git-r3_pkg_needrebuild() { - debug-print-function ${FUNCNAME} "$@" - - local new_commit_id=$(git-r3_peek_remote_ref) - [[ ${new_commit_id} && ${EGIT_VERSION} ]] || die "Lookup failed" - - if [[ ${EGIT_VERSION} != ${new_commit_id} ]]; then - einfo "Update from \e[1m${EGIT_VERSION}\e[22m to \e[1m${new_commit_id}\e[22m" - else - einfo "Local and remote at \e[1m${EGIT_VERSION}\e[22m" - fi - - [[ ${EGIT_VERSION} != ${new_commit_id} ]] -} - -# 'export' locally until this gets into EAPI -pkg_needrebuild() { git-r3_pkg_needrebuild; } - -_GIT_R3=1 -fi diff --git a/git-r3.eclass.patch b/git-r3.eclass.patch new file mode 100644 index 0000000..92310c2 --- /dev/null +++ b/git-r3.eclass.patch @@ -0,0 +1,99 @@ +Patch recreated from diff -u with +git co 9dd95690e6f4ff62d66595eb2e0f78c223b32a3e git-r3.eclass +Commit hash obtained by checking date using 'git blame', +then looking up 'git log git-r3.eclass'. +(So now you know how to do this). + +--- /portage/eclass/git-r3.eclass 2018-12-17 10:59:00.141710464 +0100 ++++ git-r3.tor.eclass 2018-12-17 10:33:59.554716188 +0100 +@@ -9,6 +9,15 @@ + # @DESCRIPTION: + # Third generation eclass for easing maintenance of live ebuilds using + # git as remote repository. ++# ++# Patched by symlynX to allow for gits via Tor. Why Tor? Because ++# unlike HTTPS it provides end-to-end authenticity which is not ++# susceptible to man-in-the-middle attacks, so all gits should ++# migrate to Tor, cjdns or gnunet-vpn. But the latter two do ++# not need custom changes to this file to do their job. ++# ++# @FIXME: Should we automatically define EGIT_SOCKS="torsocks" ++# when we see that /etc/tor/torsocks.conf exists? + + case "${EAPI:-0}" in + 0|1|2|3|4|5|6) +@@ -539,7 +548,18 @@ + for r in "${repos[@]}"; do + einfo "Fetching \e[1m${r}\e[22m ..." + +- local fetch_command=( git fetch "${r}" ) ++ if [[ ${r} == https?://* ]]; then ++ # if we're not using git protocol, web proxy takes care of things ++ EGIT_SOCKS = "" ++ elif [[ ! ${EGIT_SOCKS} ]] && [[ ${r} == git://*.onion/* ]]; then ++ if ROOT=/ has_version 'net-proxy/torsocks'; then ++ EGIT_SOCKS="torsocks" ++ else ++ die "Properly configured net-proxy/torsocks required to fetch git from onion." ++ fi ++ fi ++ ++ local fetch_command=( ${EGIT_SOCKS} git fetch "${r}" ) + local clone_type=${EGIT_CLONE_TYPE} + + if [[ ${r} == https://* ]] && ! ROOT=/ has_version 'dev-vcs/git[curl]'; then +@@ -592,7 +612,7 @@ + else + # tag or commit id... + # let ls-remote figure it out +- local tagref=$(git ls-remote "${r}" "refs/tags/${remote_ref}") ++ local tagref=$(${EGIT_SOCKS} git ls-remote "${r}" "refs/tags/${remote_ref}") + + # if it was a tag, ls-remote obtained a hash + if [[ ${tagref} ]]; then +@@ -662,7 +682,7 @@ + # find out what branch we fetched as HEAD + local head_branch=$(_git-r3_find_head \ + refs/git-r3/HEAD \ +- < <(git ls-remote --heads "${r}" || die)) ++ < <(${EGIT_SOCKS} git ls-remote --heads "${r}" || die)) + + # and move it to its regular place + git update-ref --no-deref "${head_branch}" \ +@@ -675,7 +695,7 @@ + + # now let's see what the user wants from us + local full_remote_ref=$( +- git rev-parse --verify --symbolic-full-name "${remote_ref}" ++ ${EGIT_SOCKS} git rev-parse --verify --symbolic-full-name "${remote_ref}" + ) + + if [[ ${full_remote_ref} ]]; then +@@ -701,6 +721,9 @@ + fi + [[ ${success} ]] || die "Unable to fetch from any of EGIT_REPO_URI" + ++ # consistency check, in case we got man-in-the-middle't --lynX ++ git fsck ++ + # submodules can reference commits in any branch + # always use the 'mirror' mode to accomodate that, bug #503332 + local EGIT_CLONE_TYPE=mirror +@@ -709,7 +732,7 @@ + if git cat-file -e "${local_ref}":.gitmodules &>/dev/null; then + local submodules + _git-r3_set_submodules \ +- "$(git cat-file -p "${local_ref}":.gitmodules || die)" ++ "$(${EGIT_SOCKS} git cat-file -p "${local_ref}":.gitmodules || die)" + + while [[ ${submodules[@]} ]]; do + local subname=${submodules[0]} +@@ -721,7 +744,7 @@ + # note: git cat-file does not work for submodules + if [[ $(git ls-tree -d "${local_ref}" "${path}") ]] + then +- local commit=$(git rev-parse "${local_ref}:${path}" || die) ++ local commit=$(${EGIT_SOCKS} git rev-parse "${local_ref}:${path}" || die) + + if [[ ! ${commit} ]]; then + die "Unable to get commit id for submodule ${subname}" -- cgit v1.2.3