Selective Copy — Clean Branch Creation

SkillFiles & storage

Create clean git branches from feature work, excluding agent-ops files. Use for PR preparation.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Selective Copy — Clean Branch Creation skill

What this skill tells your AI

The instructions your AI receives, as published by diegosouzapw/awesome-omni-skill in skills/data-ai/agent-ops-selective-copy/SKILL.md and read by ahel’s review.

Create a clean git branch from feature work, excluding specific paths. Platform agnostic.

Works with or without aoc CLI. Uses standard git commands.


Purpose

Create a new branch containing feature work while excluding agent/workflow files for clean PRs.


CRITICAL: No Assumptions

NEVER assume. NEVER guess. ALWAYS ask.

Before creating ANY clean branch, confirm with user:

If unclear about...ASK
Source branch"Which branch contains your feature work?"
Clean branch name"I'll create {name}. Does this look right?"
Base branch"Which branch should excluded paths be restored from? (e.g., develop, main)"
What to exclude"What paths should I exclude? (Default: .agent/, .github/)"

If ANY of these are ambiguous:

  1. Stop
  2. Ask ONE question at a time
  3. Wait for explicit confirmation
  4. Only proceed when ALL inputs are confirmed

NEVER:

  • Guess the base branch
  • Assume exclusions without asking
  • Create a branch without showing the user the exact name first
  • Proceed if source branch is unclear

Prerequisites

MANDATORY: File Audit Trail

The file-created.log MUST exist before proceeding. This ensures we know which files to exclude.

If .agent/log/created-files.log does not exist:

  1. Generate it from git history (see Generation Procedure below)
  2. Present to user for validation
  3. Only proceed after user confirms the list

This prevents accidental inclusion of agent-ops files in the clean branch.


Invocation

User says something like:

  • "Create a clean branch for PR"
  • "Make a branch without .agent and .github changes"
  • "Prepare my feature for code review"

Arguments

ArgumentDescriptionDefault
source_branchFeature branch with workCurrent branch
new_branchName for clean branch{source_branch}-clean
base_branchBranch to restore excluded paths fromAuto-detect
exclusionsPaths/patterns to excludePrompt user

Workflow

1. Gather Requirements

If not provided, ask:

  1. Source branch (default: current)
  2. New branch name (default: {current}-clean)
  3. Base branch — try auto-detect first:
# PowerShell: Find merge-base with main or develop
$mainBase = git merge-base HEAD main 2>$null
$devBase = git merge-base HEAD develop 2>$null

if ($mainBase) { $baseBranch = "main" }
elseif ($devBase) { $baseBranch = "develop" }
else {
    # Ask user
    Write-Host "Could not auto-detect base branch. Which branch was this feature branched from?"
}
# Bash: Find merge-base
main_base=$(git merge-base HEAD main 2>/dev/null)
dev_base=$(git merge-base HEAD develop 2>/dev/null)

if [ -n "$main_base" ]; then
    base_branch="main"
elif [ -n "$dev_base" ]; then
    base_branch="develop"
else
    echo "Could not auto-detect base branch. Which branch was this feature branched from?"
fi
  1. Exclusions — if not specified, prompt:
Would you like to exclude agent-ops files? This includes:
- `.agent/` directory
- `.github/skills/`, `.github/prompts/`, `.github/agents/`

Additionally, agent-ops created these files outside .agent/:
{list from .agent/log/created-files.log}

[1] Exclude all agent-ops files (recommended)
[2] Exclude only .agent/ and .github/
[3] Let me specify custom paths
[4] Don't exclude anything

2. Check and Generate Audit Trail (MANDATORY)

Before proceeding, verify .agent/log/created-files.log exists.

# PowerShell
$logPath = ".agent/log/created-files.log"
if (-not (Test-Path $logPath)) {
    Write-Host "⚠️  File audit trail not found: $logPath" -ForegroundColor Yellow
    Write-Host "Generating from git history..." -ForegroundColor Cyan
    # Proceed to generation
} else {
    Write-Host "✓ Audit trail found: $logPath" -ForegroundColor Green
    # Skip to step 3
}
# Bash
log_path=".agent/log/created-files.log"
if [ ! -f "$log_path" ]; then
    echo "⚠️  File audit trail not found: $log_path"
    echo "Generating from git history..."
    # Proceed to generation
else
    echo "✓ Audit trail found: $log_path"
    # Skip to step 3
fi

If log is missing, generate it:

Generation Procedure
  1. Find the branch point (where feature diverged from base):
# PowerShell
$baseBranch = "develop"  # or auto-detected
$branchPoint = git merge-base HEAD $baseBranch
Write-Host "Branch point: $branchPoint"
# Bash
base_branch="develop"
branch_point=$(git merge-base HEAD "$base_branch")
echo "Branch point: $branch_point"
  1. List files added since branch point (excluding .agent/ and .github/):
# PowerShell
$addedFiles = git diff --name-status --diff-filter=A $branchPoint HEAD |
    ForEach-Object { ($_ -split "\t")[1] } |
    Where-Object {
        $_ -notmatch "^\.agent/" -and
        $_ -notmatch "^\.github/skills/" -and
        $_ -notmatch "^\.github/prompts/" -and
        $_ -notmatch "^\.github/agents/"
    }

Write-Host "`nFiles added since branch point:" -ForegroundColor Cyan
$addedFiles | ForEach-Object { Write-Host "  CREATE $_" }
Write-Host "`nTotal: $($addedFiles.Count) files"
# Bash
added_files=$(git diff --name-status --diff-filter=A "$branch_point" HEAD |
    cut -f2 |
    grep -v "^\.agent/" |
    grep -v "^\.github/skills/" |
    grep -v "^\.github/prompts/" |
    grep -v "^\.github/agents/")

echo ""
echo "Files added since branch point:"
echo "$added_files" | while read -r file; do
    [ -n "$file" ] && echo "  CREATE $file"
done
echo ""
echo "Total: $(echo "$added_files" | grep -c .)"
  1. Present to user for validation (MANDATORY):
📋 Generated file list from git history:

  CREATE src/utils/helper.py
  CREATE tests/test_helper.py
  CREATE docs/PLANNING.md

Total: 3 files

⚠️  Please review this list carefully.

These files will be EXCLUDED from the clean branch.
Missing files may leak into PR. Extra files may be wrongly excluded.

Options:
[1] Approve and continue
[2] Edit list (will open in editor)
[3] Abort
  1. Save after user approval:
# PowerShell (only after user confirms)
$logDir = ".agent/log"
if (-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir -Force | Out-Null
}

$timestamp = Get-Date -Format "yyyy-MM-ddTHH:mm:ssZ"

# Write header
@"
# Agent-Ops File Creation Audit Trail
# Generated from git history on $timestamp
# Branch point: $branchPoint (from $baseBranch)
# User validated: YES
# --- Log entries below this line ---
"@ | Out-File -FilePath $logPath -Encoding utf8

# Write entries
foreach ($file in $addedFiles) {
    Add-Content -Path $logPath -Value "$timestamp CREATE $file"
}

Write-Host "✓ Audit trail saved: $logPath" -ForegroundColor Green
# Bash (only after user confirms)
log_dir=".agent/log"
mkdir -p "$log_dir"

timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)

# Write header
cat > "$log_path" << EOF
# Agent-Ops File Creation Audit Trail
# Generated from git history on $timestamp
# Branch point: $branch_point (from $base_branch)
# User validated: YES
# --- Log entries below this line ---
EOF

# Write entries
echo "$added_files" | while read -r file; do
    [ -n "$file" ] && echo "$timestamp CREATE $file" >> "$log_path"
done

echo "✓ Audit trail saved: $log_path"

3. Read Audit Trail

Check .agent/log/created-files.log for files created outside .agent/:

# PowerShell
$logPath = ".agent/log/created-files.log"
$createdFiles = Get-Content $logPath |
    Where-Object { $_ -match "^\d{4}-\d{2}-\d{2}" } |
    ForEach-Object {
        $parts = $_ -split " ", 3
        [PSCustomObject]@{
            Timestamp = $parts[0]
            Action = $parts[1]
            Path = $parts[2]
        }
    } |
    Where-Object { $_.Action -eq "CREATE" } |
    Select-Object -ExpandProperty Path

Write-Host "Files created by agent-ops:"
$createdFiles | ForEach-Object { Write-Host "  - $_" }
# Bash
echo "Files created by agent-ops:"
grep "^[0-9]" .agent/log/created-files.log |
    awk '$2 == "CREATE" { print "  - " $3 }'

4. Execute (Git-Based)

Step 1: Create worktree with new branch
# PowerShell
$sourceBranch = git branch --show-current
$newBranch = "$sourceBranch-clean"
$worktreePath = "../$newBranch"

