- Published on
Git Mastery: Advanced Workflows Every Developer Needs — From Junior to Senior
- Authors

- Name
- Youngju Kim
- @fjvbn20031
- Introduction
- 1. Understanding Git Internals — Objects, DAG, and the .git Directory
- 2. Branching Strategies — Choosing the Right Workflow for Your Team
- 3. The Rebase Master Class
- 4. 20 Real-World Scenarios — Problem-Solving Recipes
- Scenario 1: Wrong Commit Message
- Scenario 2: Committed to the Wrong Branch
- Scenario 3: Undoing After Push — revert vs reset
- Scenario 4: Merge Conflict Resolution Strategies
- Scenario 5: Bug Tracking with git bisect
- Scenario 6: Accidentally Committed a Large File
- Scenario 7: Staging Parts of a File — git add -p
- Scenario 8: Urgent Hotfix While Working — stash + worktree
- Scenario 9: Squashing Multiple Commits into One
- Scenario 10: Submodule Management
- Scenario 11: Recover a Deleted Branch
- Scenario 12: Checkout a Specific File from Another Branch
- Scenario 13: Changing Commit Dates
- Scenario 14: Code Tracking with git blame
- Scenario 15: Advanced git log
- Scenario 16: Managing Multiple Remotes
- Scenario 17: Release Management with Tags
- Scenario 18: Automation with Git Hooks
- Scenario 19: Creating and Applying Patches
- Scenario 20: git reflog — The Last Resort
- 5. Conventional Commits + Semantic Versioning
- 6. GitHub Actions CI/CD
- 7. Monorepo Strategies
- 8. Git Performance Optimization
- 9. AI + Git (2025-2026)
- Knowledge Check Quiz
- References
- Conclusion
Introduction
Git is every developer's daily companion. Yet most developers only use git add, git commit, git push and barely tap into 10% of what Git offers. This guide covers everything from Git internals to advanced workflows that you can apply immediately in your day-to-day work, whether you are a junior or a senior engineer.
Have you ever received code review feedback saying "please clean up this commit history"? Have you ever panicked when a merge conflict appeared? By the end of this article, you will handle those situations with confidence.
1. Understanding Git Internals — Objects, DAG, and the .git Directory
To truly master Git, you need to understand how it works under the hood. Git is not just a version control tool; it is a sophisticated system built on top of a content-addressable filesystem.
1.1 The Four Git Objects
There are four core object types inside Git.
Blob (Binary Large Object): Stores file contents. It does not include the filename or path — only the raw content.
# Check the hash of file contents
echo "Hello, Git!" | git hash-object --stdin
# Result: e.g. af5626b4a114abcb82d63db7c8082c3c4756e51b
# Verify the object type
git cat-file -t af5626b
# Result: blob
# View the content
git cat-file -p af5626b
# Result: Hello, Git!
Tree: Represents a directory structure. It references blobs and other trees to build a snapshot of the filesystem.
# Inspect the tree of the latest commit
git cat-file -p HEAD^{tree}
# 100644 blob a906cb2a4a904a15... README.md
# 040000 tree 99f1a6d12cb4b6f1... src
# 100644 blob 47c6340d6459e058... package.json
Commit: A snapshot at a point in time. It points to a tree object and includes the author, commit message, and parent commit references.
# Inspect a commit's internals
git cat-file -p HEAD
# tree 99f1a6d12cb4b6f19c8655fca46c3ecf317074e0
# parent 8bd3ad5e1234567890abcdef1234567890abcdef
# author John Doe <john@example.com> 1711100000 +0900
# committer John Doe <john@example.com> 1711100000 +0900
#
# feat: add user authentication
Tag: A named reference to a specific commit. Used for release version management.
# Create an annotated tag
git tag -a v1.0.0 -m "Release version 1.0.0"
# Inspect the tag object
git cat-file -p v1.0.0
1.2 SHA-1 Hashing and Content Addressing
Git identifies every object by its SHA-1 hash. Identical content always produces the same hash, which naturally prevents duplicate storage.
# Same content = same hash
echo "same content" | git hash-object --stdin
echo "same content" | git hash-object --stdin
# Both results are identical
The implication is significant: even if 100 branches contain the same file, Git stores it only once.
1.3 DAG (Directed Acyclic Graph) — The Commit Graph
Git's commit history forms a DAG (Directed Acyclic Graph). Each commit points to its parent(s), and no cycles exist.
A---B---C---D (main)
\
E---F---G (feature)
\
H---I (hotfix)
Understanding this structure makes merge, rebase, and cherry-pick operations intuitive.
# View the log as a graph
git log --oneline --graph --all --decorate
# Cleaner output
git log --oneline --graph --all --format="%h %s (%ar)"
1.4 Anatomy of the .git Directory
.git/
HEAD # Pointer to the current branch
config # Repository-specific settings
refs/
heads/ # Local branches (each file = a commit hash)
tags/ # Tags
remotes/ # Remote branch tracking
objects/ # All Git objects (blob, tree, commit, tag)
pack/ # Compressed object pack files
hooks/ # Git hook scripts
index # Staging area (binary)
# Check what HEAD points to
cat .git/HEAD
# ref: refs/heads/main
# See the commit that main points to
cat .git/refs/heads/main
# a1b2c3d4e5f6...
# Check object store size
git count-objects -vH
2. Branching Strategies — Choosing the Right Workflow for Your Team
2.1 Git Flow
A traditional branching model proposed by Vincent Driessen in 2010.
main ─────────────────────────────── (production)
│
└── develop ────────────────────── (development integration)
│ │
│ feature/login ────────── (feature development)
│
└── release/1.0 ──────────── (release preparation)
│
└── hotfix/bug-123 ──── (emergency fix)
Pros: Clear release management, production stability guaranteed Cons: Too many branches, frequent merge conflicts, poor fit with CI/CD
# Initialize Git Flow (git-flow extension)
git flow init
# Start feature development
git flow feature start user-auth
# Complete feature development
git flow feature finish user-auth
2.2 GitHub Flow
A simple branching model used by GitHub.
main ────────────────────────────────
│ │
└── feature ───┘ (PR + merge)
Rule: main is always deployable. Work on feature branches, merge via PR.
# 1. Create a branch
git checkout -b feature/add-search
# 2. Work and commit
git add .
git commit -m "feat: add search functionality"
# 3. Push
git push -u origin feature/add-search
# 4. Create PR (GitHub CLI)
gh pr create --title "Add search functionality" --body "..."
# 5. Merge after review
gh pr merge --squash
2.3 Trunk-Based Development
Used by large-scale teams at Google, Meta, and others. All developers integrate frequently into main (the trunk), either directly or through very short-lived branches.
main ──A──B──C──D──E──F──G──H──I──
\─/ \─/
(1-2 days)(1-2 days)
Core principles:
- Branch lifespan is at most 1-2 days
- Integrate into main multiple times per day
- Feature flags manage incomplete features
- A robust CI/CD pipeline is mandatory
2.4 Strategy Comparison
| Aspect | Git Flow | GitHub Flow | Trunk-Based |
|---|---|---|---|
| Complexity | High | Low | Medium |
| Branch lifespan | Long (weeks-months) | Medium (days-weeks) | Short (hours-days) |
| Release cadence | Scheduled releases | On-demand deploys | Continuous deployment |
| Team size | 10+ people | 2-15 people | Any size |
| CI/CD dependency | Low | Medium | High |
| Recommended for | Mobile apps, packages | SaaS, web apps | Large organizations |
2.5 Branch Naming Conventions
# Feature development
feature/JIRA-123-add-login
feature/user-profile-page
# Bug fixes
bugfix/JIRA-456-fix-null-pointer
fix/login-redirect-loop
# Hotfixes
hotfix/security-patch-xss
hotfix/v1.2.1
# Releases
release/1.0.0
release/2026-q1
# Experimental / maintenance
experiment/new-search-algo
chore/update-dependencies
3. The Rebase Master Class
3.1 Rebase vs Merge — When to Use Which
Merge: Preserves the history of both branches while combining them.
git checkout main
git merge feature/login
# A merge commit is created
A---B---C---D---M (main, merge commit M)
\ /
E---F---G (feature)
Rebase: Replays commits on top of a different base.
git checkout feature/login
git rebase main
# Feature commits are replayed on top of main
A---B---C---D (main)
\
E'---F'---G' (feature, replayed)
3.2 Interactive Rebase — The Complete Guide
# Interactively edit the last 5 commits
git rebase -i HEAD~5
Your editor will open with something like this:
pick a1b2c3d feat: add user model
pick d4e5f6g fix: typo in user model
pick h7i8j9k feat: add user controller
pick l0m1n2o WIP: debugging
pick p3q4r5s feat: add user routes
Available commands:
| Command | Shorthand | Description |
|---|---|---|
| pick | p | Use the commit as-is |
| reword | r | Change the commit message only |
| edit | e | Modify the commit (can change files) |
| squash | s | Merge with previous commit, edit message |
| fixup | f | Merge with previous commit, discard message |
| drop | d | Remove the commit |
Real-world example — cleaning up messy history:
pick a1b2c3d feat: add user model
fixup d4e5f6g fix: typo in user model
pick h7i8j9k feat: add user controller
drop l0m1n2o WIP: debugging
pick p3q4r5s feat: add user routes
Result: 5 commits become 3 clean commits.
3.3 The Autosquash Workflow
Using the fixup! prefix allows automatic cleanup.
# Original commit
git commit -m "feat: add user model"
# Later, when a fix is needed
git commit --fixup HEAD
# Or target a specific commit
git commit --fixup a1b2c3d
# Automatic cleanup
git rebase -i --autosquash main
3.4 The Golden Rule of Rebase
Never rebase shared branches (main, develop). Rebase changes commit hashes, which causes conflicts with everyone else's local repositories.
# Safe rebase (personal feature branch)
git checkout feature/my-task
git rebase main
# Dangerous rebase (never do this!)
git checkout main
git rebase feature/something # Forbidden!
4. 20 Real-World Scenarios — Problem-Solving Recipes
Scenario 1: Wrong Commit Message
# Fix the most recent commit message (not yet pushed)
git commit --amend -m "feat: add user authentication"
# Open editor to edit message
git commit --amend
Scenario 2: Committed to the Wrong Branch
# Situation: committed to feature branch instead of main
# Method 1: cherry-pick
git checkout main
git cherry-pick abc1234
git checkout feature/wrong-branch
git reset --hard HEAD~1
# Method 2: stash
git reset --soft HEAD~1
git stash
git checkout correct-branch
git stash pop
git commit -m "correct commit message"
Scenario 3: Undoing After Push — revert vs reset
# Safe method: revert (creates a new commit, preserves history)
git revert abc1234
git push
# Dangerous method: reset + force push (rewrites history)
git reset --hard HEAD~1
git push --force-with-lease
# force-with-lease protects against overwriting others' commits
revert vs reset comparison:
| Aspect | revert | reset |
|---|---|---|
| History | Preserved (new commit added) | Rewritten (commits removed) |
| Safety | Safe | Dangerous |
| Shared branches | OK to use | Do not use |
| Undoing | Can revert the revert | Recovery via reflog only |
Scenario 4: Merge Conflict Resolution Strategies
# When a conflict occurs
git merge feature/login
# CONFLICT (content): Merge conflict in src/auth.js
# Check conflicted files
git status
# Conflict marker structure
# <<<<<<< HEAD
# Code from current branch
# =======
# Code from the merging branch
# >>>>>>> feature/login
# After manual resolution
git add src/auth.js
git commit -m "resolve merge conflict in auth module"
Strategies for minimizing merge conflicts:
# 1. Sync with main frequently
git fetch origin
git rebase origin/main
# 2. Commit and merge in small increments
# 3. Establish clear file ownership (CODEOWNERS)
# 4. Configure merge tools
git config --global merge.tool vimdiff
git mergetool
Scenario 5: Bug Tracking with git bisect
# Start bisect
git bisect start
# Mark current state as bad (has bug)
git bisect bad
# Mark a known good commit
git bisect good v1.0.0
# Git checks out a middle commit — test and decide
git bisect good # or git bisect bad
# Repeat until the exact bad commit is found
# Result: abc1234 is the first bad commit
# End bisect
git bisect reset
Automated bisect with test scripts:
# Test script failure = bad, success = good
git bisect start HEAD v1.0.0
git bisect run npm test
# Automatically finds the bug-introducing commit!
Scenario 6: Accidentally Committed a Large File
# Method 1: git-filter-repo (recommended)
pip install git-filter-repo
git filter-repo --path large-file.zip --invert-paths
# Method 2: BFG Repo-Cleaner
java -jar bfg.jar --delete-files large-file.zip
git reflog expire --expire=now --all
git gc --prune=now --aggressive
# Prevention: .gitignore
echo "*.zip" >> .gitignore
echo "*.tar.gz" >> .gitignore
echo "node_modules/" >> .gitignore
Scenario 7: Staging Parts of a File — git add -p
# Selectively stage changes by hunk
git add -p src/utils.js
# For each hunk:
# y - stage this hunk
# n - skip this hunk
# s - split into smaller hunks
# e - manually edit
# q - quit
Scenario 8: Urgent Hotfix While Working — stash + worktree
# Method 1: stash
git stash push -m "WIP: feature work"
git checkout main
git checkout -b hotfix/critical-bug
# Work on the hotfix...
git checkout feature/my-work
git stash pop
# Method 2: worktree (the better approach!)
git worktree add ../hotfix-workspace main
cd ../hotfix-workspace
git checkout -b hotfix/critical-bug
# Work on the hotfix...
cd ../main-workspace
git worktree remove ../hotfix-workspace
Scenario 9: Squashing Multiple Commits into One
# Method 1: interactive rebase
git rebase -i HEAD~4
# Change first to pick, rest to squash
# Method 2: soft reset
git reset --soft HEAD~4
git commit -m "feat: complete user authentication"
# Method 3: merge --squash
git checkout main
git merge --squash feature/user-auth
git commit -m "feat: add user authentication system"
Scenario 10: Submodule Management
# Add a submodule
git submodule add https://github.com/org/shared-lib.git libs/shared
# Clone with submodules
git clone --recurse-submodules https://github.com/org/project.git
# Update submodules
git submodule update --remote --merge
# Run command across all submodules
git submodule foreach 'git checkout main && git pull'
Scenario 11: Recover a Deleted Branch
# Find the last commit of the deleted branch in reflog
git reflog
# abc1234 HEAD@{5}: checkout: moving from deleted-branch to main
# Recover the branch
git checkout -b recovered-branch abc1234
Scenario 12: Checkout a Specific File from Another Branch
# Get a specific file from the main branch
git checkout main -- src/config.js
# Get a file from a specific commit
git checkout abc1234 -- src/config.js
Scenario 13: Changing Commit Dates
# Change the last commit date to now
GIT_COMMITTER_DATE="$(date)" git commit --amend --date="$(date)"
# Set a specific date (during rebase)
GIT_COMMITTER_DATE="2026-03-22T10:00:00" git commit --amend --date="2026-03-22T10:00:00"
Scenario 14: Code Tracking with git blame
# See who last modified each line
git blame src/auth.js
# Check a specific line range
git blame -L 10,20 src/auth.js
# Ignore whitespace changes
git blame -w src/auth.js
# Track code movement
git blame -M src/auth.js
git blame -C src/auth.js
Scenario 15: Advanced git log
# File change history (follows renames)
git log --follow -p -- src/auth.js
# Find commits that added/removed a specific string (pickaxe)
git log -S "API_KEY" --oneline
# Filter by author
git log --author="John" --oneline --since="2026-01-01"
# Include statistics
git log --stat --oneline -10
# Diff between commits
git log -p --oneline -3
Scenario 16: Managing Multiple Remotes
# Add multiple remotes
git remote add upstream https://github.com/original/repo.git
git remote add deploy git@deploy-server:app.git
# Sync with upstream (forked project)
git fetch upstream
git rebase upstream/main
# Clean up remote branches
git remote prune origin
git fetch --prune
Scenario 17: Release Management with Tags
# Create an annotated tag
git tag -a v2.0.0 -m "Release 2.0.0: new payment system"
# Tag a specific commit
git tag -a v1.5.0 abc1234 -m "Hotfix release"
# Push tags
git push origin v2.0.0
git push origin --tags
# Delete a tag
git tag -d v2.0.0-beta
git push origin --delete v2.0.0-beta
Scenario 18: Automation with Git Hooks
# .husky/pre-commit
#!/bin/sh
npx lint-staged
# .husky/commit-msg
#!/bin/sh
npx commitlint --edit "$1"
# .husky/pre-push
#!/bin/sh
npm test
Scenario 19: Creating and Applying Patches
# Create a patch
git diff > my-changes.patch
git format-patch -3 # Create patch files from the last 3 commits
# Apply a patch
git apply my-changes.patch
git am *.patch # Apply patches created by format-patch
Scenario 20: git reflog — The Last Resort
# View the reflog (HEAD movement history)
git reflog
# Recover after an accidental reset --hard
git reflog
# abc1234 HEAD@{2}: commit: important work
git reset --hard abc1234
# Recover an accidentally dropped stash
git fsck --unreachable | grep commit
git stash apply abc1234
5. Conventional Commits + Semantic Versioning
5.1 Conventional Commits Format
type(scope): description
[optional body]
[optional footer(s)]
Type reference:
| Type | Description | Example |
|---|---|---|
| feat | New feature | feat: add login page |
| fix | Bug fix | fix: resolve null pointer in auth |
| docs | Documentation | docs: update API documentation |
| style | Code style (formatting, etc.) | style: fix indentation |
| refactor | Refactoring | refactor: extract auth middleware |
| perf | Performance improvement | perf: optimize database queries |
| test | Adding/modifying tests | test: add unit tests for auth |
| build | Build system changes | build: update webpack config |
| ci | CI configuration | ci: add GitHub Actions workflow |
| chore | Miscellaneous tasks | chore: update dependencies |
Breaking Change notation:
feat(api)!: change authentication endpoint
BREAKING CHANGE: /auth/login is now /api/v2/auth/login
5.2 Commitlint + Husky Setup
# Install packages
npm install -D @commitlint/cli @commitlint/config-conventional husky
# Configure commitlint
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
# Initialize Husky
npx husky init
echo 'npx commitlint --edit "$1"' > .husky/commit-msg
5.3 Automated Changelog Generation
# Install conventional-changelog
npm install -D conventional-changelog-cli
# Generate CHANGELOG.md
npx conventional-changelog -p angular -i CHANGELOG.md -s
{
"scripts": {
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"release": "standard-version"
}
}
5.4 Semantic Release — Full Automation
npm install -D semantic-release
{
"release": {
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
"@semantic-release/npm",
"@semantic-release/github",
"@semantic-release/git"
]
}
}
Versions are determined automatically based on commit types:
fix:-> PATCH (1.0.0 -> 1.0.1)feat:-> MINOR (1.0.0 -> 1.1.0)BREAKING CHANGE-> MAJOR (1.0.0 -> 2.0.0)
6. GitHub Actions CI/CD
6.1 Basic Workflow
name: CI Pipeline
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [18, 20, 22]
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'
- run: npm ci
- run: npm run lint
- run: npm test
- run: npm run build
6.2 PR Check Workflow
name: PR Checks
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
lint-and-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
cache: 'npm'
- run: npm ci
- name: Lint
run: npm run lint
- name: Type Check
run: npx tsc --noEmit
- name: Unit Tests
run: npm test -- --coverage
- name: Build
run: npm run build
- name: Upload coverage
uses: codecov/codecov-action@v4
with:
file: ./coverage/lcov.info
6.3 Auto-Labeling
name: Auto Label
on:
pull_request:
types: [opened, edited]
jobs:
label:
runs-on: ubuntu-latest
steps:
- uses: actions/labeler@v5
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# .github/labeler.yml
frontend:
- changed-files:
- any-glob-to-any-file: 'src/components/**'
backend:
- changed-files:
- any-glob-to-any-file: 'src/api/**'
documentation:
- changed-files:
- any-glob-to-any-file: 'docs/**'
tests:
- changed-files:
- any-glob-to-any-file: '**/*.test.*'
6.4 Dependabot Configuration
# .github/dependabot.yml
version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
day: 'monday'
open-pull-requests-limit: 10
labels:
- 'dependencies'
groups:
dev-dependencies:
dependency-type: 'development'
production-dependencies:
dependency-type: 'production'
- package-ecosystem: 'github-actions'
directory: '/'
schedule:
interval: 'weekly'
6.5 Deployment Workflow
name: Deploy
on:
push:
tags:
- 'v*'
jobs:
deploy:
runs-on: ubuntu-latest
environment: production
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- run: npm run build
- name: Deploy to Production
run: |
echo "Deploying version $GITHUB_REF_NAME"
# Actual deployment commands here
7. Monorepo Strategies
7.1 Monorepo vs Multirepo
| Aspect | Monorepo | Multirepo |
|---|---|---|
| Code sharing | Easy | Requires package publishing |
| Dependency management | Unified | Individual |
| CI/CD | Complex (selective builds) | Simple (per repository) |
| Code review | Full context available | Distributed across repos |
| Permission management | Complex | Per-repository settings |
| Notable users | Google, Meta, Microsoft | Netflix, Spotify |
7.2 Tool Comparison — Nx vs Turborepo vs Lerna
# Initialize Nx
npx create-nx-workspace@latest my-workspace
# Initialize Turborepo
npx create-turbo@latest
# Example project structure
my-monorepo/
apps/
web/ # Next.js web app
mobile/ # React Native app
api/ # Express API server
packages/
ui/ # Shared UI components
utils/ # Shared utilities
config/ # Shared configuration
turbo.json
package.json
7.3 CODEOWNERS Configuration
# .github/CODEOWNERS
# Default reviewers for the entire project
* @team-lead
# Frontend
/apps/web/ @frontend-team
/packages/ui/ @frontend-team
# Backend
/apps/api/ @backend-team
/packages/utils/ @backend-team
# DevOps
/.github/ @devops-team
/docker/ @devops-team
*.yml @devops-team
7.4 Selective Builds and Tests
{
"pipeline": {
"build": {
"dependsOn": ["^build"],
"outputs": ["dist/**"]
},
"test": {
"dependsOn": ["build"]
},
"lint": {}
}
}
# Build only changed packages
npx turbo run build --filter=...[HEAD^1]
# Build a specific app
npx turbo run build --filter=web
# Build including dependencies
npx turbo run build --filter=web...
8. Git Performance Optimization
8.1 Shallow Clone
# Clone only the latest commit (useful for CI/CD)
git clone --depth 1 https://github.com/org/repo.git
# Fetch full history later if needed
git fetch --unshallow
8.2 Partial Clone
# Clone without blobs (downloaded on demand)
git clone --filter=blob:none https://github.com/org/repo.git
# Exclude trees as well (fastest clone)
git clone --filter=tree:0 https://github.com/org/repo.git
8.3 Sparse Checkout
# Enable sparse checkout
git sparse-checkout init --cone
# Checkout specific directories only
git sparse-checkout set apps/web packages/ui
# Add another directory
git sparse-checkout add apps/api
# Check current configuration
git sparse-checkout list
8.4 Git LFS (Large File Storage)
# Install and initialize Git LFS
git lfs install
# Track large files
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "assets/videos/*"
# Check .gitattributes
cat .gitattributes
# *.psd filter=lfs diff=lfs merge=lfs -text
# Check LFS status
git lfs ls-files
git lfs status
8.5 Git Maintenance (Automated Housekeeping)
# Enable automatic maintenance
git maintenance start
# Manual garbage collection
git gc --aggressive
# Check object compression status
git count-objects -vH
# Clean up stale references
git remote prune origin
git reflog expire --expire=30.days
8.6 Scalar — Managing Massive Repositories (Microsoft)
# Register with Scalar (included in Git 2.38+)
scalar register
# Or clone fresh
scalar clone https://github.com/org/massive-repo.git
# Scalar automatically configures:
# - Partial clone
# - Sparse checkout
# - Background maintenance
# - Filesystem monitor
# - Commit graph
9. AI + Git (2025-2026)
9.1 AI Commit Message Generation
# Auto-generate commit messages with Claude Code
claude commit
# GitHub Copilot CLI
gh copilot suggest "write a commit message for these changes"
# aicommits tool
npm install -g aicommits
aicommits
9.2 AI Code Review
GitHub Copilot for Pull Requests automatically analyzes PRs and generates review comments. It identifies potential bugs, performance issues, and security vulnerabilities.
# Enable GitHub Copilot auto-review (in repository settings)
# Settings > Code review > Copilot code review > Enable
9.3 Claude Code and Git Workflows
Claude Code directly assists with Git operations.
# Request a review of staged changes
claude "review my staged changes"
# Write a commit message
claude "write a conventional commit message for my changes"
# Generate a PR description
claude "write a PR description for the current branch"
# Resolve merge conflicts
claude "help me resolve the merge conflicts in src/auth.js"
9.4 Automated PR Descriptions
name: Auto PR Description
on:
pull_request:
types: [opened]
jobs:
describe:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Generate PR description
uses: anthropics/claude-code-action@v1
with:
prompt: |
Analyze the diff of this PR and generate a clear description
including what changed, why, and any risks.
Knowledge Check Quiz
Quiz 1: Git Objects
Q: In which object are filenames stored — Blob or Tree?
A: Filenames are stored in the Tree object.
Blobs store only the raw file contents. Filenames and path information are managed by Tree objects. This design means that even if a file is renamed, Git can reuse the same blob as long as the content is unchanged.
# See filenames in a tree object
git cat-file -p HEAD^{tree}
# 100644 blob a906cb... README.md <-- Filename lives in the Tree!
Quiz 2: Rebase Safety
Q: Which of the following is a safe rebase operation? (A: rebase feature on main, B: rebase main on feature, C: Both)
A: B is safe.
The golden rule of rebase is "never rebase shared branches." main is a shared branch, so rebasing on main is dangerous. However, feature is a personal branch, so replaying its commits on top of the latest main is safe.
Quiz 3: Reset Modes
Q: What are the differences between the three reset modes (--soft, --mixed, --hard)?
A:
--soft: Moves HEAD only. Staging area and working directory are untouched. Use when you just want to undo a commit.--mixed(default): Moves HEAD + resets staging area. Working directory is untouched. Use when you want to undo a commit and unstage.--hard: Moves HEAD + resets staging area + resets working directory. All changes are discarded. (Dangerous!)
# Example: undo the last 3 commits but keep the code
git reset --soft HEAD~3
# Changes are now staged and ready to be recommitted
Quiz 4: Cherry-pick Conflicts
Q: How do you resolve a conflict during cherry-pick?
A: Resolve it the same way as a merge conflict.
git cherry-pick abc1234
# CONFLICT occurs
# 1. Fix the conflicted file
# 2. Stage it
git add resolved-file.js
# 3. Continue cherry-pick
git cherry-pick --continue
# Or abort the cherry-pick
git cherry-pick --abort
Quiz 5: Selective CI in a Monorepo
Q: In a monorepo, if only frontend code changed, should you also run backend tests?
A: It depends on dependencies.
If the frontend does not depend on any backend packages, there is no need to run backend tests. This is the core value of "affected analysis" provided by tools like Nx and Turborepo.
# Nx: test only projects affected by changes
npx nx affected --target=test
# Turborepo: build only changed packages and dependents
npx turbo run build --filter=...[HEAD^1]
However, if a shared package (utils, config, etc.) was modified, you must test all projects that depend on it.
References
Official Documentation
- Git Official Docs — The definitive reference
- GitHub Docs — GitHub feature guides
- Pro Git Book — Free online book
Branching Strategies
- Trunk Based Development — Official TBD site
- GitHub Flow Guide
- A successful Git branching model — Original Git Flow article
CI/CD
- GitHub Actions Docs
- Semantic Release — Automated versioning
- Conventional Commits — Commit conventions
Monorepo
- Nx Docs
- Turborepo Docs
- Monorepo Tools — Tool comparison
Performance
- Git LFS — Large file management
- Scalar — Massive repositories
- git-filter-repo — History cleanup
Deep Dives
- Oh Shit, Git!?! — Git mistake recovery guide
- Learn Git Branching — Visual Git learning
- Git Internals (PDF) — Git internal architecture
Conclusion
Git is not just a tool — it is core infrastructure that shapes development culture. A clean commit history reflects a team's collaboration capability, and an effective branching strategy determines deployment stability.
You do not need to learn everything in this article at once. Start by understanding the principles behind commands you use daily, then gradually adopt more advanced techniques. Interactive rebase and bisect, in particular, are tools that dramatically boost productivity once you learn them.
Remember: a good commit history is a letter to your future self and your colleagues. Why not start with Conventional Commits today?