g 8.96 KB
Newer Older
1 2 3 4
#!/usr/bin/env bash
#
# Wrapper for git to handle more subdirs at the same time
#
5

Norbert Thiebaud's avatar
Norbert Thiebaud committed
6 7
if [ -n "$g_debug" ] ; then
    set -x
8 9
fi

Norbert Thiebaud's avatar
Norbert Thiebaud committed
10
SUBMODULES_ALL="dictionaries helpcontent2 translations"
11

12
pushd $(dirname $0) > /dev/null
13
if [ -f config_host.mk ] ; then
14
    # we are in the BUILDDIR
15
    SRC_ROOT=$(< config_host.mk grep -a SRC_ROOT | sed -e "s/.*=//")
16 17 18
else
    SRC_ROOT=$(pwd)
fi
19 20
popd > /dev/null

21 22
COREDIR="$SRC_ROOT"

Norbert Thiebaud's avatar
Norbert Thiebaud committed
23 24 25 26 27 28
usage()
{
    git
    echo
    echo "Usage: g [options] [git (checkout|clone|fetch|grep|pull|push|reset) [git options/args..]]"
    echo ""
Peter Foley's avatar
Peter Foley committed
29
    echo " -z restore the git hooks and do other sanity checks"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
30
}
31

Norbert Thiebaud's avatar
Norbert Thiebaud committed
32
refresh_submodule_hooks()
33
{
34 35 36
    local repo=$1
    local hook
    local hook_name
Norbert Thiebaud's avatar
Norbert Thiebaud committed
37

38
    if [ -d "${repo?}"/.git ] ; then
Norbert Thiebaud's avatar
Norbert Thiebaud committed
39
        # use core's hook by default
40
        for hook_name in "${COREDIR?}/.git-hooks"/* ; do
41 42
            hook="${repo?}/.git/hooks/${hook_name##*/}"
            if [ ! -e "${hook?}" ] || [ -L "${hook?}" ] ; then
43 44
                rm -f "${hook?}"
                ln -sf "${hook_name}" "${hook?}"
45
            fi
46
        done
Norbert Thiebaud's avatar
Norbert Thiebaud committed
47
        # override if need be by the submodules' own hooks
48
        for hook_name in "${COREDIR?}/${repo?}/.git-hooks"/* ; do
49 50
            hook="${repo?}/.git/hooks/${hook_name##*/}"
            if [ ! -e "${hook?}" ] || [ -L "${hook?}" ] ; then
51 52 53 54
                rm -f "${hook?}"
                ln -sf "${hook_name}" "${hook?}"
            fi
        done
55
    elif [ -d .git/modules/"${repo}"/hooks ] ; then
56
        for hook_name in "${COREDIR?}/.git-hooks"/* ; do
57 58
            hook=".git/modules/${repo?}/hooks/${hook_name##*/}"
            if [ ! -e "${hook?}" ] || [ -L "${hook?}" ] ; then
59 60
                rm -f "${hook?}"
                ln -sf "${hook_name}" "${hook?}"
61
            fi
62
        done
63
        # override if need be by the submodules' own hooks
64
        for hook_name in "${COREDIR?}/${repo?}/.git-hooks"/* ; do
65 66
            hook=".git/modules/${repo?}/hooks/${hook_name##*/}"
            if [ ! -e "${hook?}" ] || [ -L "${hook?}" ] ; then
67 68 69 70
                rm -f "${hook?}"
                ln -sf "${hook_name}" "${hook?}"
            fi
        done
Norbert Thiebaud's avatar
Norbert Thiebaud committed
71
    fi
72

73 74 75 76
}

refresh_all_hooks()
{
77 78 79
    local repo
    local hook_name
    local hook
Norbert Thiebaud's avatar
Norbert Thiebaud committed
80

Stephan Bergmann's avatar
Stephan Bergmann committed
81
    pushd "${COREDIR?}" > /dev/null
82
    for hook_name in "${COREDIR?}/.git-hooks"/* ; do
83 84
        hook=".git/hooks/${hook_name##*/}"
        if [ ! -e "${hook?}" ] || [ -L "${hook?}" ] ; then
Norbert Thiebaud's avatar
Norbert Thiebaud committed
85
            rm -f "${hook?}"
86
            ln -sf "${hook_name}" "${hook?}"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
87 88 89 90
        fi
    done

    for repo in ${SUBMODULES_ALL?} ; do
91
        refresh_submodule_hooks "$repo"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
92 93 94 95 96 97 98
    done
    popd > /dev/null

}

set_push_url()
{
99
    local repo
Norbert Thiebaud's avatar
Norbert Thiebaud committed
100 101 102

    repo="$1"
    if [ -n "$repo" ] ; then
103
        pushd "${COREDIR?}/${repo?}" > /dev/null
Norbert Thiebaud's avatar
Norbert Thiebaud committed
104
    else
105 106
        pushd "${COREDIR?}" > /dev/null
        repo="core"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
107 108 109
    fi
    echo "setting up push url for ${repo?}"
    if [ "${repo?}" = "helpcontent2" ] ; then
110
        git config remote.origin.pushurl "ssh://${PUSH_USER}logerrit/help"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
111
    else
112
        git config remote.origin.pushurl "ssh://${PUSH_USER}logerrit/${repo?}"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
113 114 115 116 117 118 119 120 121
    fi
    popd > /dev/null
}

