Git Advanced Operations

Autonomous Agents Advanced autonomous-agent-skills openai-codex, chatgpt, universal
1 Upvotes
10 Views
1 Downloads
1,160 Words

Description

Performs advanced Git operations (rebase, cherry-pick, bisect, stash, submodules, worktrees, reflog, hooks) to manage complex workflows; use for clean history and safe recovery.

When to Use

perform an interactive rebase to clean up commits | cherry-pick a commit onto another branch | bisect a bug to find the bad commit | manage submodules or worktrees | recover a commit using reflog

Use Cases

Clean up feature branch history with an interactive rebase. | Cherry-pick a commit onto another branch. | Bisect a bug to locate the bad commit. | Manage submodules and worktrees for multi-repo projects. | Recover a commit using reflog.

SKILL.md Content

---
name: git-advanced-operations
description: "Performs advanced Git operations (rebase, cherry-pick, bisect, stash, submodules, worktrees, reflog, hooks) to manage complex workflows; use for clean history and safe recovery."
metadata:
  tags: "version-control, git-advanced, interactive-rebase, cherry-pick, git-bisect, stash-management, submodules, worktrees"
  source: "https://skilldb.dev/skills/autonomous-agent-skills/git-advanced-operations"
  pack: "autonomous-agent-skills"
  category: "Autonomous Agents"
---

# Git Advanced Operations

## When to use this skill
Use when the user says things like:
- "perform an interactive rebase to clean up commits"
- "cherry-pick a commit onto another branch"
- "bisect a bug to find the bad commit"
- "manage submodules or worktrees"
- "recover a commit using reflog"


You are an autonomous agent that performs advanced git operations to manage complex version control workflows.
Beyond basic commit and push, you must understand git's internal model — commits are snapshots, branches are pointers, and the reflog is your safety net.
Use these tools precisely, because mistakes in shared history are costly.

## Philosophy

Git is a content-addressable filesystem with a VCS built on top.
Understanding this model is essential for advanced operations.
Every commit is immutable once created; operations like rebase create new commits rather than modifying existing ones.
Treat shared branches (main, develop) as sacred — never rewrite their history.
Use feature branches freely for history cleanup before merging.
When faced with a complex git problem, pause and think about the commit graph — drawing it out clarifies most situations.

## Techniques

### Interactive Rebase Concepts
Interactive rebase (`git rebase -i`) lets you reorder, squash, edit, or drop commits on a branch.
Use it to clean up a feature branch before merging: squash fixup commits, reword unclear messages, and reorder commits into logical groups.
Never rebase commits that have been pushed to a shared branch.
Rebase rewrites history — every rebased commit gets a new SHA.
Mark fixup commits with `fixup!` or `squash!` prefixes so `git rebase -i --autosquash` handles them automatically.

### Cherry-Picking
Use `git cherry-pick <sha>` to apply a specific commit from one branch to another.
This is ideal for hotfixes: fix on main, cherry-pick to release branches.
Cherry-picking creates a new commit with a different SHA, so the same change appears twice in history.
Use `-x` to add a reference to the original commit in the message.
Cherry-pick ranges with `git cherry-pick A..B` to apply multiple commits.
If conflicts arise during cherry-pick, resolve them, then `git cherry-pick --continue`.

### Bisect for Finding Bugs
`git bisect` performs a binary search through commit history to find the commit that introduced a bug.
Start with `git bisect start`, mark the current state as `bad` and a known good commit as `good`.
Git checks out the midpoint; you test and mark it.
Automate with `git bisect run <test-script>` for hands-free bug hunting.
This finds the culprit in O(log n) steps.
The test script must exit 0 for good and non-zero for bad.
Bisect works best when each commit is individually buildable and testable.

### Stash Management
`git stash` saves uncommitted changes for later.
Use `git stash push -m "description"` to label stashes for identification.
List with `git stash list`, apply with `git stash pop` (removes from stack) or `git stash apply` (keeps in stack).
Stash individual files with `git stash push -- path/to/file`.
Stashes are local and can be lost during garbage collection if not applied.
For long-lived work-in-progress, prefer a WIP commit on a branch over a stash.

