Learning Objectives
- Master interactive rebasing and commit manipulation
- Practice cherry-picking and applying specific changes
- Learn to use reflog for repository recovery
- Implement advanced history rewriting techniques
Practice Overview
These exercises will help you master advanced Git concepts through practical scenarios. You'll work with complex repository manipulations and learn to handle sophisticated Git operations.
⚠️ Important Note
These exercises involve history-rewriting operations. Always practice these on a test repository first, as they can permanently alter your Git history.
Exercise 1: Interactive Rebase
Scenario
Clean up a feature branch's commit history before merging it into the main branch. You'll need to combine commits, edit commit messages, and reorder commits.
Initial Setup:
# Create test repository$ git init rebase-practice$ cd rebase-practice # Create some test commits$ echo "Initial content" > file.txt$ git add file.txt$ git commit -m "Initial commit" $ echo "Feature part 1" >> file.txt$ git commit -am "Add feature part 1" $ echo "Fix typo" >> file.txt$ git commit -am "Fix typo in part 1" $ echo "Feature part 2" >> file.txt$ git commit -am "Add feature part 2" $ echo "Another fix" >> file.txt$ git commit -am "Fix another typo"
Rebase Tasks:
- Combine the typo fixes into their related feature commits
- Edit commit messages to be more descriptive
- Ensure the history is clean and logical
Solution:
# Start interactive rebase$ git rebase -i HEAD~4 # In the editor, rearrange to:pick abc123 Add feature part 1fixup def456 Fix typo in part 1pick ghi789 Add feature part 2fixup jkl012 Fix another typo # After saving, edit commit messages as prompted$ git commit --amend -m "Add complete feature part 1 with fixes"$ git rebase --continue
Exercise 2: Cherry-Picking Operations
Scenario
Apply specific changes from one branch to another without merging the entire branch. Handle conflicts and maintain proper commit attribution.
Implementation:
# Create feature branch with multiple commits$ git checkout -b feature/complex$ echo "Feature A" > feature-a.txt$ git add feature-a.txt$ git commit -m "Add Feature A" $ echo "Feature B" > feature-b.txt$ git add feature-b.txt$ git commit -m "Add Feature B" # Cherry-pick specific commit to main$ git checkout main$ git cherry-pick feature/complex~1 # Cherry-pick with conflicts$ git cherry-pick feature/complex# Resolve conflicts if any$ git cherry-pick --continue # Cherry-pick without committing$ git cherry-pick -n commit-hash# Make additional changes$ git commit -m "Combined changes"
Exercise 3: Reflog Recovery
Scenario
Practice using Git's reflog to recover from various "disaster" scenarios, including lost commits and accidentally deleted branches.
Recovery Scenarios:
# Create and delete a branch$ git checkout -b feature/important$ echo "Important work" > important.txt$ git add important.txt$ git commit -m "Important changes"$ git checkout main$ git branch -D feature/important # Recover deleted branch$ git reflog$ git checkout -b feature/important HEAD@{1} # Reset gone wrong$ git reset --hard HEAD~3# Oops! Need those commits back$ git reflog$ git reset --hard HEAD@{1} # Recover specific commit$ git reflog$ git cherry-pick HEAD@{2}
Exercise 4: History Rewriting
Scenario
Perform complex history rewriting operations including changing author information, splitting commits, and filtering repository history.
Operations:
# Change author for last 3 commits$ git rebase -i HEAD~3# Change 'pick' to 'edit' for commits to modify$ git commit --amend --author="New Name <email@example.com>"$ git rebase --continue # Split a commit$ git reset HEAD^$ git add --patch$ git commit -m "First part of split"$ git add .$ git commit -m "Second part of split" # Filter repository history$ git filter-branch --tree-filter 'rm -f passwords.txt' HEAD # Clean up refs and reflogs$ git for-each-ref --format="%(refname)" refs/original/ | xargs -n 1 git update-ref -d$ git reflog expire --expire=now --all$ git gc --prune=now
Advanced Operations Best Practices
- Always create a backup branch before complex operations
- Use
--dry-run
when available to preview changes - Keep reflog entries for longer on important repositories
- Document complex operations in commit messages