set_push_urls()
{
    PUSH_USER="$1"
    set_push_url
    for repo in ${SUBMODULES_ACTIVE?} ; do
122
        set_push_url "${repo?}"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
123 124 125 126 127
    done
}

get_active_submodules()
{
128 129
    SUBMODULES_ACTIVE=""
    local repo
Norbert Thiebaud's avatar
Norbert Thiebaud committed
130 131

    for repo in ${SUBMODULES_ALL?} ; do
132 133 134
        if [ -d "${repo?}"/.git ] || [ -f "${repo?}"/.git ] ; then
            SUBMODULES_ACTIVE="${repo?} ${SUBMODULES_ACTIVE?}"
        fi
135
    done
136 137
}

Norbert Thiebaud's avatar
Norbert Thiebaud committed
138
get_configured_submodules()
139
{
Norbert Thiebaud's avatar
Norbert Thiebaud committed
140
    SUBMODULES_CONFIGURED=""
141
    if [ -f config_host.mk ] ; then
142
        SUBMODULES_CONFIGURED=$(< config_host.mk grep -a GIT_NEEDED_SUBMODULES | sed -e "s/.*=//")
Norbert Thiebaud's avatar
Norbert Thiebaud committed
143
    else
144 145
        # if we need the configured submodule before the configuration is done. we assumed you want them all
        SUBMODULES_CONFIGURED=${SUBMODULES_ALL?}
146
    fi
Norbert Thiebaud's avatar
Norbert Thiebaud committed
147 148
}

149 150 151 152
get_git_reference()
{
    REFERENCED_GIT=""
    if [ -f config_host.mk ]; then
153
        REFERENCED_GIT=$(< config_host.mk grep -a GIT_REFERENCE_SRC | sed -e "s/.*=//")
154
    fi
155 156
    LINKED_GIT=""
    if [ -f config_host.mk ]; then
157
        LINKED_GIT=$(< config_host.mk grep -a GIT_LINK_SRC | sed -e "s/.*=//")
158
    fi
159 160
}

161 162
do_shortcut_update()
{
163 164
    local module
    local repo
165 166

    for module in $SUBMODULES_CONFIGURED ; do
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
        if [ ! -d "${module?}"/.git ] ; then
            case "${module?}" in
                helpcontent2)
                    if [ -d clone/help/.git ] ; then
                        repo="clone/help/.git"
                    fi
                    ;;
                *)
                    if [ -d clone/"${module?}"/.git ] ; then
                        repo="clone/${module?}/.git"
                    fi
                    ;;
            esac
            if [ -n "$repo" ] ; then
                cp -r "${repo?}" "${module?}/."
            fi
        fi
184 185 186
    done
}

Norbert Thiebaud's avatar
Norbert Thiebaud committed
187 188
do_git_cmd()
{
189
    echo "cmd:$*"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
190 191 192 193 194 195
    git "$@"
    git submodule foreach git "$@" $KEEP_GOING
}

do_checkout()
{
196 197 198 199
    local cmd
    local create_branch="0"
    local branch
    local module
Norbert Thiebaud's avatar
Norbert Thiebaud committed
200 201 202

    git checkout "$@" || return $?
    for cmd in "$@" ; do
203
        if [ "$cmd" = "-f" ]; then
204
            continue
205 206 207 208 209 210
        elif [ "$cmd" = "-b" ] ; then
            create_branch=1
        elif [ "$create_branch" = "1" ] ; then
            branch="$cmd"
            create_branch=0
        fi
Norbert Thiebaud's avatar
Norbert Thiebaud committed
211 212
    done
    if [ -f .gitmodules ] ; then
213 214 215 216
        git submodule update
        if [ -n "$branch" ] ; then
            git submodule foreach git checkout -b "${branch}" HEAD || return $?
        fi
Norbert Thiebaud's avatar
Norbert Thiebaud committed
217
    else
218 219 220 221 222 223 224 225
        # now that is the nasty case we moved prior to submodules
        # delete the submodules left over if any
        for module in $SUBMODULES_ALL ; do
            echo "clean-up submodule $module"
            rm -fr "${module}"
        done
        # make sure we have the needed repo in clone
        ./g clone && ./g -f checkout "$@" || return $?
Norbert Thiebaud's avatar
Norbert Thiebaud committed
226 227 228 229 230 231 232 233
    fi
    return $?
}

do_reset()
{
    git reset "$@" || return $?
    if [ -f .gitmodules ] ; then
234
        git submodule update || return $?
Norbert Thiebaud's avatar
Norbert Thiebaud committed
235
    else
236 237 238 239 240 241 242 243
        # now that is the nasty case we moved prior to submodules
        # delete the submodules left over if any
        for module in $SUBMODULES_ALL ; do
            echo "clean-up submodule $module"
            rm -fr "${module}"
        done
        # make sure we have the needed repo in clone
        ./g clone && ./g -f reset "$@"
Norbert Thiebaud's avatar
Norbert Thiebaud committed
244 245 246 247 248 249
    fi
    return $?;
}