### Submodule Handling
Submodules embed one git repository inside another at a fixed commit.
After cloning, run `git submodule update --init --recursive` to populate them.
Update submodules with `git submodule update --remote`.
Commit the updated submodule reference in the parent.
Submodules add complexity — contributors must remember extra commands for init and update.
Consider alternatives like package managers, git subtree, or monorepo tools when submodule overhead becomes a friction point.

### Worktree Usage
`git worktree add <path> <branch>` creates a linked working tree for a branch without switching your current checkout.
This lets you work on multiple branches simultaneously — for example, building a release while developing a feature.
Each worktree has its own working directory and index but shares the same repository and object store.
Remove with `git worktree remove <path>`.

### Reflog Recovery
The reflog records every change to HEAD and branch tips for 90 days (configurable).
If you lose commits through a bad rebase, accidental reset, or branch deletion, find them in `git reflog`.
Recover with `git checkout <sha>` or `git branch recovery <sha>`.
The reflog is your undo history — it makes almost every git mistake recoverable as long as objects have not been garbage collected.
It is local only and not shared via push.
Use `git reflog show <branch>` to see reflog for a specific branch.

### Merge Strategies
Use `git merge --no-ff` to always create a merge commit, preserving branch topology in history.
Use `git merge --squash` to combine all branch commits into one without a merge commit.
The `ours` strategy keeps current branch content entirely and records the merge.
The default `recursive` strategy handles most cases well.
Specify `-X patience` or `-X histogram` for better diff algorithms when files have many similar lines.

### Conflict Resolution Patterns
When conflicts arise, understand the three versions: ours (current branch), theirs (incoming branch), and base (common ancestor).
Use `git mergetool` or resolve manually in your editor.
Configure `diff3` conflict style (`git config merge.conflictstyle diff3`) to see the base version in conflict markers, which makes resolution much clearer.
For repeated conflicts on long-lived branches, use `git rerere` to automatically apply past resolutions.
After resolving, always run tests before completing the merge.

### Git Hooks
Hooks are scripts triggered by git events.
Client-side hooks: `pre-commit` (lint, format), `commit-msg` (validate message format), `pre-push` (run tests).
Server-side hooks: `pre-receive`, `post-receive`.
Use tools like husky (Node.js) or pre-commit framework (Python) to manage hooks across a team.
Hooks should run fast — move slow checks to CI.
Keep hooks in the repository (not just `.git/hooks`) so they are shared and version-controlled.

## Best Practices

- Before any history-rewriting operation, create a backup branch: `git branch backup-before-rebase`.
- Use `git log --oneline --graph --all` to visualize branch topology before and after complex operations.
- Write meaningful commit messages: imperative mood, 50-char subject, blank line, then body explaining why.
- Use `git diff --cached` to review staged changes before committing.
- Configure `git rerere.enabled true` globally to record and replay conflict resolutions.
- Use signed commits (`git commit -S`) for verified authorship on important branches.
- Set up branch protection rules on shared repositories to prevent force pushes to main.
- Prefer `git switch` and `git restore` over the overloaded `git checkout`.
- Configure a global `.gitignore` for OS and editor files.

## Anti-Patterns

- **Rebasing shared branches** — This rewrites history that others have based work on, causing divergent histories and forced merges.
- **Force pushing without lease** — Use `git push --force-with-lease` instead of `--force` to avoid overwriting someone else's work.
- **Giant commits with unrelated changes** — Each commit should address one concern. Mixed commits make bisect useless and code review painful.
- **Ignoring the reflog** — Before panicking about lost work, check `git reflog`. Almost everything is recoverable within 90 days.
- **Nested submodules without documentation** — Deep submodule nesting creates initialization nightmares.
- **Committing generated files** — Build artifacts and dependency directories should be in `.gitignore`.
- **Using git as a deployment mechanism** — Running `git pull` on production is fragile. Use CI/CD pipelines.
- **Committing secrets** — Once pushed, secrets are in the remote history. Rotate immediately, then purge with BFG or git filter-repo.