Gitワークフロー
dotnix で管理しているGit関連ツールの設定まとめ。
設定リポジトリ: github.com/yutakobayashidev/dotnix
Git (home-manager)
設定ファイル: `nix/modules/home/programs/git.nix
エイリアス
| alias | コマンド | 説明 |
|---|---|---|
clone | clone --recursive | サブモジュール込みでclone |
logg | log --graph --abbrev-commit ... | カラー付きグラフログ |
swor | fzf でリモートブランチ選択 → switch | リモートブランチへの切り替え |
swf | branch -a | fzf | xargs switch | 全ブランチからfzf選択 |
sms | submodule foreach "git status" | 全サブモジュールのstatus |
root | rev-parse --show-toplevel | リポジトリルートを表示 |
uncommit | reset HEAD^ | 直前のコミットを取り消し |
recommit | commit -c ORIG_HEAD | 取り消したコミットを再コミット |
主要設定
[push]
default = simple
autoSetupRemote = true # push時に自動でupstream設定
useForceIfIncludes = true # force-pushの安全弁
[commit]
verbose = true # コミット時にdiffを表示
[rebase]
autoStash = true # rebase前に自動stash
autoSquash = true # fixup!/squash!を自動処理
updateRefs = true # スタックしたブランチを自動更新
[merge]
ff = false # 常にマージコミットを作成
conflictstyle = zdiff3 # 3-wayコンフリクト表示(ancestor付き)
[fetch]
writeCommitGraph = true # commit-graphを自動更新
prune = true # リモートで消えたブランチを自動削除
pruneTags = true # 同上(タグ)
all = true # 全リモートからfetch
[pull]
rebase = true # pull時にmergeではなくrebase
[init]
defaultBranch = main
[column]
ui = auto # branch等の出力をカラム表示
[branch]
sort = -committerdate # ブランチを最終コミット日時で降順ソート
[help]
autocorrect = prompt # typo時に修正候補を提示
[rerere]
enabled = true # コンフリクト解決を記憶
autoupdate = true # rerere適用後に自動stage
[wt]
basedir = .git/worktree # git-wtのworktree配置先
remover = trash # worktree削除時にtrashを使用グローバル .gitignore
macOS (DS_Store 等), Python (__pycache__, venv 等), Claude Code (z-ai/, .claude/settings.local.json) など広範にカバー。
GitHub CLI (gh)
設定ファイル: nix/modules/home/programs/gh.nix
拡張機能
| パッケージ | 説明 |
|---|---|
gh-graph | コントリビューショングラフ表示 |
gh-nippou | 日報生成(その日のGitHub活動をまとめる) |
gh-dash | ダッシュボードTUI(PR/Issue一覧) |
gh-actions-cache | GitHub Actions キャッシュ管理 |
gh-poi | マージ済みブランチの一括削除 |
gh-notify | GitHub通知管理 |
gh-do | 複数リポジトリで一括操作 |
gh-nippou と gh-graph は flake inputs から直接取得(nixpkgsに無いため overlay で導入)。
1Password Shell Plugins(macOS)
設定ファイル: nix/hosts/M2-MacBook-Air/default.nix
macOSでは1Password Shell Pluginsを使い、gh と awscli2 の認証を1Password経由で管理:
programs._1password-shell-plugins = {
enable = true;
plugins = with pkgs; [ gh awscli2 ];
};これにより gh auth login 不要で、1Passwordのバイオメトリクス認証でトークンが自動注入される。
gh auth 自動切り替え
設定ファイル: zsh/functions/gh-auth-switch.zsh
chpwd フック(ディレクトリ移動時に自動実行)で、ghqパスの owner 部分を見て gh auth switch を実行。
~/ghq/github.com/<owner>/<repo> に入る
→ GH_AUTH_ACCOUNT_MAP[owner] を参照
→ 該当アカウントに切り替え(デフォルト: yutakobayashidev)
キャッシュ変数 _GH_CURRENT_USER で無駄な gh auth status 呼び出しを回避。
gh エイリアス・シェル関数
| コマンド | 定義 | 説明 |
|---|---|---|
browse-pr | gh pr view --web | 現在のPRをブラウザで開く |
browse | gh repo view --web | 現在のリポジトリをブラウザで開く |
isv | gh issue list | fzf-tmux → gh issue view | Issue をfzfプレビュー付きで閲覧 |
prv | gh pr list | fzf-tmux → gh pr view | PR をfzfプレビュー付きで閲覧 |
brc | gh repo view --json url + git rev-parse HEAD | 現在のコミットのGitHub URLを生成 |
scorecard | GITHUB_AUTH_TOKEN=$(gh auth token) scorecard | OpenSSF Scorecardをgh認証で実行 |
ghq
設定ファイル: nix/modules/home/programs/gh.nix(パッケージ導入)
リポジトリをローカルに ~/ghq/<host>/<owner>/<repo> で統一管理。gh-auth-switchと連携してアカウント切り替えの基盤にもなっている。
ghq 関連のシェル関数・エイリアス
g — Git / ghq ハイブリッド
ファイル: zsh/functions/g.zsh
g → ghq list | peco でリポジトリ選択 → cd
g <args> → git <args>(引数があればgitに転送)
gh-q — GitHub リポジトリ検索 + clone
ファイル: zsh/functions/gh-q.zsh
GraphQL APIで全リポジトリをページネーション取得 → fzf選択:
gh-q → 自分のリポジトリをfzf選択 → ghq get → cd
gh-q <owner> → 指定ownerのリポジトリを選択
gh-q -o [owner] → 選択したリポジトリをブラウザで開く
その他
| コマンド | 説明 |
|---|---|
gg | ghq get(abbr) |
Jujutsu (jj)
設定ファイル: nix/modules/home/programs/jj.nix
Git互換の次世代VCS。
エイリアス
| alias | 展開 | 説明 |
|---|---|---|
pull | jj git fetch && jj rebase -d main | fetch + mainにrebase |
st | status | |
l | log -n 10 | 直近10件のログ |
fresh | new main | mainから新しいchangeを作成 |
revset エイリアス
trunk/trunk()→main@origin
Git シェルエイリアス(aliases.zsh)
| コマンド | 展開 | 説明 |
|---|---|---|
gundo | git reset --soft HEAD~1 | 直前のコミットをソフトリセット |
grepush | git recommit && git push -f | コミットやり直し + force push |
gsp | git stash && git pull && git stash pop | stash退避してpull |
gpgp | git pull && git push | pull→push連続実行 |
gpu | git pull |
パッケージ一覧
nix/modules/home/packages.nix で導入:
| パッケージ | 説明 |
|---|---|
git | Git本体 |
git-lfs | Large File Storage |
git-filter-repo | 履歴書き換えツール |
git-wt | worktree管理ヘルパー(wt.basedir, wt.remover 設定と連携) |
lazygit | TUI Git クライアント |
ghq | リポジトリのローカル統一管理 |
tea | Gitea CLI |
repo-creator(Claude Code コマンド)
設定ファイル: claude/commands/repo-creator.md
新規リポジトリの作成を OpenTofu + ghq + Nix flake で一気通貫に行う Claude Code コマンド(/repo-creator)。
実行フロー
1. プロジェクト情報の収集(名前, ツールチェーン, ライセンス, 可視性, 説明)
↓
2. homelab/tofu/github/repositories.tf に github_repository リソースを追加
↓
3. tofu apply でGitHubリポジトリを自動作成
↓
4. ghq get でローカルにclone → git pull origin main
↓
5. nix flake init -t github:the-nix-way/dev-templates#<toolchain> で開発環境テンプレート展開
↓
6. 新規リポに初期コミット & push
↓
7. homelab側のrepositories.tf変更もコミット & push
↓
8. サマリー出力(URL, ローカルパス, ツールチェーン, ライセンス)
対応ツールチェーン(45種)
| カテゴリ | ツールチェーン |
|---|---|
| Web/スクリプト | bun, node, typescript, python, ruby, php |
| システム | c, cpp, c-cpp, go, rust, swift, zig, nim |
| JVM | java, kotlin, scala, clojure |
| 関数型 | haskell, ocaml, purescript, gleam, lean4 |
| インフラ | hashi (Terraform/Consul), pulumi, nix |
| その他 | cue, dhall, jupyter, latex, nickel, opa, r, shell, typst 等 |
OpenTofu リソース定義例
resource "github_repository" "my_app" {
name = "my-app"
description = "My awesome project"
visibility = "public"
has_issues = true
has_projects = true
has_wiki = true
has_downloads = true
allow_merge_commit = true
allow_squash_merge = true
allow_rebase_merge = true
delete_branch_on_merge = true
license_template = "mit"
gitignore_template = "Go"
}統合エコシステム
- IaC管理:
homelab/tofu/github/repositories.tfで全GitHubリポジトリを宣言的管理 - ローカル管理: ghq で
~/ghq/<host>/<owner>/<repo>に統一配置 - 開発テンプレート:
the-nix-way/dev-templatesの Nix flake テンプレート - gh auth連動: ghqパスに基づく自動アカウント切り替え(前述)
PR Aftercare(Claude Code ルール)
設定ファイル: claude/rules/pr-aftercare.md
PR作成後のCI監視・レビュー対応をClaude Codeに自動化させるためのルール定義。
フロー全体像
PR作成
└→ CI監視(失敗 → 修正 → push → 再監視のループ)
└→ CI green
└→ レビュー待ち
└→ レビューコメント確認
├→ 即修正 → commit & push → スレッド解決
├→ 仕様トレードオフ → ユーザーに判断を仰ぐ → 解決
└→ レビュアーの誤解 → コメントで説明 → 解決
└→ CI再監視(失敗→修正ループ)
1. CI Watch
PR作成直後に gh pr checks --watch --fail-fast でCIを監視。失敗したらログを読んで原因特定→最小diffで修正→push→再監視。
2. Review Triage
GraphQL APIでレビュースレッドを取得し、各コメントを3カテゴリに分類:
| カテゴリ | 基準 | アクション |
|---|---|---|
| 即修正 | コードで対応可能、仕様影響なし | 修正してコミット |
| 仕様トレードオフ | 仕様変更やパフォーマンス/複雑性のトレードオフあり | 選択肢を整理してユーザーに確認 |
| 誤ったフィードバック | レビュアーの誤解 or 既に対応済み | コメントで説明 |
原則: 迷ったら修正する。 低コストな修正を議論するのは時間の無駄。
3. Resolve
修正をpush後、GraphQL mutationでレビュースレッドを一括解決。複数スレッドはエイリアスでバッチ処理:
mutation {
t1: resolveReviewThread(input: {threadId: "..."}) { thread { isResolved } }
t2: resolveReviewThread(input: {threadId: "..."}) { thread { isResolved } }
}解決前の確認事項: テスト通過、lint通過、変更がpush済み。
グローバル .gitignore 詳細
設定ファイル: nix/modules/home/programs/git.nix の programs.git.ignores
home-managerの programs.git.ignores で定義。全リポジトリに適用されるグローバルignoreルール。
カテゴリ別一覧
Environment
- `.venv`, `.direnv` — Python仮想環境 & direnv
macOS
- `.DS_Store`, `.AppleDouble`, `.LSOverride`, `Icon`, `._*` など
- Time Machine, Spotlight, Trash 関連ファイル一式
Python(網羅的)
- ビルド成果物: `build/`, `dist/`, `.egg-info/`, `.egg`, `*.so`
- キャッシュ: `pycache/`, `.mypy_cache/`, `.pytest_cache/`, `.cache`
- カバレッジ: `htmlcov/`, `.coverage`, `coverage.xml`
- 仮想環境: `.env`, `env/`, `venv/`, `ENV/`
- その他: `.tox/`, `.nox/`, `.hypothesis/`, `db.sqlite3`, `.ipynb_checkpoints` 等
Claude Code / AIエージェント
- `**/.claude/settings.local.json` — Claude Codeのローカル設定(個人のMCP設定等を含む)
- `**/CLAUDE.local.md` — ローカル専用のClaude Code指示ファイル
- `z-ai/` — AIエージェントの作業ディレクトリ(後述)
Continues
- `.continues-handoff.md` — Continue Dev のハンドオフファイル
z-ai/ ディレクトリについて
`z-ai/` はAIエージェント(Claude Code, Codex)がタスク管理や学習に使う一時作業ディレクトリ。各リポジトリのルートに作られるが、グローバル .gitignore でコミット対象外にしている。
用途
| ファイル | 用途 |
|---|---|
| `z-ai/todo.md` | タスク計画をチェックリスト形式で管理。完了時にレビューセクションも追加 |
| `z-ai/lessons.md` | ユーザーからの修正・指摘を学習パターンとして蓄積。同じミスを繰り返さないためのルール集 |
| `z-ai/screenshot.png` | agent-browser でのスクリーンショット保存先 |
ワークフロー
1. タスク開始 → z-ai/todo.md に計画を書く
2. 実装中 → 完了項目をチェック
3. ユーザーから修正 → z-ai/lessons.md にパターン記録
4. タスク完了 → z-ai/todo.md にレビューセクション追加
`z-ai/` は「名前の先頭が z なのでファイルツリーの一番下に来る」という命名規則。リポジトリの本体コードと混ざらないようにしている。