Skip to content

Git Advanced

← Back to all decks

15 cards — 🟢 3 easy | 🟡 10 medium | 🔴 2 hard

🟢 Easy (3)

1. How do you use git log to find specific changes?

Show answer Powerful search options beyond basic git log:

git log --oneline --graph # visual branch history
git log -S 'function_name' # pickaxe: commits adding/removing string
git log -G 'regex_pattern' # grep through diffs
git log --author='name' # filter by author
git log --since='2 weeks ago' # time-based filter
git log -- path/to/file # history of specific file
git log --follow -- old_name.py # track renames
git log --all --merges # only merge commits
git shortlog -sn # commit count by author

Combine filters: git log --since='1 month' --author='alice' -S 'TODO' for targeted forensics.

2. What is git clean and when do you use it?

Show answer git clean removes untracked files from the working directory.

git clean -n # dry run — show what would be deleted
git clean -f # force delete untracked files
git clean -fd # also remove untracked directories
git clean -fx # also remove ignored files (.gitignore)
git clean -fxd # nuclear option: everything not tracked

Always use -n first to preview. Common use: cleaning build artifacts, resetting to a pristine state. Combine with git checkout -- . to fully reset working directory to last commit state. Safer alternative: git stash -u to save untracked files before removing.

3. Explain git tags: lightweight vs annotated

Show answer Tags mark specific commits, commonly used for release versions.

# Lightweight tag (just a pointer)
git tag v1.0

# Annotated tag (full object with metadata)
git tag -a v1.0 -m 'Release 1.0'

# Tag a specific commit
git tag -a v0.9 abc1234 -m 'Retroactive tag'

# Push tags
git push origin v1.0 # push specific tag
git push origin --tags # push all tags

# List and filter
git tag -l 'v1.*' # glob filter
git show v1.0 # show tag details

Annotated tags store tagger, date, message, and can be GPG-signed. Use annotated for releases, lightweight for temporary/private markers.

🟡 Medium (10)

1. What does git cherry-pick do and when would you use it?

Show answer cherry-pick applies a specific commit from one branch onto another, creating a new commit with the same changes.

git cherry-pick abc1234
git cherry-pick abc1234..def5678 # range (exclusive start)
git cherry-pick -x abc1234 # adds '(cherry picked from ...)' to message

Use cases: backporting a bugfix to a release branch, selectively pulling changes. Caution: creates duplicate commits — prefer merge/rebase for full branch integration.

2. How does git bisect work?

Show answer bisect uses binary search to find the commit that introduced a bug.

git bisect start
git bisect bad # current commit is broken
git bisect good v1.0 # this tag was working
# Git checks out the midpoint — test it
git bisect good # or 'bad'
# Repeat until found
git bisect reset # return to original branch

Automate: git bisect run ./test.sh (exit 0 = good, non-zero = bad). Finds the culprit in O(log n) commits. Essential for debugging regressions in large histories.

3. Explain git stash subcommands: pop vs apply, show, list

Show answer git stash temporarily shelves uncommitted changes.

git stash # stash tracked changes
git stash -u # include untracked files
git stash list # show all stashes
git stash show -p # show diff of latest stash
git stash apply # restore but keep in stash list
git stash pop # restore and remove from stash list
git stash drop stash@{2} # delete specific stash
git stash branch newbranch # create branch from stash

pop = apply + drop. Use apply when you want to apply the same stash to multiple branches. Named stashes: git stash push -m 'description'.

4. What is git reflog and how do you recover lost commits?

Show answer reflog records every HEAD movement locally — a safety net for recovering 'lost' work.

git reflog # show HEAD history
git reflog show feature-branch # show branch history
git checkout HEAD@{3} # go back 3 HEAD changes
git branch recovery abc1234 # create branch at lost commit

Recovery examples:
- After bad rebase: git reset --hard HEAD@{1}
- After deleted branch: find SHA in reflog, git branch restore
- After bad reset: git reset --hard HEAD@{N}

Reflog entries expire after 90 days (30 for unreachable). Local only — not shared via push/pull.

5. How does git blame work and what are its useful options?

Show answer blame shows who last modified each line of a file.

git blame file.py # basic blame
git blame -L 10,20 file.py # lines 10-20 only
git blame -w file.py # ignore whitespace changes
git blame -C file.py # detect moved/copied lines
git blame -C -C file.py # also detect from other files
git blame --since=2w file.py # only recent changes