do_init_modules()
{
250 251
    local module
    local configured
252

253 254
    do_shortcut_update

Norbert Thiebaud's avatar
Norbert Thiebaud committed
255
    for module in $SUBMODULES_CONFIGURED ; do
256 257 258 259 260 261 262 263 264
        if [ -n "$LINKED_GIT" ] ; then
            if ! [ -d ".git/modules/${module}" ]; then
                ./bin/git-new-module-workdir "${LINKED_GIT}/${module}" "${module}"
            fi
        fi
        configured=$(git config --local --get submodule."${module}".url)
        if [ -z "$configured" ] ; then
            git submodule init "$module" || return $?
        fi
Norbert Thiebaud's avatar
Norbert Thiebaud committed
265
    done
266 267
    for module in $SUBMODULES_CONFIGURED ; do
        if [ -n "$REFERENCED_GIT" ] ; then
268
            git submodule update --reference "$REFERENCED_GIT/.git/modules/$module" "$module" || return $?
269
        else
270
            git submodule update "$module" || return $?
271 272
        fi
    done
Norbert Thiebaud's avatar
Norbert Thiebaud committed
273
    return 0
274 275
}

Norbert Thiebaud's avatar
Norbert Thiebaud committed
276 277 278 279 280 281

# no params, no action
if [ "$#" -eq "0" ] ; then
    usage
fi

282
if [ ! "$(type -p git)" ]; then
Norbert Thiebaud's avatar
Norbert Thiebaud committed
283 284 285 286 287 288 289
    echo "Cannot find the git binary! Is git installed and is in PATH?"
    exit 1
fi


get_active_submodules
get_configured_submodules
290
get_git_reference
Norbert Thiebaud's avatar
Norbert Thiebaud committed
291 292 293



294

295 296 297 298 299 300
# extra params for some commands, like log
EXTRA=
COMMAND="$1"
PAGER=
RELATIVIZE=1
PUSH_ALL=
301 302 303 304
PUSH_USER=
PUSH_NOTES=
LAST_WORKING=
SET_LAST_WORKING=
305
ALLOW_EMPTY=
Norbert Thiebaud's avatar
Norbert Thiebaud committed
306
KEEP_GOING=
307
REPORT_REPOS=1
308
REPORT_COMMANDS=0
309
REPORT_COMPACT=0
310
DO_HOOK_REFRESH=false
311 312 313

while [ "${COMMAND:0:1}" = "-" ] ; do
    case "$COMMAND" in
Norbert Thiebaud's avatar
Norbert Thiebaud committed
314
        -f )KEEP_GOING="||:"
315 316
            ;;
        -z)
317 318 319 320 321 322 323 324 325 326 327
            refresh_all_hooks
            exit 0;
            ;;
        --set-push-urls)
            shift
            PUSH_USER="$1"
            if [ -n "${PUSH_USER}" ] ; then
                PUSH_USER="${PUSH_USER}@"
            fi
            set_push_urls "$PUSH_USER"
            exit 0;
328
            ;;
329 330 331
        -*)
            echo "option: $COMMAND not supported" 1>&2
            exit 1
332 333 334 335 336
    esac
    shift
    COMMAND="$1"
done

Norbert Thiebaud's avatar
Norbert Thiebaud committed
337 338
shift

339
case "$COMMAND" in
Norbert Thiebaud's avatar
Norbert Thiebaud committed
340
    branch)
341 342
        do_git_cmd "${COMMAND}" "$@"
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
343
    checkout)
344 345
        do_checkout "$@"
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
346
    clone)
347
        do_init_modules && refresh_all_hooks
348
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
349
    fetch)
350
        (git fetch "$@" && git submodule foreach git fetch "$@" ) && git submodule update
Norbert Thiebaud's avatar
Norbert Thiebaud committed
351

352
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
353 354
    grep)
        KEEP_GOING="||:"
355 356
        do_git_cmd "${COMMAND}" "$@"
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
357
    pull)
358 359
        git pull "$@" && git submodule update && refresh_all_hooks
        ;;
360
    push)
361 362 363 364 365
        git submodule foreach git push "$@"
        if [ "$?" = "0" ] ; then
            git push "$@"
        fi
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
366
    reset)
367 368
        do_reset
        ;;
369
    tag)
370 371 372 373
        do_git_cmd "${COMMAND}" "$@"
        ;;
    "")
        ;;
Norbert Thiebaud's avatar
Norbert Thiebaud committed
374
    *)
375 376
        echo "./g does not support command: $COMMAND" 1>&2
        exit 1;
377 378 379
        ;;
esac

Norbert Thiebaud's avatar
Norbert Thiebaud committed
380
exit $?
381

382
# vi:set shiftwidth=4 expandtab: