agentsclimarketplace

Local sync

Skill getpipher/skills/skills/git-tools/skills/local-sync

Monorepo of @getpipher/* pi-packages and framework-agnostic Agent Skills β€” git workflows, quality, workspace, Solana, infra playbooks.

Install
npx -y skills add getpipher/skills --skill local-sync

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Comprehensive git synchronization - fetch all remotes, update all branches, and ensure local repo matches remote completely (dual-remote aware)

SKILL.md

12.7 KB, ~3.3k tokens by cl100k_base, as published. Nobody here has run it

Bismillah! I'll perform a comprehensive synchronization of your local repository with all remote repositories to ensure nothing is left behind.

Arguments provided: $ARGUMENTS

Comprehensive Local-Remote Synchronization (Dual-Remote Aware)

This command ensures your local repository is completely synchronized with all remote repositories. Fully supports dual-remote setups (GitHub + GitLab) and multi-remote configurations.

Supported Arguments

  • --cleanup - Remove obsolete local branches (only if not on ANY remote)
  • --create-missing - Create local tracking branches for new remote branches
  • --force - Override local changes with remote versions
  • --prefer-remote <name> - Preferred remote for branch creation (default: origin)

Implementation Steps

Step 1: Pre-sync Repository Analysis & Remote Detection

echo "πŸ“Š **Repository Analysis**"
echo ""

# Check for uncommitted changes
if [[ -n $(git status --porcelain) ]]; then
    echo "⚠️  Warning: You have uncommitted changes:"
    git status --short
    echo ""
fi

# Detect all configured remotes
echo "πŸ”— **Configured Remotes:**"
remotes=($(git remote))
for remote in "${remotes[@]}"; do
    url=$(git remote get-url "$remote" 2>/dev/null)
    echo "  β”œβ”€ $remote β†’ $url"
done
echo ""

# Current branch info
current_branch=$(git branch --show-current)
echo "🌿 **Current Branch:** $current_branch"
echo ""

Step 2: Comprehensive Fetch from All Remotes

echo "πŸ”„ **Fetching from all remotes...**"
echo ""

fetch_failed=()
for remote in "${remotes[@]}"; do
    echo -n "  Fetching $remote... "
    if git fetch "$remote" --tags --prune 2>/dev/null; then
        echo "βœ“"
    else
        echo "βœ— (failed)"
        fetch_failed+=("$remote")
    fi
done

if [[ ${#fetch_failed[@]} -gt 0 ]]; then
    echo ""
    echo "⚠️  Failed to fetch from: ${fetch_failed[*]}"
fi
echo ""

Step 3: Current Branch Synchronization

echo "πŸ“₯ **Synchronizing current branch ($current_branch)...**"

# Check if current branch has upstream
if git rev-parse --verify @{upstream} >/dev/null 2>&1; then
    upstream=$(git rev-parse --abbrev-ref @{upstream})
    echo "  Upstream: $upstream"

    # Check ahead/behind status
    ahead=$(git rev-list --count @{upstream}..HEAD 2>/dev/null || echo 0)
    behind=$(git rev-list --count HEAD..@{upstream} 2>/dev/null || echo 0)

    if [[ $behind -gt 0 ]]; then
        echo "  Behind by $behind commit(s), pulling..."
        git pull --ff-only 2>/dev/null || {
            echo "  ⚠️  Fast-forward failed, attempting merge..."
            git pull --no-ff
        }
    else
        echo "  βœ“ Already up to date"
    fi

    if [[ $ahead -gt 0 ]]; then
        echo "  ⚠️  Ahead by $ahead commit(s) - consider pushing"
    fi
else
    echo "  ⚠️  No upstream tracking branch configured"
fi
echo ""

Step 4: Update All Local Tracking Branches

echo "πŸ”„ **Updating all local tracking branches...**"
echo ""

git for-each-ref --format='%(refname:short) %(upstream:short)' refs/heads | while read local upstream; do
    if [[ -n "$upstream" && "$local" != "$current_branch" ]]; then
        remote_name="${upstream%%/*}"

        # Check if upstream exists
        if git rev-parse --verify "$upstream" >/dev/null 2>&1; then
            local_sha=$(git rev-parse "$local")
            remote_sha=$(git rev-parse "$upstream")

            if [[ "$local_sha" != "$remote_sha" ]]; then
                # Check if can fast-forward
                if git merge-base --is-ancestor "$local" "$upstream" 2>/dev/null; then
                    echo -n "  Updating $local from $upstream... "
                    git update-ref "refs/heads/$local" "$remote_sha" && echo "βœ“" || echo "βœ—"
                else
                    echo "  ⚠️  $local has diverged from $upstream (manual merge needed)"
                fi
            fi
        fi
    fi
done
echo ""

Step 5: Discover Remote Branches Across All Remotes

echo "πŸ” **Discovering remote branches...**"
echo ""

declare -A branch_remotes  # branch_name -> "remote1,remote2"
declare -A new_branches    # branches not in local

# Collect all remote branches and which remotes have them
for remote in "${remotes[@]}"; do
    while read -r remote_branch; do
        [[ -z "$remote_branch" ]] && continue
        [[ "$remote_branch" == *"/HEAD" ]] && continue

        branch_name="${remote_branch#$remote/}"

        # Track which remotes have this branch
        if [[ -n "${branch_remotes[$branch_name]}" ]]; then
            branch_remotes[$branch_name]="${branch_remotes[$branch_name]},$remote"
        else
            branch_remotes[$branch_name]="$remote"
        fi

        # Check if local branch exists
        if ! git show-ref --verify --quiet "refs/heads/$branch_name"; then
            new_branches[$branch_name]="${branch_remotes[$branch_name]}"
        fi
    done < <(git branch -r --list "$remote/*" | sed 's/^[[:space:]]*//')