git annotate is an alias with slightly different output format. For finding when a line was deleted, use git log -S 'deleted text' (pickaxe search). Combine with -M to detect moves.

6. What is .gitattributes and what problems does it solve?

Show answer .gitattributes controls per-path Git behavior: line endings, diff drivers, merge strategies, LFS tracking.

Common entries:
*.sh text eol=lf # force Unix line endings
*.bat text eol=crlf # force Windows line endings
*.png binary # treat as binary (no diff/merge)
*.pbxproj merge=union # auto-merge by taking both sides
*.lock linguist-generated # exclude from GitHub stats
*.csv diff=csv # custom diff driver
*.psd filter=lfs diff=lfs # Git LFS tracking

Place in repo root (or any directory for scoped rules). Prevents cross-platform line ending issues and enables binary file handling with LFS.

7. How does git worktree work?

Show answer worktree lets you check out multiple branches simultaneously in separate directories — no stashing or cloning needed.

git worktree add ../hotfix release-1.0 # check out branch in new dir
git worktree add ../experiment -b new-feature # create + check out
git worktree list # show all worktrees
git worktree remove ../hotfix # clean up

Each worktree shares the same .git data but has its own working directory and index. You cannot check out the same branch in two worktrees. Great for: reviewing PRs while keeping your work intact, running tests on another branch, comparing implementations side by side.

8. Explain the difference between merge and rebase

Show answer merge creates a merge commit preserving both branch histories. rebase replays commits onto a new base, creating a linear history.

# Merge: feature into main
git checkout main && git merge feature
# Creates merge commit M with two parents

# Rebase: feature onto main
git checkout feature && git rebase main
# Replays feature commits on top of main

Rebase produces cleaner history but rewrites commits (new SHAs). Golden rule: never rebase commits that have been pushed and shared. Use merge for shared branches, rebase for local cleanup before merging. Interactive rebase (git rebase -i) lets you squash, edit, reorder commits.

9. How do you resolve merge conflicts?

Show answer Conflict markers in files:
<<<<<<< HEAD
your changes
=======
their changes
>>>>>>> feature-branch

Resolution steps:
1. Open conflicted files, choose/combine changes
2. Remove conflict markers (<<<<, ====, >>>>)
3. git add resolved_file.py
4. git commit # or git merge --continue

Tools:
git mergetool # launch configured merge tool
git checkout --ours file # take our version entirely
git checkout --theirs file # take their version entirely
git diff --check # verify no markers remain

Prevent: communicate about shared files, merge frequently, keep branches short-lived.

10. How does git reset differ from git revert?

Show answer reset moves the branch pointer backward (rewrites history). revert creates a new commit that undoes changes (safe for shared branches).

# Reset (local only — rewrites history)
git reset --soft HEAD~1 # undo commit, keep changes staged
git reset --mixed HEAD~1 # undo commit, unstage changes (default)
git reset --hard HEAD~1 # undo commit, discard all changes

# Revert (safe for shared branches)
git revert abc1234 # create inverse commit
git revert HEAD~3..HEAD # revert a range
git revert -m 1 # revert a merge commit

Rule: use reset for local unpushed commits, revert for anything already shared. Reset --hard is destructive — check reflog if you need to recover.

🔴 Hard (2)

1. Explain git submodules and their common operations

Show answer Submodules embed one Git repo inside another at a specific commit.

git submodule add path/ # add submodule
git submodule update --init # clone submodule after fresh clone
git submodule update --remote # pull latest from submodule remote
git submodule foreach 'git pull origin main'

The parent repo tracks a specific commit SHA, not a branch. After updating a submodule, you must commit the parent repo to record the new SHA.

Common gotchas: detached HEAD in submodules (normal), forgetting --recurse-submodules on clone, CI needing explicit submodule init. Alternative: git subtree (merges history) or package managers.

2. What is git rebase --onto and when is it useful?

Show answer --onto transplants a branch segment onto a new base.

git rebase --onto newbase oldbase feature

Example: feature was branched from dev, but should be on main:
git rebase --onto main dev feature
# Takes commits unique to feature (after dev) and replays them on main

Also useful for dropping commits:
git rebase --onto HEAD~3 HEAD~1 HEAD
# Removes the commit at HEAD~1

Think of it as: 'take commits from oldbase..feature and replay them onto newbase'. More surgical than plain rebase.