1 分で読了 #devops
このページの目次

Git 操作マニュアル

履歴と検索

deltagit diff の現代的な代替手段です。サイドバー、行番号、シンタックスハイライトを提供します。設定: git config --global pager.diff delta && git config --global pager.log delta

# コミット履歴
git log --oneline -20
git log --oneline --graph --all          # 全ブランチの可視化
git log -p <file>                        # 特定ファイルの変更差分
git log --since="2025-01-01" --until="2025-01-15"
git log --author="name" --oneline
git log -S "function_name"               # 特定コードの導入/削除を含むコミットを検索 (pickaxe)
git log -G "regex"                       # 同上、正規表現版

# 誰が変更したか
git blame <file> -L 40,60

# バグを導入したコミットを二分探索で特定
git bisect start
git bisect bad HEAD                      # 現在のバージョンに問題あり
git bisect good v1.0                     # v1.0 は問題なし
# → Git が中間バージョンをチェックアウト → テスト → git bisect good/bad → ... → 最初の bad commit を特定
git bisect reset                         # bisect を終了

# 失われたコミットを復元
git reflog                               # 全 HEAD 変更履歴 (30 日間)
git reflog show feature-branch           # 特定ブランチの reflog
# → リセット/ドロップされたコミットハッシュを見つける → git checkout -b recovery <hash>

ブランチとマージ

git branch                               # ローカルブランチ一覧
git branch -r                            # リモートブランチ一覧
git branch -a                            # 全ブランチ
git checkout -b feature                  # 作成して切り替え

# merge: ブランチ履歴を保持し、マージコミットを生成
git merge feature
# 用途: feature ブランチを main にマージし、「この機能は別々に開発された」という情報を保持

# rebase: 現在のブランチのコミットをターゲットブランチの後ろに移動し、線形履歴を作成
git rebase main
# 用途: PR 送信前に feature ブランチを main に合わせて、線形履歴を維持

# rebase 競合時の対応:
git rebase --continue                    # 競合を解決して続行
git rebase --skip                        # 現在のコミットをスキップ
git rebase --abort                       # rebase 全体をキャンセル

# cherry-pick: 他ブランチから単一コミットを取得
git cherry-pick <commit-hash>
# 用途: リリースブランチに特定のバグ修正のみをマージし、他の変更は含めない

# マージ済みブランチの削除
git branch --merged main | grep -v 'main' | xargs git branch -d

ストッシュと取り消し

# 現在の変更を一時退避 (ブランチ切り替え前)
git stash
git stash save "説明"
git stash list
git stash pop                            # 最新の stash を復元して削除
git stash apply stash@{1}                # 指定した stash を復元(削除しない)
git stash drop stash@{1}
git stash clear                          # 全 stash をクリア

# 取り消し
git reset --soft HEAD~1                  # 直近のコミットを取り消し、変更はステージに保持
git reset --mixed HEAD~1                 # 直近のコミットを取り消し、変更はワークツリーに保持(デフォルト)
git reset --hard HEAD~1                  # 直近のコミットを取り消し、全変更を破棄(元に戻せない!)
git checkout -- <file>                   # ステージ未登録の変更を破棄(元に戻せない)
git restore <file>                       # checkout -- と同等(新コマンド)
git restore --staged <file>              # add の取消し(ステージからワークツリーへ移動)

# push 済みコミットのリモートでの取り消し:
git revert <commit-hash>                 # 逆方向のコミットを作成(安全、履歴を変更しない)
# vs reset: revert は公開ブランチに適している(他人の履歴を壊さない)、reset はローカルブランチに適している

リモート

git remote -v
git remote add upstream https://github.com/original/repo.git
git fetch upstream                       # 全リモートブランチを取得(マージしない)
git fetch --prune                        # リモートに存在しなくなったローカル参照も同時に削除
git pull --rebase                        # fetch + rebase(推奨、意味のないマージコミットを回避)

# 安全な force push: リモートが他人によって変更されていない場合にのみプッシュ
git push --force-with-lease
# --force より安全: 最後の fetch 以降に同僚が push した場合、これを拒否し、上書きを防ぐ

Submodule

git submodule update --init --recursive  # 初回 clone 後に全サブモジュールを取得
git submodule update --remote            # サブモジュールを各自の最新コミットに更新
git submodule foreach git pull origin main

Worktree

# 同一リポジトリの異なるディレクトリで異なるブランチをチェックアウト(2回 clone 不要)
git worktree add ../hotfix hotfix-branch
# → ../hotfix ディレクトリは hotfix-branch のワークツリーであり、現在のディレクトリに影響を与えない

git worktree list
git worktree remove ../hotfix
# 用途: 長時間のテストを実行中に、別のブランチでバグ修正を行う

Tag

git tag v1.0.0                           # ライトタグ
git tag -a v1.0.0 -m "Release v1.0.0"    # アノテーション付きタグ(推奨)
git tag -d v1.0.0                        # ローカルタグを削除
git push origin v1.0.0                   # 単一タグをプッシュ
git push --tags                          # 全タグをプッシュ