done

# Display new remote branches
if [[ ${#new_branches[@]} -gt 0 ]]; then
    echo "πŸ†• **New remote branches (not local):**"
    for branch in "${!new_branches[@]}"; do
        remotes_list="${new_branches[$branch]}"
        # Determine display label
        if [[ "$remotes_list" == *","* ]]; then
            echo "  β”œβ”€ $branch (on: $remotes_list)"
        else
            echo "  β”œβ”€ $branch ($remotes_list only)"
        fi
    done
    echo ""
else
    echo "  βœ“ No new remote branches found"
    echo ""
fi

Step 6: Create Missing Local Branches (if --create-missing)

if [[ "$ARGUMENTS" == *"--create-missing"* ]]; then
    echo "πŸ“ **Creating local tracking branches...**"

    # Determine preferred remote
    prefer_remote="origin"
    if [[ "$ARGUMENTS" =~ --prefer-remote[[:space:]]+([^[:space:]]+) ]]; then
        prefer_remote="${BASH_REMATCH[1]}"
    fi
    echo "  Preferred remote: $prefer_remote"
    echo ""

    for branch in "${!new_branches[@]}"; do
        remotes_list="${new_branches[$branch]}"

        # Select source remote (prefer specified, fallback to first available)
        if [[ "$remotes_list" == *"$prefer_remote"* ]]; then
            source_remote="$prefer_remote"
        else
            source_remote="${remotes_list%%,*}"
        fi

        echo -n "  Creating $branch from $source_remote/$branch... "
        if git branch --track "$branch" "$source_remote/$branch" 2>/dev/null; then
            echo "βœ“"
        else
            echo "βœ—"
        fi
    done
    echo ""
fi

Step 7: Smart Cleanup Obsolete Branches (if --cleanup)

Check if branch exists on ANY remote before considering it obsolete.

if [[ "$ARGUMENTS" == *"--cleanup"* ]]; then
    echo "πŸ—‘οΈ  **Checking for obsolete local branches...**"
    echo ""

    obsolete_branches=()

    git for-each-ref --format='%(refname:short)' refs/heads | while read local_branch; do
        # Skip current branch
        [[ "$local_branch" == "$current_branch" ]] && continue

        # Skip main/master/dev protected branches
        [[ "$local_branch" =~ ^(main|master|dev|develop)$ ]] && continue

        exists_on_remote=false

        # Check if branch exists on ANY remote
        for remote in "${remotes[@]}"; do
            if git ls-remote --heads "$remote" "$local_branch" 2>/dev/null | grep -q .; then
                exists_on_remote=true
                break
            fi
        done

        if [[ "$exists_on_remote" == false ]]; then
            # Double-check: does it have upstream that's gone?
            upstream=$(git rev-parse --abbrev-ref "$local_branch@{upstream}" 2>/dev/null)
            if [[ -n "$upstream" ]] || [[ -z "$(git log -1 --since='3 months ago' "$local_branch" 2>/dev/null)" ]]; then
                echo "  ⚠️  $local_branch - not on any remote"
                obsolete_branches+=("$local_branch")
            fi
        fi
    done

    if [[ ${#obsolete_branches[@]} -gt 0 ]]; then
        echo ""
        echo "Found ${#obsolete_branches[@]} obsolete branch(es)."

        if [[ "$ARGUMENTS" == *"--force"* ]]; then
            for branch in "${obsolete_branches[@]}"; do
                git branch -D "$branch" && echo "  Deleted: $branch"
            done
        else
            echo "Run with --force to auto-delete, or delete manually:"
            for branch in "${obsolete_branches[@]}"; do
                echo "  git branch -d $branch"
            done
        fi
    else
        echo "  βœ“ No obsolete branches found"
    fi
    echo ""
fi

Step 8: Comprehensive Multi-Remote Status Report

echo ""
echo "═══════════════════════════════════════════════════════════════"
echo "πŸ”„ **SYNCHRONIZATION COMPLETE**"
echo "═══════════════════════════════════════════════════════════════"
echo ""

# Remote status
echo "πŸ”— **Remotes Synchronized:**"
for remote in "${remotes[@]}"; do
    url=$(git remote get-url "$remote" 2>/dev/null)
    if [[ " ${fetch_failed[*]} " =~ " $remote " ]]; then
        echo "  β”œβ”€ $remote βœ— (fetch failed)"
    else
        echo "  β”œβ”€ $remote βœ“"
    fi
done
echo ""

# Branch status with ahead/behind for all tracking branches
echo "🌿 **Local Branches Status:**"
git for-each-ref --format='%(refname:short) %(upstream:short) %(upstream:track)' refs/heads | while read local upstream track; do
    if [[ -n "$upstream" ]]; then
        echo "  $local β†’ $upstream $track"
    else
        echo "  $local (no upstream)"
    fi
done
echo ""

# Summary of remote-only branches per remote
echo "🌐 **Remote-Only Branches:**"
for remote in "${remotes[@]}"; do
    count=0
    while read -r remote_branch; do
        [[ -z "$remote_branch" ]] && continue
        [[ "$remote_branch" == *"/HEAD" ]] && continue
        branch_name="${remote_branch#$remote/}"
        if ! git show-ref --verify --quiet "refs/heads/$branch_name"; then
            ((count++))
        fi
    done < <(git branch -r --list "$remote/*" | sed 's/^[[:space:]]*//')
    echo "  $remote: $count new branch(es)"
done
echo ""

# Recent activity
echo "πŸ“ˆ **Recent Activity (last 10 commits across all branches):**"
git log --oneline --graph --decorate --all -10
echo ""

# Sync summary
echo "βœ… **Sync Summary:**"
echo "  β€’ Remotes fetched: ${#remotes[@]} (failed: ${#fetch_failed[@]})"
echo "  β€’ Current branch: $current_branch"
echo "  β€’ Cleanup: $(if [[ "$ARGUMENTS" == *"--cleanup"* ]]; then echo "Yes"; else echo "No (use --cleanup)"; fi)"
echo "  β€’ Create missing: $(if [[ "$ARGUMENTS" == *"--create-missing"* ]]; then echo "Yes"; else echo "No (use --create-missing)"; fi)"
echo ""
echo "πŸš€ **Repository is now fully synchronized with all remotes!**"

Usage Examples

# Basic synchronization (all remotes)
/local-sync

# Sync and create local branches for all new remote branches
/local-sync --create-missing

# Sync and create branches, preferring gitlab as source
/local-sync --create-missing --prefer-remote gitlab

# Sync and clean up obsolete local branches (checks ALL remotes)
/local-sync --cleanup

# Complete sync with all options
/local-sync --create-missing --cleanup

# Force sync (override local changes, auto-delete obsolete)
/local-sync --force --cleanup

Dual-Remote Behavior

ScenarioBehavior
Branch on GitHub onlyShows as "(origin only)" or "(github only)"
Branch on GitLab onlyShows as "(gitlab only)"
Branch on bothShows as "(on: origin,gitlab)"
Local branch, gone from origin but exists on gitlabNOT deleted - still on a remote
Local branch, gone from ALL remotesMarked obsolete, safe to delete
--create-missingUses --prefer-remote or first available

Safety Features

  1. Multi-Remote Awareness: Never deletes branches that exist on ANY configured remote
  2. Protected Branches: Skips main/master/dev/develop from cleanup
  3. Uncommitted Changes Warning: Alerts before operations
  4. Fetch Failure Handling: Continues sync even if one remote fails
  5. Non-Destructive Default: Requires --force for auto-deletion
  6. Clear Reporting: Shows exactly which remote(s) have each branch

This command ensures your local repository stays completely synchronized with all remotes, respecting your dual-push GitHub + GitLab setup. InshaAllah, this will keep your development workflow smooth and up-to-date!

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 327,132. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.