DevOps

Git Advanced

Master advanced Git: rebase vs merge, interactive rebase, Git hooks, and best practices for GitHub/GitLab workflows.

By TechCoder TeamLast updated: 2026-06-02
In a Nutshell

Master advanced Git: rebase vs merge, interactive rebase, Git hooks, and best practices for GitHub/GitLab workflows. This hands-on tutorial focuses on practical implementation of git advanced concepts.

Git Advanced

Building on Git basics, let's explore advanced workflows including rebase, interactive rebase, hooks, and collaboration on GitHub/GitLab.

Rebase vs Merge

Understanding the Difference

Merge: Combines two branches by creating a merge commit, preserving history.

Before:              After Merge:
main:   A---B        main:   A---B---D---E
           ↑                      ↗
develop:   C---D      develop:   C---D---E (merge commit)

Rebase: Moves commits to the tip of another branch, creating linear history.

Before:              After Rebase:
main:   A---B        main:   A---B
           ↑                      ↓
develop:   C---D      develop:       C'---D' (replayed commits)

When to Use Each

ScenarioUseWhy
Feature to mainMergePreserves context
Local cleanupRebaseClean history
Before PRRebaseEasy review
Shared branchMergeAvoids conflicts
HotfixMergeClear traceability

Rebase Commands

# Basic rebase
git checkout feature
git rebase main

# Interactive rebase
git rebase -i HEAD~3

# Continue after resolving conflicts
git rebase --continue

# Skip current commit
git rebase --skip

# Abort rebase
git rebase --abort

# Rebase onto specific commit
git rebase --onto newbase upstream branch

Pull with Rebase

# Configure pull to use rebase
git config --global pull.rebase true

# Pull with rebase (one-time)
git pull --rebase origin main

# Pull with merge (override)
git pull --no-rebase origin main

Interactive Rebase

Powerful History Rewriting

# Interactive rebase last 3 commits
git rebase -i HEAD~3

# Interactive rebase from specific commit
git rebase -i abc1234

Interactive Commands

pick abc1234 First commit
reword def5678 Second commit (edit message)
squash ghi9012 Third commit (combine with previous)
fixup jkl3456 Fourth commit (combine, discard message)
drop mno7890 Fifth commit (remove)
edit pqr1234 Sixth commit (pause to edit)
reorder commits by moving lines

Common Interactive Patterns

# Change commit message
git rebase -i HEAD~1
# Change 'pick' to 'reword'

# Combine last 3 commits
git rebase -i HEAD~3
# Change last 2 'pick' to 'squash'

# Remove a commit
git rebase -i HEAD~5
# Change 'pick' to 'drop' for unwanted commit

# Split a commit
git rebase -i HEAD~3
# Change to 'edit', then:
git reset HEAD^
git add -p
git commit -m "Part 1"
git add .
git commit -m "Part 2"
git rebase --continue

Cherry-Pick

Selective Commit Application

# Cherry-pick single commit
git cherry-pick abc1234

# Cherry-pick without committing
git cherry-pick -n abc1234

# Cherry-pick multiple commits
git cherry-pick abc1234 def5678

# Cherry-pick range
git cherry-pick abc1234^..def5678

Resolving Cherry-Pick Conflicts

# When conflict occurs:
git status
# Resolve conflicts
git add .
git cherry-pick --continue

# Abort cherry-pick
git cherry-pick --abort

Git Hooks

Automated Workflows

.git/hooks/
├── applypatch-msg     # Patch apply
├── commit-msg         # Commit message validation
├── post-applypatch    # After patch
├── post-checkout      # After checkout
├── post-commit        # After commit
├── post-merge         # After merge
├── post-receive       # Server: After push received
├── pre-applypatch     # Before patch
├── pre-auto-gc        # Before garbage collection
├── pre-commit         # Before commit
├── pre-push           # Before push
├── pre-rebase         # Before rebase
├── pre-receive        # Server: Before accepting push
├── prepare-commit-msg # Modify commit message
├── push-to-checkout   # Update checked out branch
└── update             # Server: Per-ref update

Common Hook Examples

#!/bin/bash
# .git/hooks/pre-commit - Prevent commits with "TODO"

if git diff --cached --grep="TODO" --quiet; then
    echo "Error: Commit contains TODO markers"
    exit 1
fi
#!/bin/bash
# .git/hooks/commit-msg - Enforce commit message format

message=$(cat "$1")
pattern="^(feat|fix|docs|style|refactor|test|chore): .+"

if ! echo "$message" | grep -qE "$pattern"; then
    echo "Error: Commit message must follow conventional commits"
    echo "Format: type: description"
    exit 1
