Git Commands Design
Vision
Replicate familiar git commands in repoindex, allowing users to run git operations on repositories through the VFS. This is especially powerful in the shell where users can execute git commands on multiple repositories at once.
Key Design Principles
- Familiar Interface: Commands should feel like native git
- VFS-Aware: Work with VFS paths, not just filesystem paths
- Multi-Repo: Can operate on multiple repositories simultaneously
- Shell-First: Optimized for interactive shell use, but CLI works too
- Non-Destructive Defaults: Require confirmation for destructive operations
Use Cases
In Shell
# Navigate to VFS location
repoindex:/> cd /by-tag/work/active
# Run git status on ALL repos with that tag
repoindex:/by-tag/work/active> git status
# See recent commits across all active work repos
repoindex:/by-tag/work/active> git log --oneline -5
# Pull updates for all active work repos
repoindex:/by-tag/work/active> git pull
# Navigate to specific repo
repoindex:/> cd /repos/myproject
# Git commands work on single repo
repoindex:/repos/myproject> git log --graph --all
repoindex:/repos/myproject> git diff
repoindex:/repos/myproject> git commit -m "Update"
In CLI
# Status for specific VFS path
repoindex git status /by-tag/work/active
# Log for specific repo
repoindex git log /repos/myproject --oneline -5
# Pull all repos in directory
repoindex git pull /by-tag/needs-update
# Diff across multiple repos
repoindex git diff --name-status /by-language/Python
Command Categories
Read-Only Commands (Safe, No Confirmation)
git status- Show working tree statusgit log- Show commit historygit diff- Show changesgit show- Show commit detailsgit branch- List branchesgit remote- Show remotesgit ls-files- List tracked filesgit blame- Show line-by-line authorship
State-Changing Commands (Require Confirmation)
git pull- Pull from remotegit fetch- Fetch from remotegit push- Push to remote (with --dry-run default?)git checkout/git switch- Switch branchesgit stash- Stash changesgit clean- Remove untracked files
Write Commands (Require Explicit Confirmation)
git add- Stage changesgit commit- Commit changesgit reset- Reset changesgit revert- Revert commitsgit merge- Merge branchesgit rebase- Rebase branches
Implementation Structure
Examples:
# CLI mode - path is explicit
repoindex git status /by-tag/work/active
repoindex git log /repos/myproject --oneline -10
repoindex git pull /by-tag/needs-update --confirm
# Shell mode - path is from cwd
repoindex:/by-tag/work/active> git status
repoindex:/repos/myproject> git log --oneline -10
repoindex:/by-tag/needs-update> git pull
Output Formats
Single Repository
repoindex git status /repos/myproject
Repository: myproject (/home/user/repos/myproject)
On branch: main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
modified: README.md
modified: src/main.py
Multiple Repositories
repoindex git status /by-tag/work/active
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Repository: myproject
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
On branch: main
Modified: 2 files
Untracked: 0 files
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Repository: another-project
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
On branch: develop
Clean working tree
Summary: 2 repositories, 1 with changes
JSONL Mode
repoindex git status /by-tag/work/active --json
{"repo": "myproject", "path": "/home/user/repos/myproject", "branch": "main", "clean": false, "modified": 2}
{"repo": "another-project", "path": "/home/user/repos/another", "branch": "develop", "clean": true, "modified": 0}
Command-Specific Designs
git status
Usage: repoindex git status [VFS_PATH] [OPTIONS]
Show working tree status for repositories.
Options:
--short, -s Show short format
--branch, -b Show branch info
--json Output as JSONL
--dirty-only Show only repos with changes
git log
Usage: repoindex git log [VFS_PATH] [OPTIONS]
Show commit history.
Options:
--oneline Show one line per commit
--graph Show commit graph
--all Show all branches
-n, --max-count N Limit to N commits
--since DATE Show commits since date
--author AUTHOR Filter by author
--json Output as JSONL
git pull
Usage: repoindex git pull [VFS_PATH] [OPTIONS]
Pull changes from remote.
Options:
--dry-run Show what would be pulled
--confirm Require confirmation for each repo
--no-confirm Don't require confirmation (use with caution!)
--parallel Pull repos in parallel
--json Output as JSONL
git diff
Usage: repoindex git diff [VFS_PATH] [OPTIONS]
Show changes.
Options:
--name-only Show only names
--name-status Show names with status
--stat Show stats
--cached, --staged Show staged changes
--json Output as JSONL
Shell Integration
In the shell, git commands should:
-
Use current VFS directory as default path
-
Support relative VFS paths
-
Work on single repos
Safety Features
Confirmation Prompts
repoindex git pull /by-tag/work/active
Found 5 repositories. Pull changes? [y/N]: y
Pulling: myproject... ✓ (already up to date)
Pulling: another-project... ✓ (fast-forward, 3 commits)
Pulling: third-project... ✗ (merge conflict, skipped)
Summary: 2/5 successful, 1 failed
Dry Run Mode
repoindex git push /by-tag/ready-to-publish --dry-run
Would push to remote:
myproject (main): 2 commits
another-project (develop): 1 commit
Use --confirm to actually push.
Implementation Plan
Phase 1: Read-Only Commands
- Implement
git status - Implement
git log - Implement
git diff - Implement
git show - Implement
git branch
Phase 2: Fetch Operations
- Implement
git fetch - Implement
git pull(with confirmation) - Implement
git remote
Phase 3: Write Operations
- Implement
git add - Implement
git commit - Implement
git push(with confirmation) - Implement
git stash
Phase 4: Advanced Operations
- Implement
git checkout/git switch - Implement
git merge - Implement
git rebase - Implement
git reset
File Structure
repoindex/commands/git.py # Main git command group
repoindex/git_ops/
__init__.py
status.py # Git status operations
log.py # Git log operations
diff.py # Git diff operations
pull.py # Git pull operations
commit.py # Git commit operations
utils.py # Common git utilities
Key Implementation Details
Multi-Repo Execution
def execute_git_on_repos(repos: List[str], git_command: str,
parallel: bool = False,
confirm: bool = True) -> Generator[Dict, None, None]:
"""Execute git command on multiple repositories."""
if confirm and len(repos) > 1:
if not click.confirm(f"Execute on {len(repos)} repositories?"):
return
if parallel:
# Use threading/multiprocessing
with ThreadPoolExecutor() as executor:
futures = {executor.submit(run_git, repo, git_command): repo
for repo in repos}
for future in as_completed(futures):
yield future.result()
else:
# Sequential execution
for repo in repos:
yield run_git(repo, git_command)
VFS Path Resolution
def get_repos_from_vfs_path(vfs_path: str) -> List[str]:
"""Get all repository paths from a VFS path."""
vfs = build_vfs_structure(load_config())
node = resolve_vfs_path(vfs, vfs_path)
if node['type'] == 'repository':
return [node['path']]
elif node['type'] == 'symlink':
return [node['path']]
elif node['type'] == 'directory':
# Collect all repos in this directory recursively
return collect_repos_from_node(node)
Benefits
- Familiar Commands: Users already know git
- Multi-Repo Power: Operate on many repos at once
- VFS Integration: Natural fit with VFS navigation
- Flexible: Works in both CLI and shell
- Safe: Confirmation prompts prevent accidents
- Scriptable: JSONL output for automation
Example Workflows
Daily Status Check
# In shell
repoindex:/> cd /by-tag/work/active
repoindex:/by-tag/work/active> git status --dirty-only
# Shows only repos with uncommitted changes
Pull All Work Repos
# In CLI
repoindex git pull /by-tag/work --confirm
# Pulls updates for all work-tagged repos with confirmation
View Recent Activity
# In shell
repoindex:/by-tag/client/acme> git log --since="1 week ago" --oneline
# Shows commits from last week across all client repos
Bulk Operations
# Push all ready repos
repoindex git push /by-tag/ready-to-publish --dry-run # Check first
repoindex git push /by-tag/ready-to-publish --confirm # Then push
Questions to Consider
- Should we allow glob patterns in VFS paths?
/by-tag/work/* - Should we support git aliases/custom shortcuts?
- Should there be a
--allflag to run on all repos? - How to handle repos in different states (some ahead, some behind)?
- Should we add repoindex-specific enhancements (like auto-fix, bulk tagging based on git state)?
Next Steps
- Implement basic
git statuscommand - Test with multiple repos
- Add to shell as a command
- Iterate based on usage