git-advanced について
複雑な履歴やブランチ操作を行う経験豊富なGitユーザー向けのガイダンススキルです。リベース、コミット編集、マージ、競合解決、ステージングなどを扱います。
主な機能
- 01インタラクティブリベースとコミットの並べ替え
- 02コミットのスカッシュ、分割、修正、編集
- 03高度なチェリーピックとマージ戦略
- 04競合解決と rerere
- 05部分ステージング、リセット、スタッシュ操作
- 06ブランチ、サブモジュール、履歴の管理
活用シーン
- 01共有前にローカルのコミット履歴を書き換える
- 02整理時にコミットを分割または統合する
- 03ブランチ間でコミットを適用して競合を解決する
- 04失われたコミットの復元や履歴の調査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ geoffjay/ claude-plugins --skill git-advancedインストール後、Claude Code で/git-advancedを入力して読み込まれたか確認します。
詳細
Git Advanced Operations Skill
このスキルでは、経験豊富な Git ユーザー向けに、高度な Git 操作、洗練されたリベース戦略、コミットを自在に編集する手法、複雑な履歴操作について包括的に説明します。
使用するタイミング
次の操作を行うときに、このスキルを有効にしてください:
- 複雑なインタラクティブリベースを行う
- コミット履歴を書き換える
- コミットを分割または結合する
- 高度なマージ戦略を使う
- ブランチをまたいでチェリーピックする
- 履歴内のコミットメッセージを編集する
- 作成者情報を変更する
- 複雑な競合を解決する
インタラクティブリベース戦略
基本的なインタラクティブリベース
# Rebase last 5 commits
git rebase -i HEAD~5
# Rebase from specific commit
git rebase -i abc123^
# Rebase entire branch
git rebase -i main
リベースコマンド
# Interactive rebase editor commands:
# p, pick = use commit
# r, reword = use commit, but edit commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like squash, but discard commit message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
コミットのスカッシュ
# Example: Squash last 3 commits
git rebase -i HEAD~3
# In editor:
pick abc123 feat: add user authentication
squash def456 fix: resolve login bug
squash ghi789 style: format code
# Squash all commits in feature branch
git rebase -i main
# Mark all except first as 'squash'
フィックスアップのワークフロー
# Create fixup commit automatically
git commit --fixup=abc123
# Autosquash during rebase
git rebase -i --autosquash main
# Set autosquash as default
git config --global rebase.autosquash true
# Example workflow:
git log --oneline -5
# abc123 feat: add authentication
# def456 feat: add authorization
git commit --fixup=abc123
git rebase -i --autosquash HEAD~3
コミットの並べ替え
# Interactive rebase
git rebase -i HEAD~5
# In editor, change order:
pick def456 feat: add database migration
pick abc123 feat: add user model
pick ghi789 feat: add API endpoints
# Reorder by moving lines:
pick abc123 feat: add user model
pick def456 feat: add database migration
pick ghi789 feat: add API endpoints
コミットの分割
# Start interactive rebase
git rebase -i HEAD~3
# Mark commit to split with 'edit'
edit abc123 feat: add user and role features
# When rebase stops:
git reset HEAD^
# Stage and commit parts separately
git add user.go
git commit -m "feat: add user management"
git add role.go
git commit -m "feat: add role management"
# Continue rebase
git rebase --continue
古いコミットの編集
# Start interactive rebase
git rebase -i HEAD~5
# Mark commit with 'edit'
edit abc123 feat: add authentication
# When rebase stops, make changes
git add modified-file.go
git commit --amend --no-edit
# Or change commit message
git commit --amend
# Continue rebase
git rebase --continue
コミットを自在に編集する
コミットの修正
# Amend last commit (add changes)
git add forgotten-file.go
git commit --amend --no-edit
# Amend commit message
git commit --amend -m "fix: correct typo in feature"
# Amend author information
git commit --amend --author="John Doe <[email protected]>"
# Amend date
git commit --amend --date="2024-03-15 10:30:00"
コミットメッセージの変更
# Change last commit message
git commit --amend
# Change older commit messages
git rebase -i HEAD~5
# Mark commits with 'reword'
# Change commit message without opening editor
git commit --amend -m "new message" --no-edit
複数の作成者の変更
# Filter-branch (legacy method, use filter-repo instead)
git filter-branch --env-filter '
if [ "$GIT_COMMITTER_EMAIL" = "[email protected]" ]; then
export GIT_COMMITTER_NAME="New Name"
export GIT_COMMITTER_EMAIL="[email protected]"
fi
if [ "$GIT_AUTHOR_EMAIL" = "[email protected]" ]; then
export GIT_AUTHOR_NAME="New Name"
export GIT_AUTHOR_EMAIL="[email protected]"
fi
' --tag-name-filter cat -- --branches --tags
# Modern method with git-filter-repo
git filter-repo --email-callback '
return email.replace(b"[email protected]", b"[email protected]")
'
履歴からのファイルの削除
# Remove file from all history
git filter-branch --tree-filter 'rm -f passwords.txt' HEAD
# Better performance with index-filter
git filter-branch --index-filter 'git rm --cached --ignore-unmatch passwords.txt' HEAD
# Modern method with git-filter-repo (recommended)
git filter-repo --path passwords.txt --invert-paths
# Remove large files
git filter-repo --strip-blobs-bigger-than 10M
BFG Repo-Cleaner
# Install BFG
# brew install bfg (macOS)
# apt-get install bfg (Ubuntu)
# Remove files by name
bfg --delete-files passwords.txt
# Remove large files
bfg --strip-blobs-bigger-than 50M
# Replace passwords in history
bfg --replace-text passwords.txt
# After BFG cleanup
git reflog expire --expire=now --all
git gc --prune=now --aggressive
高度なチェリーピック
基本的なチェリーピック
# Cherry-pick single commit
git cherry-pick abc123
# Cherry-pick multiple commits
git cherry-pick abc123 def456 ghi789
# Cherry-pick range of commits
git cherry-pick abc123..ghi789
# Cherry-pick without committing (stage only)
git cherry-pick -n abc123
競合を伴うチェリーピック
# When conflicts occur
git cherry-pick abc123
# CONFLICT: resolve conflicts
# After resolving conflicts
git add resolved-file.go
git cherry-pick --continue
# Or abort cherry-pick
git cherry-pick --abort
# Skip current commit
git cherry-pick --skip
チェリーピックのオプション
# Edit commit message during cherry-pick
git cherry-pick -e abc123
# Sign-off cherry-picked commit
git cherry-pick -s abc123
# Keep original author date
git cherry-pick --ff abc123
# Apply changes without commit attribution
git cherry-pick -n abc123
git commit --author="New Author <[email protected]>"
マージコミットのメインライン選択
# Cherry-pick merge commit (specify parent)
git cherry-pick -m 1 abc123
# -m 1 = use first parent (main branch)
# -m 2 = use second parent (merged branch)
# Example workflow:
git log --graph --oneline
# * abc123 Merge pull request #123
# |\
# | * def456 feat: feature commit
# * | ghi789 fix: main branch commit
# To cherry-pick the merge keeping main branch changes:
git cherry-pick -m 1 abc123
高度なマージ
マージ戦略
# Recursive merge (default)
git merge -s recursive branch-name
# Ours (keep our changes on conflict)
git merge -s ours branch-name
# Theirs (keep their changes on conflict)
git merge -s theirs branch-name
# Octopus (merge 3+ branches)
git merge -s octopus branch1 branch2 branch3
# Subtree merge
git merge -s subtree branch-name
マージ戦略のオプション
# Ours (resolve conflicts with our version)
git merge -X ours branch-name
# Theirs (resolve conflicts with their version)
git merge -X theirs branch-name
# Ignore whitespace
git merge -X ignore-space-change branch-name
git merge -X ignore-all-space branch-name
# Patience algorithm (better conflict detection)
git merge -X patience branch-name
# Renormalize line endings
git merge -X renormalize branch-name
三者間マージ
# Standard three-way merge
git merge feature-branch
# With custom merge message
git merge feature-branch -m "Merge feature: add authentication"
# No fast-forward (always create merge commit)
git merge --no-ff feature-branch
# Fast-forward only (fail if merge commit needed)
git merge --ff-only feature-branch
# Squash merge (combine all commits)
git merge --squash feature-branch
git commit -m "feat: add complete authentication system"
高度な競合解決
競合マーカーを理解する
<<<<<<< HEAD (Current Change)
int result = add(a, b);
=======
int sum = calculate(a, b);
>>>>>>> feature-branch (Incoming Change)
競合解決ツール
# Use mergetool
git mergetool
# Specify merge tool
git mergetool --tool=vimdiff
git mergetool --tool=meld
git mergetool --tool=kdiff3
# Configure default merge tool
git config --global merge.tool vimdiff
git config --global mergetool.vimdiff.cmd 'vimdiff "$LOCAL" "$MERGED" "$REMOTE"'
# Check out specific version
git checkout --ours file.go # Keep our version
git checkout --theirs file.go # Keep their version
git checkout --merge file.go # Recreate conflict markers
rerere(記録済みの解決策を再利用)
# Enable rerere
git config --global rerere.enabled true
# Rerere will automatically resolve previously seen conflicts
git merge feature-branch
# Conflict occurs and is resolved
git add file.go
git commit
# Later, same conflict:
git merge another-branch
# Rerere automatically applies previous resolution
# View rerere cache
git rerere status
git rerere diff
# Clear rerere cache
git rerere forget file.go
git rerere clear
インタラクティブなステージング
ファイルの一部をステージングする
# Interactive staging
git add -p file.go
# Patch commands:
# y - stage this hunk
# n - do not stage this hunk
# q - quit (do not stage this and remaining hunks)
# a - stage this and all remaining hunks
# d - do not stage this and all remaining hunks
# s - split the current hunk into smaller hunks
# e - manually edit the current hunk
インタラクティブな追加
# Interactive mode
git add -i
# Commands:
# 1: status - show paths with changes
# 2: update - stage paths
# 3: revert - unstage paths
# 4: add untracked - stage untracked files
# 5: patch - partial staging
# 6: diff - show staged changes
# 7: quit - exit
部分コミット
# Stage part of file interactively
git add -p file.go
# Create commit with partial changes
git commit -m "feat: add validation logic"
# Stage remaining changes
git add file.go
git commit -m "feat: add error handling"
高度なリセット操作
リセットモード
# Soft reset (keep changes staged)
git reset --soft HEAD~1
# Mixed reset (keep changes unstaged, default)
git reset --mixed HEAD~1
git reset HEAD~1
# Hard reset (discard all changes)
git reset --hard HEAD~1
# Reset to specific commit
git reset --hard abc123
リセットとリバートの違い
# Reset (rewrites history, use for local changes)
git reset --hard HEAD~3
# Revert (creates new commit, safe for shared history)
git revert HEAD
git revert HEAD~3
git revert abc123..def456
高度なブランチ操作
特定のコミットからブランチを作成する
# Create branch from commit
git branch new-branch abc123
git checkout new-branch
# Or in one command
git checkout -b new-branch abc123
# Create branch from remote commit
git checkout -b local-branch origin/remote-branch
孤立ブランチ
# Create orphan branch (no parent)
git checkout --orphan new-root
git rm -rf .
# Useful for gh-pages, documentation, etc.
echo "# Documentation" > README.md
git add README.md
git commit -m "docs: initialize documentation"
ブランチの追跡設定
# Set upstream branch
git branch -u origin/main
# Push and set upstream
git push -u origin feature-branch
# Change upstream
git branch -u origin/develop
# View tracking information
git branch -vv
高度なスタッシュ操作
特定のファイルをスタッシュする
# Stash specific files
git stash push -m "WIP: feature work" file1.go file2.go
# Stash with pathspec
git stash push -p
# Stash untracked files
git stash -u
# Stash including ignored files
git stash -a
スタッシュをブランチに移す
# Create branch from stash
git stash branch new-branch stash@{0}
# Creates new branch and applies stash
git stash branch feature-work
スタッシュの一部を適用する
# Apply specific files from stash
git checkout stash@{0} -- file.go
# Apply stash without dropping
git stash apply stash@{0}
# Apply and drop
git stash pop stash@{0}
サブモジュールの管理
高度なサブモジュール操作
# Update submodule to specific commit
cd submodule-dir
git checkout abc123
cd ..
git add submodule-dir
git commit -m "chore: update submodule to version 1.2.3"
# Update all submodules to latest
git submodule update --remote --merge
# Update specific submodule
git submodule update --remote --merge path/to/submodule
# Run command in all submodules
git submodule foreach 'git checkout main'
git submodule foreach 'git pull'
# Clone with submodules at specific depth
git clone --recurse-submodules --depth 1 repo-url
サブモジュールからサブツリーへの移行
# Remove submodule
git submodule deinit path/to/submodule
git rm path/to/submodule
rm -rf .git/modules/path/to/submodule
# Add as subtree
git subtree add --prefix=path/to/submodule \
https://github.com/user/repo.git main --squash
# Update subtree
git subtree pull --prefix=path/to/submodule \
https://github.com/user/repo.git main --squash
高度なログと履歴
ログのカスタム書式設定
# One-line format with custom fields
git log --pretty=format:"%h - %an, %ar : %s"
# Full custom format
git log --pretty=format:"%C(yellow)%h%C(reset) %C(blue)%ad%C(reset) %C(green)%an%C(reset) %s" --date=short
# Aliases for common formats
git config --global alias.lg "log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit --date=relative"
失われたコミットを見つける
# Find commits not in any branch
git log --all --oneline --no-walk --decorate $(git fsck --no-reflog | grep commit | cut -d' ' -f3)
# Find dangling commits
git fsck --lost-found
# Search commit messages
git log --all --grep="search term"
# Find commits by author
git log --author="John Doe"
# Find commits modifying specific code
git log -S "function_name"
git log -G "regex_pattern"
二分探索の自動化
# Start bisect
git bisect start
git bisect bad HEAD
git bisect good abc123
# Automate bisect with script
git bisect run ./test.sh
# test.sh example:
#!/bin/bash
make && make test
exit $?
# Bisect will automatically find first bad commit
ベストプラクティス
- 履歴を書き換える前にバックアップする: 複雑な操作の前にバックアップブランチを作成します
- 公開済みの履歴は決して書き換えない: 書き換えるのはローカルコミットのみにします
- リベースについてチームに伝える: 強制プッシュを行う際はチームに知らせます
- 内容がわかるコミットメッセージを使う: インタラクティブリベース中も同様です
- リベース後にテストする: 履歴の変更後もコードが動作することを確認します
- ローカルブランチではリベースを優先する: 履歴を直線的に保ちます
- 共有ブランチではマージを使う: 履歴全体を保持します
- 重要なコミットに署名する: リリースには GPG 署名を使います
- 複雑な操作を記録する: 後で参照できるようにコメントを残します
- やめどきを見極める: リベースした履歴よりもマージコミットのほうがわかりやすい場合もあります
リソース
追加のガイドや例は assets/ ディレクトリにあります:
examples/- 複雑なリベースとマージのシナリオscripts/- 一般的な操作を自動化するスクリプトworkflows/- 高度なワークフローのパターン
次の内容については references/ ディレクトリを参照してください:
- Git の内部構造に関するドキュメント
- 高度なリベース戦略
- filter-branch の代替手段
- 競合解決の手法
コメント
Markdown 対応