fi
#!/bin/bash
# .git/hooks/pre-push - Run tests before push

if ! npm test; then
    echo "Tests failed. Push aborted."
    exit 1
fi

Global Hooks

# Configure global hooks directory
git config --global core.hooksPath ~/.git-hooks

# Apply to all repos
cp pre-commit ~/.git-hooks/
chmod +x ~/.git-hooks/pre-commit

Git Submodules

Managing External Repositories

# Add submodule
git submodule add https://github.com/user/repo.git path/to/submodule

# Clone with submodules
git clone --recurse-submodules https://github.com/user/main-repo.git

# Initialize submodules in existing clone
git submodule update --init --recursive

# Update submodules
git submodule update --remote

# Remove submodule
git submodule deinit path/to/submodule
git rm path/to/submodule
rm -rf .git/modules/path/to/submodule

Worktrees

Multiple Working Directories

# Create worktree for feature branch
git worktree add ../project-feature feature-branch

# List worktrees
git worktree list

# Remove worktree
git worktree remove ../project-feature

# Prune stale worktrees
git worktree prune

Reflog - Safety Net

Recovering from Mistakes

# View all reference updates
git reflog

# Find lost commit
git reflog | grep "commit-message"

# Recover deleted branch
git reflog
# Find the SHA before deletion
git checkout -b recovered-branch abc1234

# Recover reset commit
git reset --hard HEAD@{2}

# Time-based recovery
git reflog show --all --since="3 days ago"

GitHub/GitLab Workflows

Fork and PR Workflow

# 1. Fork on GitHub
# 2. Clone your fork
git clone https://github.com/YOUR-USER/repo.git
cd repo

# 3. Add upstream remote
git remote add upstream https://github.com/ORIGINAL/repo.git

# 4. Create feature branch
git checkout -b feature-name

# 5. Make changes and commit
git add .
git commit -m "feat: add new feature"

# 6. Push to your fork
git push origin feature-name

# 7. Create Pull Request on GitHub

# 8. Sync with upstream
git fetch upstream
git rebase upstream/main

Syncing Fork

# Fetch upstream changes
git fetch upstream

# Checkout main
git checkout main

# Merge upstream
git merge upstream/main

# Or rebase for cleaner history
git rebase upstream/main

# Push to your fork
git push origin main

Feature Branch Strategy

main (protected)
  |  PR reviewed & merged
  |
develop
  |  PR reviewed & merged
  |
feature/login
feature/api
feature/ui

Release Workflow

# Create release branch
git checkout -b release/v1.2.0 develop

# Version bump, final fixes
git commit -am "Bump version to 1.2.0"

# Merge to main
git checkout main
git merge --no-ff release/v1.2.0
git tag -a v1.2.0

# Merge back to develop
git checkout develop
git merge --no-ff release/v1.2.0

# Delete release branch
git branch -d release/v1.2.0

Git Best Practices

Commit Guidelines

# Commit often
# Small, focused commits
# Write clear messages

# Good examples:
git commit -m "feat: add user authentication endpoint"
git commit -m "fix: resolve null pointer in checkout"
git commit -m "docs: update API documentation"
git commit -m "test: add unit tests for payment service"

# Bad examples:
git commit -m "fix"
git commit -m "updates"
git commit -m "stuff"

Branch Naming Conventions

feature/user-authentication
feature/JIRA-123-payment-gateway
bugfix/login-error-500
hotfix/security-patch
release/v2.1.0
docs/api-reference
refactor/database-layer
test/integration-tests

Pull Request Best Practices

  1. Keep PRs Small: Under 400 lines when possible
  2. Descriptive Title: "Fix race condition in cache" not "Fix bug"
  3. Detailed Description: What, Why, How
  4. Link Issues: "Closes #123"
  5. Add Tests: Include relevant test coverage
  6. Review Checklist: Self-review before requesting
  7. Respond to Feedback: Address all comments

Git LFS (Large File Storage)

# Install Git LFS
git lfs install

# Track large files
git lfs track "*.psd"
git lfs track "*.zip"
git lfs track "videos/*"

# Commit .gitattributes
git add .gitattributes
git commit -m "Add Git LFS tracking"

# Push LFS objects
git lfs push origin main

Quiz

Quiz

Question 1 of 5

What is the main difference between git merge and git rebase?

Merge is faster than rebase
Merge creates a merge commit; rebase creates linear history
Rebase can only be used on public branches
Merge deletes the source branch

Next Steps

Now let's explore build tools and package management—the foundation of application deployment.