git worktree add -b $newBranch $worktreePath HEAD
Set-Location $worktreePath
# Bash
source_branch=$(git branch --show-current)
new_branch="${source_branch}-clean"
worktree_path="../${new_branch}"

git worktree add -b "$new_branch" "$worktree_path" HEAD
cd "$worktree_path"
Step 2: Restore excluded directories from base branch
# PowerShell
$baseBranch = "develop"  # or detected/user-provided
$excludeDirs = @(".github", ".agent")

foreach ($dir in $excludeDirs) {
    git checkout $baseBranch -- $dir 2>$null
    if ($LASTEXITCODE -eq 0) {
        Write-Host "Restored $dir from $baseBranch"
    } else {
        Write-Host "$dir doesn't exist in $baseBranch (new directory)"
    }
}
# Bash
base_branch="develop"
exclude_dirs=(".github" ".agent")

for dir in "${exclude_dirs[@]}"; do
    if git checkout "$base_branch" -- "$dir" 2>/dev/null; then
        echo "Restored $dir from $base_branch"
    else
        echo "$dir doesn't exist in $base_branch (new directory)"
    fi
done
Step 3: Remove NEW files that don't exist in base

For files logged in audit trail that are new (not in base branch):

# PowerShell
foreach ($file in $createdFiles) {
    # Check if file exists in base branch
    $existsInBase = git ls-tree -r $baseBranch --name-only | Where-Object { $_ -eq $file }

    if (-not $existsInBase) {
        # File is new, remove from git tracking
        git rm --cached $file 2>$null
        Write-Host "Removed new file from tracking: $file"
    } else {
        # File exists in base, restore it
        git checkout $baseBranch -- $file 2>$null
        Write-Host "Restored $file from $baseBranch"
    }
}
# Bash
for file in "${created_files[@]}"; do
    if git ls-tree -r "$base_branch" --name-only | grep -q "^${file}$"; then
        # File exists in base, restore it
        git checkout "$base_branch" -- "$file" 2>/dev/null
        echo "Restored $file from $base_branch"
    else
        # File is new, remove from git tracking
        git rm --cached "$file" 2>/dev/null
        echo "Removed new file from tracking: $file"
    fi
done
Step 4: Commit the exclusions
# PowerShell
git add -A
git commit -m "chore: prepare clean branch for PR (exclude agent-ops files)"
# Bash
git add -A
git commit -m "chore: prepare clean branch for PR (exclude agent-ops files)"
Step 5: Create Exclusion Log

Create a log file for selective-merge to use later:

# PowerShell
$timestamp = Get-Date -Format "yyyy-MM-dd-HHmmss"
$logFile = ".agent/log/selective-copy-$newBranch-$timestamp.log"
$cleanBranchHash = git rev-parse HEAD
$sourceBranchHash = git rev-parse $sourceBranch

# Create log directory if needed
New-Item -ItemType Directory -Path ".agent/log" -Force | Out-Null

# Write log header
@"
# Selective Copy Exclusion Log
# Generated: $(Get-Date -Format "yyyy-MM-ddTHH:mm:ssK")
# Source Branch: $sourceBranch ($sourceBranchHash)
# Clean Branch: $newBranch ($cleanBranchHash)
# Base Branch: $baseBranch
# Excluded Paths: $($excludeDirs -join ", ")

# Format: {ACTION} {path}
# RESTORE = restored from base branch
# REMOVE = removed from tracking (new file not in base)

"@ | Out-File -FilePath $logFile -Encoding utf8

# Log each excluded directory
foreach ($dir in $excludeDirs) {
    Add-Content -Path $logFile -Value "RESTORE $dir"
}

# Log removed files from audit trail
foreach ($file in $createdFiles) {
    $existsInBase = git ls-tree -r $baseBranch --name-only | Where-Object { $_ -eq $file }
    if (-not $existsInBase) {
        Add-Content -Path $logFile -Value "REMOVE $file"
    } else {
        Add-Content -Path $logFile -Value "RESTORE $file"
    }
}

Write-Host "Exclusion log created: $logFile"
# Bash
timestamp=$(date +"%Y-%m-%d-%H%M%S")
log_file=".agent/log/selective-copy-${new_branch}-${timestamp}.log"
clean_branch_hash=$(git rev-parse HEAD)
source_branch_hash=$(git rev-parse "$source_branch")

# Create log directory if needed
mkdir -p ".agent/log"

# Write log header
cat > "$log_file" << EOF
# Selective Copy Exclusion Log
# Generated: $(date -Iseconds)
# Source Branch: $source_branch ($source_branch_hash)
# Clean Branch: $new_branch ($clean_branch_hash)
# Base Branch: $base_branch
# Excluded Paths: ${exclude_dirs[*]}

# Format: {ACTION} {path}
# RESTORE = restored from base branch
# REMOVE = removed from tracking (new file not in base)

EOF

# Log each excluded directory
for dir in "${exclude_dirs[@]}"; do
    echo "RESTORE $dir" >> "$log_file"
done

# Log removed files from audit trail
for file in "${created_files[@]}"; do
    if git ls-tree -r "$base_branch" --name-only | grep -q "^${file}$"; then
        echo "RESTORE $file" >> "$log_file"
    else
        echo "REMOVE $file" >> "$log_file"
    fi
done

echo "Exclusion log created: $log_file"

5. Verify

# PowerShell
Write-Host "`n=== Verification ===" -ForegroundColor Cyan

# Check status
git status

# Compare with base branch
Write-Host "`nChanges compared to ${baseBranch}:"
git diff $baseBranch --stat

# Verify excluded paths match base
Write-Host "`nVerifying exclusions:"
foreach ($dir in $excludeDirs) {
    $diff = git diff $baseBranch -- $dir
    if ([string]::IsNullOrEmpty($diff)) {
        Write-Host "  $dir matches $baseBranch ✓" -ForegroundColor Green
    } else {
        Write-Host "  $dir has differences from $baseBranch" -ForegroundColor Yellow
    }
}
# Bash
echo ""
echo "=== Verification ==="

# Check status
git status

# Compare with base branch
echo ""
echo "Changes compared to ${base_branch}:"
git diff "$base_branch" --stat

# Verify excluded paths match base
echo ""
echo "Verifying exclusions:"
for dir in "${exclude_dirs[@]}"; do
    if [ -z "$(git diff "$base_branch" -- "$dir")" ]; then
        echo "  $dir matches $base_branch ✓"
    else
        echo "  $dir has differences from $base_branch"
    fi
done

6. Validate Results (MANDATORY)

After creating the clean branch, validate using created-files.log as source of truth:

# PowerShell - Validation Script
Write-Host "`n=== Validation ===" -ForegroundColor Cyan

$validationPassed = $true
$issues = @()

# 1. Check created files exist in clean branch (they should be the feature work)
$createdFilesLog = ".agent/log/created-files.log"
if (Test-Path $createdFilesLog) {
    Write-Host "`nChecking feature files are present in clean branch..."

    $createdFiles = Get-Content $createdFilesLog |
        Where-Object { $_ -match "^\d{4}-\d{2}-\d{2}" -and $_ -match "CREATE" } |
        ForEach-Object { ($_ -split " ", 3)[2] } |
        Where-Object {
            $_ -notmatch "^\.agent/" -and
            $_ -notmatch "^\.github/skills/" -and
            $_ -notmatch "^\.github/prompts/" -and
            $_ -notmatch "^\.github/agents/"
        }

    foreach ($file in $createdFiles) {
        $existsInClean = git ls-tree -r HEAD --name-only | Where-Object { $_ -eq $file }
        if ($existsInClean) {
            Write-Host "  ✓ $file" -ForegroundColor Green
        } else {
            Write-Host "  ✗ MISSING: $file" -ForegroundColor Red
            $issues += "MISSING: $file (should be in clean branch)"
            $validationPassed = $false
        }
    }
}

# 2. Check NO agent-ops files leaked into clean branch
Write-Host "`nChecking for leaked agent-ops files..."

$leakedFiles = git ls-tree -r HEAD --name-only | Where-Object {
    $_ -match "^\.agent/" -or
    $_ -match "^\.github/skills/agent-ops-" -or
    $_ -match "^\.github/prompts/agent-ops-" -or
    $_ -match "^\.github/agents/agent-ops-"
}

if ($leakedFiles) {
    foreach ($leaked in $leakedFiles) {
        Write-Host "  ✗ LEAKED: $leaked" -ForegroundColor Red
        $issues += "LEAKED: $leaked (should NOT be in clean branch)"
    }
    $validationPassed = $false
} else {
    Write-Host "  ✓ No agent-ops files found" -ForegroundColor Green
}

