git-parse-remote.shon commit fetch, pull: ask config for remote information (5a223a0)
   1#!/bin/sh
   2
   3# git-ls-remote could be called from outside a git managed repository;
   4# this would fail in that case and would issue an error message.
   5GIT_DIR=$(git-rev-parse --git-dir 2>/dev/null) || :;
   6
   7if [ -d "$GIT_DIR"/remotes -a "$GIT_REWRITE_REMOTES" = true ]; then
   8        echo "Rewriting $GIT_DIR/remotes" >&2
   9        error=0
  10        # rewrite into config
  11        {
  12                cd "$GIT_DIR"/remotes
  13                ls | while read f; do
  14                        name=$(echo -n "$f" | tr -c "A-Za-z0-9" ".")
  15                        sed -n \
  16                        -e "s/^URL: /remote.$name.url . /p" \
  17                        -e "s/^Pull: /remote.$name.pull ^$ /p" \
  18                        -e "s/^Push: /remote.$name.push ^$ /p" \
  19                        < "$f"
  20                done
  21                echo done
  22        } | while read key regex value; do
  23                case $key in
  24                done)
  25                        if [ $error = 0 ]; then
  26                                mv "$GIT_DIR"/remotes "$GIT_DIR"/remotes.old
  27                        fi ;;
  28                *)
  29                        git-repo-config $key "$value" $regex || error=1 ;;
  30                esac
  31        done
  32fi
  33
  34get_data_source () {
  35        case "$1" in
  36        */*)
  37                # Not so fast.  This could be the partial URL shorthand...
  38                token=$(expr "z$1" : 'z\([^/]*\)/')
  39                remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
  40                if test "$(git-repo-config --get "remote.$token.url")"
  41                then
  42                        echo config-partial
  43                elif test -f "$GIT_DIR/branches/$token"
  44                then
  45                        echo branches-partial
  46                else
  47                        echo ''
  48                fi
  49                ;;
  50        *)
  51                if test "$(git-repo-config --get "remote.$1.url")"
  52                then
  53                        echo config
  54                elif test -f "$GIT_DIR/remotes/$1"
  55                then
  56                        echo remotes
  57                elif test -f "$GIT_DIR/branches/$1"
  58                then
  59                        echo branches
  60                else
  61                        echo ''
  62                fi ;;
  63        esac
  64}
  65
  66get_remote_url () {
  67        data_source=$(get_data_source "$1")
  68        case "$data_source" in
  69        '')
  70                echo "$1" ;;
  71        config-partial)
  72                token=$(expr "z$1" : '\([^/]*\)/')
  73                remainder=$(expr "z$1" : '[^/]*/\(.*\)')
  74                url=$(git-repo-config --get "remote.$token.url")
  75                echo "$url/$remainder"
  76                ;;
  77        config)
  78                git-repo-config --get "remote.$1.url"
  79                ;;
  80        remotes)
  81                sed -ne '/^URL: */{
  82                        s///p
  83                        q
  84                }' "$GIT_DIR/remotes/$1" ;;
  85        branches)
  86                sed -e 's/#.*//' "$GIT_DIR/branches/$1" ;;
  87        branches-partial)
  88                token=$(expr "z$1" : 'z\([^/]*\)/')
  89                remainder=$(expr "z$1" : 'z[^/]*/\(.*\)')
  90                url=$(sed -e 's/#.*//' "$GIT_DIR/branches/$token")
  91                echo "$url/$remainder"
  92                ;;
  93        *)
  94                die "internal error: get-remote-url $1" ;;
  95        esac
  96}
  97
  98get_remote_default_refs_for_push () {
  99        data_source=$(get_data_source "$1")
 100        case "$data_source" in
 101        '' | config-partial | branches | branches-partial)
 102                ;; # no default push mapping, just send matching refs.
 103        config)
 104                git-repo-config --get-all "remote.$1.push" ;;
 105        remotes)
 106                sed -ne '/^Push: */{
 107                        s///p
 108                }' "$GIT_DIR/remotes/$1" ;;
 109        *)
 110                die "internal error: get-remote-default-ref-for-push $1" ;;
 111        esac
 112}
 113
 114# Subroutine to canonicalize remote:local notation.
 115canon_refs_list_for_fetch () {
 116        # Leave only the first one alone; add prefix . to the rest
 117        # to prevent the secondary branches to be merged by default.
 118        dot_prefix=
 119        for ref
 120        do
 121                force=
 122                case "$ref" in
 123                +*)
 124                        ref=$(expr "z$ref" : 'z+\(.*\)')
 125                        force=+
 126                        ;;
 127                esac
 128                expr "z$ref" : 'z.*:' >/dev/null || ref="${ref}:"
 129                remote=$(expr "z$ref" : 'z\([^:]*\):')
 130                local=$(expr "z$ref" : 'z[^:]*:\(.*\)')
 131                case "$remote" in
 132                '') remote=HEAD ;;
 133                refs/heads/* | refs/tags/* | refs/remotes/*) ;;
 134                heads/* | tags/* | remotes/* ) remote="refs/$remote" ;;
 135                *) remote="refs/heads/$remote" ;;
 136                esac
 137                case "$local" in
 138                '') local= ;;
 139                refs/heads/* | refs/tags/* | refs/remotes/*) ;;
 140                heads/* | tags/* | remotes/* ) local="refs/$local" ;;
 141                *) local="refs/heads/$local" ;;
 142                esac
 143
 144                if local_ref_name=$(expr "z$local" : 'zrefs/\(.*\)')
 145                then
 146                   git-check-ref-format "$local_ref_name" ||
 147                   die "* refusing to create funny ref '$local_ref_name' locally"
 148                fi
 149                echo "${dot_prefix}${force}${remote}:${local}"
 150                dot_prefix=.
 151        done
 152}
 153
 154# Returns list of src: (no store), or src:dst (store)
 155get_remote_default_refs_for_fetch () {
 156        data_source=$(get_data_source "$1")
 157        case "$data_source" in
 158        '' | config-partial | branches-partial)
 159                echo "HEAD:" ;;
 160        config)
 161                canon_refs_list_for_fetch \
 162                        $(git-repo-config --get-all "remote.$1.pull") ;;
 163        branches)
 164                remote_branch=$(sed -ne '/#/s/.*#//p' "$GIT_DIR/branches/$1")
 165                case "$remote_branch" in '') remote_branch=master ;; esac
 166                echo "refs/heads/${remote_branch}:refs/heads/$1"
 167                ;;
 168        remotes)
 169                # This prefixes the second and later default refspecs
 170                # with a '.', to signal git-fetch to mark them
 171                # not-for-merge.
 172                canon_refs_list_for_fetch $(sed -ne '/^Pull: */{
 173                                                s///p
 174                                        }' "$GIT_DIR/remotes/$1")
 175                ;;
 176        *)
 177                die "internal error: get-remote-default-ref-for-push $1" ;;
 178        esac
 179}
 180
 181get_remote_refs_for_push () {
 182        case "$#" in
 183        0) die "internal error: get-remote-refs-for-push." ;;
 184        1) get_remote_default_refs_for_push "$@" ;;
 185        *) shift; echo "$@" ;;
 186        esac
 187}
 188
 189get_remote_refs_for_fetch () {
 190        case "$#" in
 191        0)
 192            die "internal error: get-remote-refs-for-fetch." ;;
 193        1)
 194            get_remote_default_refs_for_fetch "$@" ;;
 195        *)
 196            shift
 197            tag_just_seen=
 198            for ref
 199            do
 200                if test "$tag_just_seen"
 201                then
 202                    echo "refs/tags/${ref}:refs/tags/${ref}"
 203                    tag_just_seen=
 204                    continue
 205                else
 206                    case "$ref" in
 207                    tag)
 208                        tag_just_seen=yes
 209                        continue
 210                        ;;
 211                    esac
 212                fi
 213                canon_refs_list_for_fetch "$ref"
 214            done
 215            ;;
 216        esac
 217}
 218
 219resolve_alternates () {
 220        # original URL (xxx.git)
 221        top_=`expr "z$1" : 'z\([^:]*:/*[^/]*\)/'`
 222        while read path
 223        do
 224                case "$path" in
 225                \#* | '')
 226                        continue ;;
 227                /*)
 228                        echo "$top_$path/" ;;
 229                ../*)
 230                        # relative -- ugly but seems to work.
 231                        echo "$1/objects/$path/" ;;
 232                *)
 233                        # exit code may not be caught by the reader.
 234                        echo "bad alternate: $path"
 235                        exit 1 ;;
 236                esac
 237        done
 238}