Knowledge Base

Preserving for the future: Shell scripts, AoC, and more

Git clone and/or pull

I heavily adapted a function generated by a Copyright Expunging Engine. Here is my function for easily cloning/pulling a git remote.

files/2026/listings/ginit.sh (Source)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
ginit() {
    err() {
        printf '%s\n' "${@}" 1>&2
    }
    err "# ginit ${*}"
    ( # parenthesis to suppress the cd
        if test "${#}" -lt 1 ;
        then
            err "Usage: ginit <repository_url> [branch_name] [dirname]"
            return 1
        fi
        REPO_URL="${1}"
        REPO_DIR="$( basename "${REPO_URL}" .git )"
        BRANCH_NAME="${2}"
        DIRNAME="${3}"
        if test -n "${DIRNAME}" ; then REPO_DIR="${DIRNAME}" ; fi
        if test -d "${REPO_DIR}" ;
        then
            err "Directory ${REPO_DIR} already exists. Changing directory to it."
            cd "${REPO_DIR}" || return
            if test -n "${BRANCH_NAME}" ;
            then
                err "Switching to branch ${BRANCH_NAME}"
                git fetch --all
                # my old redirect trick to filter stderr
                {
                    {
                        # Use 'git switch' (modern) or 'git checkout' (older versions)
                        # 'git switch -c' creates and switches to a new branch if it doesn't exist locally
                        git switch -c "${BRANCH_NAME}" "origin/${BRANCH_NAME}" || \
                            git checkout -b "${BRANCH_NAME}" "origin/${BRANCH_NAME}" || \
                            git checkout "${BRANCH_NAME}"
                    } 2>&1 1>&3 | sed -r -e '/fatal: a branch named.*already exists/d' 1>&2
                } 3>&1
            fi
        else
            if test -n "${BRANCH_NAME}" ;
            then
                err "Cloning branch ${BRANCH_NAME} into ${REPO_DIR}"
                git clone -b "${BRANCH_NAME}" "${REPO_URL}" "${REPO_DIR}"
            else
                err "Cloning default branch into ${REPO_DIR}"
                git clone "${REPO_URL}" "${REPO_DIR}"
            fi
            if test -d "${REPO_DIR}" ;
            then
                cd "${REPO_DIR}" || return
                git pull
                err "Changed directory to ${REPO_DIR}"
            else
                err "Failed to clone repository"
                return 1
            fi
        fi
    )
}

Comments