Initial commit
This commit is contained in:
11
.claude-plugin/plugin.json
Normal file
11
.claude-plugin/plugin.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "git-absorb",
|
||||||
|
"description": "Automatically fold uncommitted changes into appropriate commits. Use for applying review feedback and maintaining atomic commit history.",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"author": {
|
||||||
|
"name": "Alberto Leal"
|
||||||
|
},
|
||||||
|
"skills": [
|
||||||
|
"./"
|
||||||
|
]
|
||||||
|
}
|
||||||
3
README.md
Normal file
3
README.md
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# git-absorb
|
||||||
|
|
||||||
|
Automatically fold uncommitted changes into appropriate commits. Use for applying review feedback and maintaining atomic commit history.
|
||||||
232
SKILL.md
Normal file
232
SKILL.md
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
---
|
||||||
|
name: git-absorb
|
||||||
|
description: Automatically fold uncommitted changes into appropriate commits on a feature branch. Use when applying review feedback, fixing bugs in feature branches, or maintaining atomic commit history without manual interactive rebasing. Particularly useful for making corrections to recent commits without creating messy "fixes" commits.
|
||||||
|
---
|
||||||
|
|
||||||
|
# Git Absorb
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
`git absorb` automatically identifies which commits should contain your staged changes and creates fixup commits that can be autosquashed. This eliminates the need to manually find commit SHAs or run interactive rebases when applying review feedback or fixing bugs in feature branches.
|
||||||
|
|
||||||
|
## When to Use This Skill
|
||||||
|
|
||||||
|
Use git-absorb when:
|
||||||
|
- **Applying review feedback**: Reviewer pointed out bugs or improvements across multiple commits
|
||||||
|
- **Fixing bugs**: Discovered issues in your feature branch that belong in specific earlier commits
|
||||||
|
- **Maintaining atomic commits**: Want to keep commits focused without creating "fixes" or "oops" commits
|
||||||
|
- **Avoiding manual rebasing**: Don't want to manually identify which commits need which changes
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
**CRITICAL**: Before proceeding, you MUST verify that git-absorb is installed:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git absorb --version
|
||||||
|
```
|
||||||
|
|
||||||
|
**If git-absorb is not installed:**
|
||||||
|
- **DO NOT** attempt to install it automatically
|
||||||
|
- **STOP** and inform the user that git-absorb is required
|
||||||
|
- **RECOMMEND** manual installation with the following instructions:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# macOS
|
||||||
|
brew install git-absorb
|
||||||
|
|
||||||
|
# Linux (Debian/Ubuntu)
|
||||||
|
apt install git-absorb
|
||||||
|
|
||||||
|
# Arch Linux
|
||||||
|
pacman -S git-absorb
|
||||||
|
|
||||||
|
# Cargo (all platforms)
|
||||||
|
cargo install git-absorb
|
||||||
|
|
||||||
|
# Other systems: see https://github.com/tummychow/git-absorb
|
||||||
|
```
|
||||||
|
|
||||||
|
**If git-absorb is not available, exit gracefully and do not proceed with the workflow below.**
|
||||||
|
|
||||||
|
### Important Default Behaviors
|
||||||
|
|
||||||
|
Before using git-absorb, understand these key defaults:
|
||||||
|
|
||||||
|
**Author Filtering**: By default, git-absorb **only modifies commits you authored**. It will not absorb changes into commits made by teammates.
|
||||||
|
- To absorb into any author's commits, use `git absorb --force-author`
|
||||||
|
- Or configure globally: `git config absorb.forceAuthor true`
|
||||||
|
|
||||||
|
**Stack Size Limit**: By default, git-absorb searches only the **last 10 commits**. If you're working on a larger feature branch, you may need to:
|
||||||
|
- Use `--base <branch>` to specify a range (e.g., `--base main`)
|
||||||
|
- Or increase the limit in `.gitconfig` (see Configuration section below)
|
||||||
|
|
||||||
|
**Staged Changes Only**: git-absorb only considers changes in the git index (staging area). Unstaged changes are ignored.
|
||||||
|
|
||||||
|
## Basic Workflow
|
||||||
|
|
||||||
|
**ONLY proceed with this workflow if git-absorb is confirmed to be installed.**
|
||||||
|
|
||||||
|
### Step 1: Make Your Changes
|
||||||
|
|
||||||
|
Make fixes or improvements to files in your working directory.
|
||||||
|
|
||||||
|
### Step 2: Stage the Changes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add <files-you-fixed>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Important**: Only stage changes you want absorbed. git-absorb only considers staged changes.
|
||||||
|
|
||||||
|
### Step 3: Run git absorb
|
||||||
|
|
||||||
|
**Option A: Automatic (recommended for trust)**
|
||||||
|
```bash
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
This creates fixup commits AND automatically rebases them into the appropriate commits.
|
||||||
|
|
||||||
|
**Option B: Manual review**
|
||||||
|
```bash
|
||||||
|
git absorb
|
||||||
|
git log # Review the generated fixup commits
|
||||||
|
git rebase -i --autosquash <base-branch>
|
||||||
|
```
|
||||||
|
|
||||||
|
Use this when you want to inspect the fixup commits before integrating them.
|
||||||
|
|
||||||
|
## Common Patterns
|
||||||
|
|
||||||
|
### Pattern 1: Review Feedback
|
||||||
|
|
||||||
|
**Scenario**: PR reviewer found bugs in commits A, B, and C
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Make all the fixes
|
||||||
|
vim file1.py file2.py file3.py
|
||||||
|
|
||||||
|
# 2. Stage all fixes
|
||||||
|
git add file1.py file2.py file3.py
|
||||||
|
|
||||||
|
# 3. Let git-absorb figure out which fix goes where
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
git-absorb analyzes each change and assigns it to the appropriate commit.
|
||||||
|
|
||||||
|
### Pattern 2: Bug Fix in Feature Branch
|
||||||
|
|
||||||
|
**Scenario**: Found a bug in an earlier commit while developing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Fix the bug
|
||||||
|
vim src/module.py
|
||||||
|
|
||||||
|
# 2. Stage and absorb
|
||||||
|
git add src/module.py
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
The fix is automatically folded into the commit that introduced the bug.
|
||||||
|
|
||||||
|
### Pattern 3: Multiple Small Fixes
|
||||||
|
|
||||||
|
**Scenario**: Several typos, formatting issues across multiple commits
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Fix everything first
|
||||||
|
vim file1.py file2.py README.md
|
||||||
|
|
||||||
|
# Stage and absorb in one go
|
||||||
|
git add -A
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Usage
|
||||||
|
|
||||||
|
For comprehensive coverage of all flags and advanced patterns, see [references/advanced-usage.md](references/advanced-usage.md).
|
||||||
|
|
||||||
|
**Key flags:**
|
||||||
|
- `--base <commit>`: Specify range (e.g., `--base main`)
|
||||||
|
- `--dry-run`: Preview without making changes
|
||||||
|
- `--force`: Skip safety checks
|
||||||
|
- `--one-fixup-per-commit`: Generate one fixup per target commit
|
||||||
|
- `--verbose`: See detailed output
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --base main --dry-run --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
For complete configuration reference with all options, see [references/configuration.md](references/configuration.md).
|
||||||
|
|
||||||
|
**Most important configuration:**
|
||||||
|
|
||||||
|
If you see "WARN stack limit reached, limit: 10", increase the stack size:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git config absorb.maxStack 50 # Local
|
||||||
|
git config --global absorb.maxStack 50 # Global
|
||||||
|
```
|
||||||
|
|
||||||
|
By default, git-absorb only searches the last 10 commits. For larger feature branches, increase this to 50 or higher.
|
||||||
|
|
||||||
|
**Other useful configs:**
|
||||||
|
- `oneFixupPerCommit`: One fixup per commit instead of per hunk
|
||||||
|
- `autoStageIfNothingStaged`: Auto-stage all changes if nothing staged
|
||||||
|
- `forceAuthor`: Allow absorbing into teammates' commits
|
||||||
|
|
||||||
|
See [references/configuration.md](references/configuration.md) for details and all 7 configuration options.
|
||||||
|
|
||||||
|
## Recovery
|
||||||
|
|
||||||
|
If something goes wrong or you're not satisfied:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git reset --soft PRE_ABSORB_HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
This restores the state before running git-absorb. You can also find the commit in `git reflog`.
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
git-absorb uses commutative patch theory:
|
||||||
|
1. For each staged hunk, check if it commutes with the last commit
|
||||||
|
2. If not, that's the parent commit for this change
|
||||||
|
3. If it commutes with all commits in range, leave it staged (warning shown)
|
||||||
|
4. Create fixup commits for absorbed changes
|
||||||
|
|
||||||
|
This ensures changes are assigned to the correct commits based on line modification history.
|
||||||
|
|
||||||
|
## Safety Considerations
|
||||||
|
|
||||||
|
- **Always review**: Use manual mode first until comfortable with automatic mode
|
||||||
|
- **Local only**: Only use on local branches, never on shared/pushed commits
|
||||||
|
- **Backup**: git-absorb is safe, but `git reflog` is your friend
|
||||||
|
- **Test after**: Run tests after absorbing to verify nothing broke
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
**"WARN stack limit reached, limit: 10"**
|
||||||
|
- git-absorb only searches the last 10 commits by default
|
||||||
|
- Increase the stack size: `git config absorb.maxStack 50`
|
||||||
|
- Or use `--base <branch>` to specify the range (e.g., `--base main`)
|
||||||
|
- See the Configuration section above for details
|
||||||
|
|
||||||
|
**"Can't find appropriate commit for these changes"**
|
||||||
|
- The changes may be too new (modify lines not in recent commits)
|
||||||
|
- Try increasing the range with `--base <branch>`
|
||||||
|
- Try increasing stack size: `git config absorb.maxStack 50`
|
||||||
|
- Changes may need to be in a new commit
|
||||||
|
|
||||||
|
**"Command not found: git-absorb"**
|
||||||
|
- Not installed. See Prerequisites section above for manual installation instructions
|
||||||
|
- Do NOT attempt automatic installation
|
||||||
|
|
||||||
|
**"Conflicts during rebase"**
|
||||||
|
- Some changes couldn't be absorbed cleanly
|
||||||
|
- Resolve conflicts manually or use `git rebase --abort`
|
||||||
|
- Consider breaking changes into smaller pieces
|
||||||
53
plugin.lock.json
Normal file
53
plugin.lock.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"$schema": "internal://schemas/plugin.lock.v1.json",
|
||||||
|
"pluginId": "gh:dashed/claude-marketplace:plugins/git-absorb",
|
||||||
|
"normalized": {
|
||||||
|
"repo": null,
|
||||||
|
"ref": "refs/tags/v20251128.0",
|
||||||
|
"commit": "4b00f4e4ffb12956fb21aee8080dceba6e77eff9",
|
||||||
|
"treeHash": "6f7ebcb708b7d0d0ffc133557ed89c3f0382f620f6b9f474365c8f89a845dd18",
|
||||||
|
"generatedAt": "2025-11-28T10:16:02.736662Z",
|
||||||
|
"toolVersion": "publish_plugins.py@0.2.0"
|
||||||
|
},
|
||||||
|
"origin": {
|
||||||
|
"remote": "git@github.com:zhongweili/42plugin-data.git",
|
||||||
|
"branch": "master",
|
||||||
|
"commit": "aa1497ed0949fd50e99e70d6324a29c5b34f9390",
|
||||||
|
"repoRoot": "/Users/zhongweili/projects/openmind/42plugin-data"
|
||||||
|
},
|
||||||
|
"manifest": {
|
||||||
|
"name": "git-absorb",
|
||||||
|
"description": "Automatically fold uncommitted changes into appropriate commits. Use for applying review feedback and maintaining atomic commit history.",
|
||||||
|
"version": "1.0.0"
|
||||||
|
},
|
||||||
|
"content": {
|
||||||
|
"files": [
|
||||||
|
{
|
||||||
|
"path": "README.md",
|
||||||
|
"sha256": "276869e3bec68b5c98df6e4d53c2b029db13f582aa6994eb9843abef4e69e44f"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "SKILL.md",
|
||||||
|
"sha256": "61a77de2961f097c04ad3e47a70523afd0341b2cbfe4960c9c7a3bde558fbc48"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "references/configuration.md",
|
||||||
|
"sha256": "434a87b892d520c7b6117bbad3b7f9ee74a84da2c6a7d787eae6315a7956983b"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "references/advanced-usage.md",
|
||||||
|
"sha256": "3bccc5bf2d5f73b21f085fe6b8f18bce9d8252d128669357788d49c85504d046"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": ".claude-plugin/plugin.json",
|
||||||
|
"sha256": "6b9e76464613264af84fd09463a76ca0a0f7c8a0b4db87111cda87266a603ec9"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"dirSha256": "6f7ebcb708b7d0d0ffc133557ed89c3f0382f620f6b9f474365c8f89a845dd18"
|
||||||
|
},
|
||||||
|
"security": {
|
||||||
|
"scannedAt": null,
|
||||||
|
"scannerVersion": null,
|
||||||
|
"flags": []
|
||||||
|
}
|
||||||
|
}
|
||||||
374
references/advanced-usage.md
Normal file
374
references/advanced-usage.md
Normal file
@@ -0,0 +1,374 @@
|
|||||||
|
# Advanced Usage
|
||||||
|
|
||||||
|
This document covers all command-line flags and advanced usage patterns for git-absorb.
|
||||||
|
|
||||||
|
## Complete Flag Reference
|
||||||
|
|
||||||
|
### Core Flags
|
||||||
|
|
||||||
|
#### `--and-rebase` / `-r`
|
||||||
|
Run rebase automatically after creating fixup commits.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- You trust git-absorb's output
|
||||||
|
- You want a streamlined workflow
|
||||||
|
- Changes are straightforward
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--dry-run` / `-n`
|
||||||
|
Preview what would happen without making any changes.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- First time using git-absorb on a branch
|
||||||
|
- Testing if changes will absorb correctly
|
||||||
|
- Understanding which commits would be affected
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--base <commit>` / `-b <commit>`
|
||||||
|
Specify the base commit for the absorb stack.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Feature branch has more than 10 commits (default limit)
|
||||||
|
- Want to absorb into commits since a specific branch point
|
||||||
|
- Getting "stack limit reached" warnings
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
```bash
|
||||||
|
# Absorb into all commits since main
|
||||||
|
git absorb --base main
|
||||||
|
|
||||||
|
# Absorb into all commits since specific SHA
|
||||||
|
git absorb --base abc123
|
||||||
|
```
|
||||||
|
|
||||||
|
### Safety and Control Flags
|
||||||
|
|
||||||
|
#### `--force`
|
||||||
|
Skip all safety checks (equivalent to all `--force-*` flags).
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Need to bypass author filtering AND detached HEAD restrictions
|
||||||
|
- Understand the risks and have reviewed changes
|
||||||
|
|
||||||
|
**Warning:** Use with caution. This disables protective checks.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --force --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--force-author`
|
||||||
|
Generate fixups for commits not authored by you.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Pair programming with teammate's commits
|
||||||
|
- Maintaining a branch with multiple authors
|
||||||
|
- Cleaning up inherited code
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --force-author --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--force-detach`
|
||||||
|
Generate fixups even when HEAD is detached (not on a branch).
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Working in detached HEAD state intentionally
|
||||||
|
- Cherry-picking workflow
|
||||||
|
- Advanced git operations
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --force-detach
|
||||||
|
```
|
||||||
|
|
||||||
|
### Output Format Flags
|
||||||
|
|
||||||
|
#### `--one-fixup-per-commit` / `-F`
|
||||||
|
Generate only one fixup commit per target commit (instead of per hunk).
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Want cleaner commit history during rebase
|
||||||
|
- Multiple hunks absorbing into same commit
|
||||||
|
- Prefer consolidated fixups
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --one-fixup-per-commit --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--squash` / `-s`
|
||||||
|
Create squash commits instead of fixup commits.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Want to edit commit messages during rebase
|
||||||
|
- Need to document why changes were added
|
||||||
|
- Prefer squash over fixup in workflow
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --squash --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** When using this flag, all references to "fixup commits" should be read as "squash commits".
|
||||||
|
|
||||||
|
### Advanced Matching Flags
|
||||||
|
|
||||||
|
#### `--whole-file` / `-w`
|
||||||
|
Match the first commit that touched the same file (not just the same lines).
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Adding new functions to a file
|
||||||
|
- Changes don't overlap with existing lines
|
||||||
|
- Want to absorb into file's original commit
|
||||||
|
|
||||||
|
**Warning:** Use with care! This is less precise than line-based matching.
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --whole-file
|
||||||
|
```
|
||||||
|
|
||||||
|
### Information Flags
|
||||||
|
|
||||||
|
#### `--verbose` / `-v`
|
||||||
|
Display more detailed output about the absorption process.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Debugging unexpected behavior
|
||||||
|
- Understanding how changes are being matched
|
||||||
|
- Learning how git-absorb works
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --verbose --dry-run
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--version` / `-V`
|
||||||
|
Display git-absorb version information.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git absorb --version
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `--help` / `-h`
|
||||||
|
Display help information.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git absorb --help
|
||||||
|
```
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
#### `--message <MESSAGE>` / `-m <MESSAGE>`
|
||||||
|
Use the same commit message body for all generated fixup commits.
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Want consistent messaging across fixups
|
||||||
|
- Documenting a batch of related changes
|
||||||
|
- Organization requires specific commit formats
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb -m "Address PR review feedback" --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `-- <REBASE_OPTIONS>`
|
||||||
|
Pass options to git rebase (must be last argument, requires `--`).
|
||||||
|
|
||||||
|
**When to use:**
|
||||||
|
- Need to pass specific rebase options
|
||||||
|
- Custom rebase behavior required
|
||||||
|
- Using with `--and-rebase` flag
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
git absorb --and-rebase -- --autostash
|
||||||
|
```
|
||||||
|
|
||||||
|
**Note:** Only valid when `--and-rebase` is used.
|
||||||
|
|
||||||
|
## Advanced Patterns
|
||||||
|
|
||||||
|
### Pattern 1: Large Feature Branch
|
||||||
|
|
||||||
|
**Scenario:** Working on a feature branch with 50+ commits
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Option 1: Use --base to specify range
|
||||||
|
git add <fixed-files>
|
||||||
|
git absorb --base main --and-rebase
|
||||||
|
|
||||||
|
# Option 2: Configure maxStack permanently
|
||||||
|
git config absorb.maxStack 100
|
||||||
|
git add <fixed-files>
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 2: Selective Absorption
|
||||||
|
|
||||||
|
**Scenario:** Only want to absorb specific files, not everything staged
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stage only the files you want to absorb
|
||||||
|
git add file1.py file2.py
|
||||||
|
|
||||||
|
# Other staged files won't be absorbed
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 3: Review Before Committing
|
||||||
|
|
||||||
|
**Scenario:** Want to inspect fixup commits before rebasing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Step 1: Create fixup commits (no rebase)
|
||||||
|
git absorb
|
||||||
|
|
||||||
|
# Step 2: Review what was created
|
||||||
|
git log --oneline -10
|
||||||
|
|
||||||
|
# Step 3: If satisfied, rebase manually
|
||||||
|
git rebase -i --autosquash main
|
||||||
|
|
||||||
|
# If not satisfied, reset
|
||||||
|
git reset --soft PRE_ABSORB_HEAD
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 4: Team Branch with Multiple Authors
|
||||||
|
|
||||||
|
**Scenario:** Fixing bugs across a shared feature branch
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Allow absorbing into teammates' commits
|
||||||
|
git absorb --force-author --and-rebase
|
||||||
|
|
||||||
|
# Or configure permanently for this repo
|
||||||
|
git config absorb.forceAuthor true
|
||||||
|
git absorb --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 5: Verbose Debugging
|
||||||
|
|
||||||
|
**Scenario:** Understanding why changes aren't absorbing
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Use verbose mode with dry-run
|
||||||
|
git absorb --verbose --dry-run
|
||||||
|
|
||||||
|
# Look for messages like:
|
||||||
|
# "Can't find appropriate commit for hunk..."
|
||||||
|
# "Stack limit reached..."
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 6: Consolidate Multiple Hunks
|
||||||
|
|
||||||
|
**Scenario:** Many small fixes to the same commit, want one fixup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git absorb --one-fixup-per-commit --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
### Pattern 7: Detached HEAD Workflow
|
||||||
|
|
||||||
|
**Scenario:** Working in detached HEAD state (cherry-pick, bisect, etc.)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git absorb --force-detach --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flag Combinations
|
||||||
|
|
||||||
|
### Recommended Combinations
|
||||||
|
|
||||||
|
**Safe exploration:**
|
||||||
|
```bash
|
||||||
|
git absorb --dry-run --verbose
|
||||||
|
```
|
||||||
|
|
||||||
|
**Aggressive auto-fix:**
|
||||||
|
```bash
|
||||||
|
git absorb --force --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
**Team branch cleanup:**
|
||||||
|
```bash
|
||||||
|
git absorb --force-author --one-fixup-per-commit --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
**Large feature branch:**
|
||||||
|
```bash
|
||||||
|
git absorb --base main --verbose --and-rebase
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Issues and Solutions
|
||||||
|
|
||||||
|
### "Can't find appropriate commit"
|
||||||
|
|
||||||
|
**Cause:** Changes are too new or don't match any commits in range
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Increase range
|
||||||
|
git absorb --base main
|
||||||
|
|
||||||
|
# Check if file exists in commits
|
||||||
|
git log --oneline --follow <file>
|
||||||
|
|
||||||
|
# Consider if change belongs in new commit
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Stack limit reached"
|
||||||
|
|
||||||
|
**Cause:** Default 10-commit limit exceeded
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Use --base
|
||||||
|
git absorb --base main --and-rebase
|
||||||
|
|
||||||
|
# Or increase maxStack
|
||||||
|
git config absorb.maxStack 50
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Conflicts during rebase"
|
||||||
|
|
||||||
|
**Cause:** Changes can't be cleanly absorbed
|
||||||
|
|
||||||
|
**Solutions:**
|
||||||
|
```bash
|
||||||
|
# Abort and try manual approach
|
||||||
|
git rebase --abort
|
||||||
|
git reset --soft PRE_ABSORB_HEAD
|
||||||
|
|
||||||
|
# Or resolve conflicts manually
|
||||||
|
# (follow git's conflict resolution prompts)
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unintended absorption into wrong commit
|
||||||
|
|
||||||
|
**Cause:** git-absorb matched lines incorrectly
|
||||||
|
|
||||||
|
**Prevention:**
|
||||||
|
```bash
|
||||||
|
# Always use --dry-run first
|
||||||
|
git absorb --dry-run
|
||||||
|
|
||||||
|
# Review before rebasing
|
||||||
|
git absorb # no --and-rebase
|
||||||
|
git log --oneline -10 # review fixups
|
||||||
|
```
|
||||||
|
|
||||||
|
**Recovery:**
|
||||||
|
```bash
|
||||||
|
git reset --soft PRE_ABSORB_HEAD
|
||||||
|
```
|
||||||
436
references/configuration.md
Normal file
436
references/configuration.md
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
# Configuration Reference
|
||||||
|
|
||||||
|
Complete guide to configuring git-absorb behavior via `.gitconfig`.
|
||||||
|
|
||||||
|
## Quick Reference
|
||||||
|
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 50
|
||||||
|
oneFixupPerCommit = true
|
||||||
|
autoStageIfNothingStaged = true
|
||||||
|
fixupTargetAlwaysSHA = false
|
||||||
|
forceAuthor = false
|
||||||
|
forceDetach = false
|
||||||
|
createSquashCommits = false
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### `maxStack`
|
||||||
|
|
||||||
|
**Default:** `10`
|
||||||
|
|
||||||
|
**Purpose:** Maximum number of commits to search when run without `--base`.
|
||||||
|
|
||||||
|
**When to configure:**
|
||||||
|
- Working on feature branches with >10 commits
|
||||||
|
- Seeing "WARN stack limit reached" messages
|
||||||
|
- Want to absorb into older commits
|
||||||
|
|
||||||
|
**Recommended values:**
|
||||||
|
- Small projects: `20-30`
|
||||||
|
- Medium projects: `50`
|
||||||
|
- Large feature branches: `100+`
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
# Local (current repository only)
|
||||||
|
git config absorb.maxStack 50
|
||||||
|
|
||||||
|
# Global (all repositories)
|
||||||
|
git config --global absorb.maxStack 50
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 50
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning message when limit reached:**
|
||||||
|
```
|
||||||
|
WARN stack limit reached, limit: 10
|
||||||
|
```
|
||||||
|
|
||||||
|
**Alternative:** Use `--base <branch>` flag to specify range without changing config:
|
||||||
|
```bash
|
||||||
|
git absorb --base main # searches all commits since main
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `oneFixupPerCommit`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Generate only one fixup commit per target commit instead of per hunk.
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Multiple fixup commits if multiple hunks absorb into same commit
|
||||||
|
- `true`: Single consolidated fixup commit per target
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Prefer cleaner rebase history
|
||||||
|
- Don't need per-hunk granularity
|
||||||
|
- Many small changes to same commits
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.oneFixupPerCommit true
|
||||||
|
git config --global absorb.oneFixupPerCommit true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
oneFixupPerCommit = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example difference:**
|
||||||
|
|
||||||
|
Without `oneFixupPerCommit`:
|
||||||
|
```
|
||||||
|
fixup! Add feature X (for hunk 1)
|
||||||
|
fixup! Add feature X (for hunk 2)
|
||||||
|
fixup! Add feature X (for hunk 3)
|
||||||
|
```
|
||||||
|
|
||||||
|
With `oneFixupPerCommit`:
|
||||||
|
```
|
||||||
|
fixup! Add feature X (all hunks consolidated)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Command-line alternative:**
|
||||||
|
```bash
|
||||||
|
git absorb --one-fixup-per-commit
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `autoStageIfNothingStaged`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Automatically stage all changes when nothing is staged.
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Only consider explicitly staged files (requires `git add`)
|
||||||
|
- `true`: Auto-stage all changes if index is empty, unstage remainder after absorb
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Frequently run `git add .` before absorbing
|
||||||
|
- Want streamlined workflow
|
||||||
|
- Trust git-absorb with all working directory changes
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.autoStageIfNothingStaged true
|
||||||
|
git config --global absorb.autoStageIfNothingStaged true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
autoStageIfNothingStaged = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Workflow with this enabled:**
|
||||||
|
```bash
|
||||||
|
# Make changes (don't stage)
|
||||||
|
vim file1.py file2.py
|
||||||
|
|
||||||
|
# Run absorb directly (no git add needed)
|
||||||
|
git absorb --and-rebase
|
||||||
|
# -> auto-stages all changes
|
||||||
|
# -> absorbs what it can
|
||||||
|
# -> unstages remainder
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning:** Be careful with this if you have unrelated changes in working directory.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `fixupTargetAlwaysSHA`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Always use commit SHA in fixup messages instead of commit summary.
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Use commit summary if unique, fall back to SHA for duplicates
|
||||||
|
- `true`: Always use SHA
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Commit messages have many duplicates
|
||||||
|
- Prefer consistency in fixup references
|
||||||
|
- Working with auto-generated commit messages
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.fixupTargetAlwaysSHA true
|
||||||
|
git config --global absorb.fixupTargetAlwaysSHA true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
fixupTargetAlwaysSHA = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example difference:**
|
||||||
|
|
||||||
|
Default (`false`):
|
||||||
|
```
|
||||||
|
fixup! Add user authentication
|
||||||
|
fixup! abc123 (if "Add user authentication" appears multiple times)
|
||||||
|
```
|
||||||
|
|
||||||
|
With `fixupTargetAlwaysSHA = true`:
|
||||||
|
```
|
||||||
|
fixup! abc123
|
||||||
|
fixup! def456
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `forceAuthor`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Generate fixups for commits authored by anyone, not just you.
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Only modify your own commits (filtered by git author)
|
||||||
|
- `true`: Can modify any author's commits
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Pair programming environments
|
||||||
|
- Shared feature branches with multiple authors
|
||||||
|
- Taking over someone else's work
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.forceAuthor true
|
||||||
|
git config --global absorb.forceAuthor true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
forceAuthor = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Security consideration:** Only enable if you have permission to modify others' commits.
|
||||||
|
|
||||||
|
**Command-line alternative:**
|
||||||
|
```bash
|
||||||
|
git absorb --force-author
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `forceDetach`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Allow generating fixups when HEAD is detached (not on a branch).
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Refuse to run when HEAD is detached
|
||||||
|
- `true`: Run even in detached HEAD state
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Frequently work in detached HEAD state
|
||||||
|
- Using git-absorb during cherry-pick/bisect workflows
|
||||||
|
- Advanced git workflows
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.forceDetach true
|
||||||
|
git config --global absorb.forceDetach true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
forceDetach = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Warning:** Detached HEAD state can be confusing. Only enable if you understand the implications.
|
||||||
|
|
||||||
|
**Command-line alternative:**
|
||||||
|
```bash
|
||||||
|
git absorb --force-detach
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `createSquashCommits`
|
||||||
|
|
||||||
|
**Default:** `false`
|
||||||
|
|
||||||
|
**Purpose:** Generate squash commits instead of fixup commits.
|
||||||
|
|
||||||
|
**Effect:**
|
||||||
|
- `false`: Create `fixup!` commits (message discarded during autosquash)
|
||||||
|
- `true`: Create `squash!` commits (message kept and editable during autosquash)
|
||||||
|
|
||||||
|
**When to enable:**
|
||||||
|
- Need to document why changes were added
|
||||||
|
- Want to edit commit messages during rebase
|
||||||
|
- Organizational requirements for commit message detail
|
||||||
|
|
||||||
|
**Configuration:**
|
||||||
|
```bash
|
||||||
|
git config absorb.createSquashCommits true
|
||||||
|
git config --global absorb.createSquashCommits true
|
||||||
|
```
|
||||||
|
|
||||||
|
**In .gitconfig:**
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
createSquashCommits = true
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example difference:**
|
||||||
|
|
||||||
|
With `fixup!` (default):
|
||||||
|
```
|
||||||
|
fixup! Add feature X
|
||||||
|
# During rebase: message discarded, change absorbed silently
|
||||||
|
```
|
||||||
|
|
||||||
|
With `squash!` (createSquashCommits = true):
|
||||||
|
```
|
||||||
|
squash! Add feature X
|
||||||
|
# During rebase: editor opens, can edit combined message
|
||||||
|
```
|
||||||
|
|
||||||
|
**Command-line alternative:**
|
||||||
|
```bash
|
||||||
|
git absorb --squash
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Scope
|
||||||
|
|
||||||
|
### Local vs Global
|
||||||
|
|
||||||
|
**Local** (repository-specific):
|
||||||
|
```bash
|
||||||
|
git config absorb.maxStack 50
|
||||||
|
```
|
||||||
|
- Stored in `.git/config`
|
||||||
|
- Only affects current repository
|
||||||
|
- Use for project-specific settings
|
||||||
|
|
||||||
|
**Global** (all repositories):
|
||||||
|
```bash
|
||||||
|
git config --global absorb.maxStack 50
|
||||||
|
```
|
||||||
|
- Stored in `~/.gitconfig`
|
||||||
|
- Affects all repositories
|
||||||
|
- Use for personal preferences
|
||||||
|
|
||||||
|
### Checking Current Configuration
|
||||||
|
|
||||||
|
**View all absorb settings:**
|
||||||
|
```bash
|
||||||
|
git config --get-regexp absorb
|
||||||
|
```
|
||||||
|
|
||||||
|
**View specific setting:**
|
||||||
|
```bash
|
||||||
|
git config absorb.maxStack
|
||||||
|
```
|
||||||
|
|
||||||
|
**View with source:**
|
||||||
|
```bash
|
||||||
|
git config --list --show-origin | grep absorb
|
||||||
|
```
|
||||||
|
|
||||||
|
### Removing Configuration
|
||||||
|
|
||||||
|
**Remove local setting:**
|
||||||
|
```bash
|
||||||
|
git config --unset absorb.maxStack
|
||||||
|
```
|
||||||
|
|
||||||
|
**Remove global setting:**
|
||||||
|
```bash
|
||||||
|
git config --global --unset absorb.maxStack
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recommended Configurations
|
||||||
|
|
||||||
|
### Conservative (default behavior)
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 10
|
||||||
|
oneFixupPerCommit = false
|
||||||
|
autoStageIfNothingStaged = false
|
||||||
|
fixupTargetAlwaysSHA = false
|
||||||
|
forceAuthor = false
|
||||||
|
forceDetach = false
|
||||||
|
createSquashCommits = false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Balanced (recommended for most users)
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 50
|
||||||
|
oneFixupPerCommit = true
|
||||||
|
autoStageIfNothingStaged = false
|
||||||
|
fixupTargetAlwaysSHA = false
|
||||||
|
forceAuthor = false
|
||||||
|
forceDetach = false
|
||||||
|
createSquashCommits = false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aggressive (streamlined workflow)
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 100
|
||||||
|
oneFixupPerCommit = true
|
||||||
|
autoStageIfNothingStaged = true
|
||||||
|
fixupTargetAlwaysSHA = false
|
||||||
|
forceAuthor = true
|
||||||
|
forceDetach = false
|
||||||
|
createSquashCommits = false
|
||||||
|
```
|
||||||
|
|
||||||
|
### Team collaboration
|
||||||
|
```toml
|
||||||
|
[absorb]
|
||||||
|
maxStack = 50
|
||||||
|
oneFixupPerCommit = true
|
||||||
|
autoStageIfNothingStaged = false
|
||||||
|
fixupTargetAlwaysSHA = true
|
||||||
|
forceAuthor = true # Allow fixing teammates' commits
|
||||||
|
forceDetach = false
|
||||||
|
createSquashCommits = false
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Command-Line Flags Override Configuration
|
||||||
|
|
||||||
|
All configuration options can be overridden with command-line flags:
|
||||||
|
|
||||||
|
| Configuration | Command-Line Flag |
|
||||||
|
|--------------|-------------------|
|
||||||
|
| `oneFixupPerCommit` | `--one-fixup-per-commit` / `-F` |
|
||||||
|
| `forceAuthor` | `--force-author` |
|
||||||
|
| `forceDetach` | `--force-detach` |
|
||||||
|
| `createSquashCommits` | `--squash` / `-s` |
|
||||||
|
| `maxStack` | `--base <commit>` |
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```bash
|
||||||
|
# Even with forceAuthor = false in config
|
||||||
|
git absorb --force-author # Will absorb into any author's commits
|
||||||
|
```
|
||||||
Reference in New Issue
Block a user