Last active
June 15, 2022 10:25
-
-
Save mattyclarkson/e3d75fe06548f3ca58053acd5d01b786 to your computer and use it in GitHub Desktop.
A shell script to add `safe.directory` to a `.gitconfig`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Usage: ./safe-directory.sh directory [.gitconfig] [dst] | |
# | |
# `git` will throw permission errors when a repository has been cloned with a | |
# user different to the runtime user. This script allows adding the cloned | |
# repository to the `safe.directory` configuration variable without the need | |
# for an installed `git` binary. | |
# | |
# This can be useful on CI runners, when the repository has been cloned as the | |
# `root` user but the build runs inside a container that has a user different | |
# to `root`. There is no guarantee that the container will have `git` | |
# installed, hence this script. | |
# | |
# Arguments | |
# directory The directory to add to `safe.directory` | |
# .gitconfig The `.gitconfig` to parse, defaulting to `~/.gitconfig` | |
# dst Filepath to write the resulting `git `configuration, | |
# defaults to the input `.gitconfig` | |
# | |
# Examples | |
# ./safe-directory.sh $CI_PROJECT_DIR | |
set -eu | |
# Parse the incoming user arguments | |
DIRECTORY="${1}" | |
SRC="${2-"~/.gitconfig"}" | |
DST="${3-"${SRC}"}" | |
# shellcheck disable=SC2088,SC2249 | |
case "${DIRECTORY}" in | |
"~/"*) | |
SRC="${HOME}/${DIRECTORY#"~/"}" | |
;; | |
esac | |
# shellcheck disable=SC2088,SC2249 | |
case "${SRC}" in | |
"~/"*) | |
SRC="${HOME}/${SRC#"~/"}" | |
;; | |
esac | |
# shellcheck disable=SC2088,SC2249 | |
case "${DST}" in | |
"~/"*) | |
DST="${HOME}/${DST#"~/"}" | |
;; | |
esac | |
readonly DIRECTORY SRC DST | |
# Initialize/check the `.gitconfig` | |
if ! test -f "${SRC}"; then | |
touch "${SRC}" | |
fi | |
if ! test -f "${SRC}"; then | |
printf >&2 "'%s' is not a normal SRC" "${SRC}" | |
exit 2 | |
fi | |
# Write into a temporary file | |
TMP="$(mktemp /tmp/gitconfig.XXXXXXXXXX)" | |
readonly TMP | |
trap 'rm ${TMP}' EXIT | |
# For each line in the configuration | |
# Detect any previous `[safe]` section | |
# Insert the directory | |
while IFS= read -r LINE; do | |
# Process the `[safe]` section | |
if ! "${SAFE-true}"; then | |
case "${LINE}" in | |
*"directory"*) | |
if test "${LINE##*= }" != "${DIRECTORY}"; then | |
printf "%s\n" "${LINE}" >>"${TMP}" | |
continue | |
fi | |
;; | |
*) | |
printf "Adding '%s' to '%s'\n" "${DIRECTORY}" "${SRC}" | |
;; | |
esac | |
SAFE=true | |
printf "\tdirectory = %s\n" "${DIRECTORY}" >>"${TMP}" | |
continue | |
fi | |
# Detect the `[safe]` section | |
case "${LINE}" in | |
"[safe]"*) | |
printf "%s\n" "${LINE}" >>"${TMP}" | |
SAFE=false | |
;; | |
*) | |
printf "%s\n" "${LINE}" >>"${TMP}" | |
;; | |
esac | |
done <"${SRC}" | |
# Add the `[safe]` header if, needed | |
if test "null" = "${SAFE-null}"; then | |
printf "[safe]\n" >>"${TMP}" | |
SAFE=false | |
fi | |
# If the directory was never found then add it | |
if ! "${SAFE:-true}"; then | |
printf "Adding '%s' to '%s'\n" "${DIRECTORY}" "${SRC}" | |
printf "\tdirectory = %s\n" "${DIRECTORY}" >>"${TMP}" | |
fi | |
# Copy over the temporary file | |
cp "${TMP}" "${DST}" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment