From 4f7a53dd36315e5f280d4553dc58bc3226e6ccc2 Mon Sep 17 00:00:00 2001 From: Kornilios Kourtis Date: Tue, 18 Feb 2025 15:14:19 +0100 Subject: [PATCH] api/Makefile: make it work for worktrees Signed-off-by: Kornilios Kourtis --- api/Makefile | 4 +-- contrib/scripts/repo-docker-run.sh | 54 ++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100755 contrib/scripts/repo-docker-run.sh diff --git a/api/Makefile b/api/Makefile index e8ec8c6f43d..9b862f6b582 100644 --- a/api/Makefile +++ b/api/Makefile @@ -30,7 +30,7 @@ __check-breaking_local: .PHONY: proto lint format check-breaking all proto lint format check-breaking: - $(CONTAINER_ENGINE) container run --rm \ + ../contrib/scripts/repo-docker-run.sh --rm \ --volume $(CURDIR)/..:/src \ --workdir /src/api \ --user "$(shell id -u):$(shell id -g)" \ @@ -39,7 +39,7 @@ all proto lint format check-breaking: .PHONY: debug debug: - @echo $(CONTAINER_ENGINE) container run --rm \ + @echo ../contrib/scripts/repo-docker-run.sh --rm \ --volume $(CURDIR)/..:/src \ --workdir /src/api \ --user "$(shell id -u):$(shell id -g)" \ diff --git a/contrib/scripts/repo-docker-run.sh b/contrib/scripts/repo-docker-run.sh new file mode 100755 index 00000000000..c9d78ce2ab4 --- /dev/null +++ b/contrib/scripts/repo-docker-run.sh @@ -0,0 +1,54 @@ +#!/usr/bin/env bash +# +# Running things that use the git command in a container might result in issues when using bare git +# directories, worktrees, or repositories cloned with --shared. This script aims to address that. +# +# See: https://github.com/buildroot/buildroot/blob/master/utils/docker-run + + +DIR=$(dirname "${0}") +MAIN_DIR=$(readlink -f "${DIR}/..") +if [ -L "${MAIN_DIR}/.git/config" ]; then + # Support git-new-workdir + GIT_DIR="$(dirname "$(realpath "${MAIN_DIR}/.git/config")")" +else + # Support git-worktree + GIT_DIR="$(cd "${MAIN_DIR}" && git rev-parse --no-flags --git-common-dir)" +fi + +declare -a mountpoints=( + "${MAIN_DIR}" +) + +# Empty GIT_DIR means that we are not in a workdir, *and* git is too old +# to know about worktrees, so we're not in a worktree either. So it means +# we're in the main git working copy, and thus we don't need to mount the +# .git directory. +if [ "${GIT_DIR}" ]; then + # GIT_DIR in the main working copy (when git supports worktrees) will + # be just '.git', but 'docker run' needs an absolute path. If it is + # not absolute, GIT_DIR is relative to MAIN_DIR. If it's an absolute + # path already (in a wordir), then that's a noop. + GIT_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}")" + mountpoints+=( "${GIT_DIR}" ) + + # 'repo' stores .git/objects separately. + if [ -L "${GIT_DIR}/objects" ]; then + # GITDIR is already an absolute path, but for symetry + # with the above, keep the same cd+readlink construct. + OBJECTS_DIR="$(cd "${MAIN_DIR}"; readlink -e "${GIT_DIR}/objects")" + mountpoints+=( "${OBJECTS_DIR}" ) + fi +fi + +declare -a docker_opts=( + --rm + --user "$(id -u):$(id -g)" +) + +# shellcheck disable=SC2013 # can't use while-read because of the assignment +for dir in $(printf '%s\n' "${mountpoints[@]}" |LC_ALL=C sort -u); do + docker_opts+=( --mount "type=bind,src=${dir},dst=${dir}" ) +done + +docker run "${docker_opts[@]}" "${@}"