rein's world

다 쓴 git worktree 간편하게 제거하기

git gone을 써서 merge된 branch를 제거하고 있는 것처럼, 더 쓰지 않을 worktree를 제거할 간편하게 제거할 방법이 없을까 하다가 간단한 도구가 없어서, “없으니 내가 짠다” 모드로 짧은 스크립트를 작성했다.

내가 쓰는 git gone 의 원본이 된게 eed3si9n의 쉘 스크립트인데, 여기서 remote에서 없어진 branch를 어떻게 감지하고 처리하는지 – origin/.*: gone] 을 정규표현식으로 찾음 – 따라해서 스크립트 작성했다.

이 스크립트를 활용해서 git-worktree-gone 을 하면 remote에서 없어진 branch에 해당하는 worktree를 찾을 수 있고, git-worktree-gone --prune 을 하면 해당 디렉터리를 모두 제거한다.

#!/usr/bin/env bash -e

GIT="/usr/local/bin/git"

PATTERN_GONE="origin/.*: gone]"

export LC_MESSAGES=C

# find worktree directories that refer "gone" branches.
# - $2: a directory for the worktree.
# - $4: a branch referenced by the worktree.
"${GIT}" branch -vv \
    | grep "${PATTERN_GONE}" \
    | awk '/^[+*]/ {
      printf "The branch \"%s\" for the worktree directory \"%s\" is gone.\n",
        $2, substr($4, 2, length($4)-2)}'

if [[ "$1" == "--prune" ]]; then
  "${GIT}" branch -vv \
      | grep "${PATTERN_GONE}" \
      | awk '/^\+/ {printf "\"%s\"\n", substr($4, 2, length($4)-2)}' \
      | xargs -n1 "${GIT}" worktree remove --force
fi

약간의 사족을 달자면,

  • 현재 디렉터리에 해당하는 worktree가 없어진 branch를 참조하는지는 확인하지만 – 첫번째 awk 패턴인 /^[+*]/ – 제거할 때는 이 패턴을 쓰지 않는다.
  • export LC_MESSAGES=C 로 locale를 C로 강제해서 패턴 매칭이 간단해지게 한다. 이건 원본 스크립트와 동일.
  • git 경로가 /usr/local/bin/git 인데, linux distro의 git을 쓰거나, macOS arm64의 homebrew로 설치한 git의 경우 위치가 달라서 업데이트가 필요할 수 있다.
  • 사라진 원격 branch를 로컬에 반영하려면 git fetch --prunegit pull --prune 을 쓰거나, git config remote.origin.prune true 로 자동으로 이 옵션을 넣어서 쓰면 된다.