# 3. Report
Write-Host "`n=== Validation Result ===" -ForegroundColor Cyan
if ($validationPassed) {
    Write-Host "✅ PASSED" -ForegroundColor Green
    Write-Host "   - All feature files present in clean branch"
    Write-Host "   - No agent-ops files leaked"
    Write-Host "   - Clean branch ready for PR"
} else {
    Write-Host "❌ FAILED" -ForegroundColor Red
    foreach ($issue in $issues) {
        Write-Host "   - $issue" -ForegroundColor Yellow
    }
    Write-Host "`nPlease review and fix before pushing."
}
# Bash - Validation Script
echo ""
echo "=== Validation ==="

validation_passed=true
issues=()

# 1. Check created files exist in clean branch
created_files_log=".agent/log/created-files.log"
if [ -f "$created_files_log" ]; then
    echo ""
    echo "Checking feature files are present in clean branch..."

    while IFS= read -r line; do
        if [[ "$line" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}.*CREATE ]]; then
            file=$(echo "$line" | awk '{print $3}')
            # Skip agent-ops files
            if [[ ! "$file" =~ ^\.agent/ && ! "$file" =~ ^\.github/skills/ && ! "$file" =~ ^\.github/prompts/ && ! "$file" =~ ^\.github/agents/ ]]; then
                if git ls-tree -r HEAD --name-only | grep -q "^${file}$"; then
                    echo "  ✓ $file"
                else
                    echo "  ✗ MISSING: $file"
                    issues+=("MISSING: $file (should be in clean branch)")
                    validation_passed=false
                fi
            fi
        fi
    done < "$created_files_log"
fi

# 2. Check NO agent-ops files leaked
echo ""
echo "Checking for leaked agent-ops files..."

leaked_files=$(git ls-tree -r HEAD --name-only | grep -E "^\.agent/|^\.github/skills/agent-ops-|^\.github/prompts/agent-ops-|^\.github/agents/agent-ops-")

if [ -n "$leaked_files" ]; then
    while IFS= read -r leaked; do
        echo "  ✗ LEAKED: $leaked"
        issues+=("LEAKED: $leaked (should NOT be in clean branch)")
    done <<< "$leaked_files"
    validation_passed=false
else
    echo "  ✓ No agent-ops files found"
fi

# 3. Report
echo ""
echo "=== Validation Result ==="
if [ "$validation_passed" = true ]; then
    echo "✅ PASSED"
    echo "   - All feature files present in clean branch"
    echo "   - No agent-ops files leaked"
    echo "   - Clean branch ready for PR"
else
    echo "❌ FAILED"
    for issue in "${issues[@]}"; do
        echo "   - $issue"
    done
    echo ""
    echo "Please review and fix before pushing."
fi

7. Report to User

✅ Clean branch created: {new_branch}

Location: {worktree_path}

Excluded:
- .github/ (restored from {base_branch})
- .agent/ (restored from {base_branch})
- {N} files from audit trail

Changes from {base_branch}:
{git diff --stat output}

Validation: PASSED ✓

Next steps:
1. Review changes: cd {worktree_path} && git log --oneline {base_branch}..HEAD
2. Push for PR: git push -u origin {new_branch}
3. Cleanup when done: git worktree remove {worktree_path}

Cleanup

When done with the clean branch:

# PowerShell
# Return to original repo
Set-Location ../{original-repo}

# Remove worktree (keeps branch)
git worktree remove ../{new_branch}

# Delete branch if no longer needed
git branch -D {new_branch}
# Bash
# Return to original repo
cd ../{original-repo}

# Remove worktree (keeps branch)
git worktree remove "../${new_branch}"

# Delete branch if no longer needed
git branch -D "${new_branch}"

Common Exclusion Presets

Clean PR (Recommended)

Directories: .github, .agent
Files: All from audit trail

Feature Only

Directories: .github, .agent, .vscode, docs
Files: *.md at root, audit trail files

Minimal (Agent Core Only)

Directories: .agent
Files: None

Error Handling

ErrorSolution
"fatal: not a git repository"Must run from git repo
"error: branch already exists"Use different name or delete existing
"fatal: worktree already exists"Remove existing worktree first
"error: pathspec did not match"Path doesn't exist in base branch (ok to skip)

Related Skills

  • agent-ops-git — General git operations
  • agent-ops-implementation — Creates files that get logged
  • agent-ops-validation — Run before creating clean branch

Signals

GitHub stars
57
Forks
19
Last commit
Mar 2026
Advanced
Catalog kind
skill
Gateway key
agent-ops-selective-copy
Source
github.com/diegosouzapw/awesome-omni-skill