0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Git管理フォルダのタグ付け

0
Last updated at Posted at 2026-01-04

はじめに

MacのFinderにはファイルやフォルダに好きな名前のタグを付ける機能があります。
今回は、Git管理しているフォルダにGitタグを付けるコードを紹介します。

目次

Codeの説明

git-tag-sync.shはzsh用のシェルスクリプトです。
このスクリプトでは次のことを実行します。

  1. .gitというディレクトリの親ディレクトリを収集し(隠しフォルダを除く)、Git管理フォルダとする
  2. Gitタグが付いているディレクトリを収集する
  3. Gitタグが付いているGit管理フォルダのタグを保持する
  4. Gitタグが付いている非Git管理フォルダのGitタグを外す
  5. Gitタグが付いていないGit管理フォルダにGitタグを付ける
  6. Gitタグの付与・維持・取消の数をそれぞれ表示
git-tag-sync.sh
#!/usr/bin/env zsh
set -euo pipefail

ROOT="$HOME"
TAGNAME="Git"
MDLS_BIN="/usr/bin/mdls"
AWK_BIN="/usr/bin/awk"

# has_tag: mdls でタグ検知(スペース/特殊文字/パス形式差異に強い)
has_tag() {
  local path="$1"
  local tag="$2"
  "$MDLS_BIN" -raw -name kMDItemUserTags "$path" 2>/dev/null \
    | "$AWK_BIN" -v t="$tag" '
        BEGIN { found=0 }
        /\(null\)/ { next }
        {
          gsub(/[()]/, "");
          n=split($0, a, ",");
          for (i=1; i<=n; i++) {
            s=a[i];
            gsub(/^[[:space:]]+|[[:space:]]+$/, "", s);
            gsub(/^"|"$/, "", s);
            if (s == t) { found=1 }
          }
        }
        END { exit !found }
      '
}

# --- 収集 ----------------------------------------------------------
# 方針:
# - find は -print0 で NUL 区切りにして、スペース/改行を含むパスでも壊れないようにする
# - 隠しフォルダは探索しない。ただし .git 自体は例外で拾う

# 1) .git の親ディレクトリを収集
GIT_DIRS=()
{
  # zsh の read で NUL 区切りを読む
  while IFS= read -r -d '' gitdir; do
    # "/path/to/repo/.git" -> "/path/to/repo"
    GIT_DIRS+=("${gitdir:h}")
  done < <(
    find "$ROOT" \
      \( -path '*/.*' -a ! -name .git -type d -prune \) \
      -o \( -type d -name .git -print0 \) \
      2>/dev/null
  )
}

# sort -u 相当(zsh 組み込み)
# ※ path の順序は安定化させつつ重複排除
GIT_DIRS=(${(ou)GIT_DIRS})

# 2) いま TAGNAME が付いているフォルダ一覧
TAGGED_DIRS=()
{
  # tag --find の出力は改行区切り想定
  # 空でも安全に配列化
  local out
  out="$(tag --find "$TAGNAME" "$ROOT" 2>/dev/null || true)"
  if [[ -n "$out" ]]; then
    TAGGED_DIRS=(${(f)out})
    TAGGED_DIRS=(${(ou)TAGGED_DIRS})
  fi
}

# 高速化: Git 管理フォルダ集合を作る
typeset -A GIT_SET
for d in "${GIT_DIRS[@]}"; do
  GIT_SET[$d]=1
done

# カウント
typeset -i COUNT_KEEP=0
typeset -i COUNT_ADD=0
typeset -i COUNT_REMOVE=0

# --- 反映 ----------------------------------------------------------
# 3) 付ける/保持する(Git管理されているフォルダ)
for d in "${GIT_DIRS[@]}"; do
  # mdls ベースのタグ検知(iCloudなどスペース含むパスでも安全)
  if has_tag "$d" "$TAGNAME"; then
    print -r -- "KEEP  : $d"
    COUNT_KEEP+=1
  else
    tag --add "$TAGNAME" "$d"
    print -r -- "ADD   : $d"
    COUNT_ADD+=1
  fi
done

# 4) 外す(Git管理されてないのにタグが付いてるもの)
#    ※「Git」タグを他用途に使ってない前提。使ってるなら条件を絞る必要あり。
for d in "${TAGGED_DIRS[@]}"; do
  if [[ -z "${GIT_SET[$d]-}" ]]; then
    tag --remove "$TAGNAME" "$d"
    print -r -- "REMOVE: $d"
    COUNT_REMOVE+=1
  fi
done

# --- 集計 ----------------------------------------------------------
print -r -- "SUMMARY -> KEEP: $COUNT_KEEP, ADD: $COUNT_ADD, REMOVE: $COUNT_REMOVE"

実装方法

git-tag-sync.shtagコマンドを使用するので、Homebrewでインストールします。

zsh
brew install tag

git-tag-sync.shという名前で上記のコードをローカルに保存してください。以下では自作スクリプト置き場の定番である~/.local/binに保存することを前提に進めます。

zsh
mkdir -p `~/.local/bin`
mv git-tag-sync.sh ~/.local/bin/

次に実行権限を付与します。(しなればpermission deniedとなります。)

zsh
chmod +x ~/.local/bin/git-tag-sync.sh

~/.local/binをPATHに追加し、反映します。(./を付けずに実行が可能になります。)

zsh
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

使い方

ターミナルで以下を実行してください。MacではFinderのGUIでタグには色をつけられます。
Finderの設定(cmd+,)で、タグの色に応じてフォルダに色を付ける設定にすることもできます。

zsh
git-tag-sync.sh

おわりに

様々なアプリやその拡張機能に.gitフォルダが入っていることがあるので、隠しフォルダは探索から除外しています。

iCloud / Google Drive / One Drive / Dropbox のようなクラウドにあるフォルダも、デスクトップアプリでFiderから探索できてpathを有する場合はGitタグ管理ができるようにしています。
スペース・改行・特殊文字が原因で上手く反映しない可能性もありますが、その場合は適宜コードの編集をお願いします。

今回紹介したコードはMacOSのzshを想定していますが、普段bashを使用されている方は適宜書き換えて使ってみてください。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?