{"id":46059367,"url":"https://github.com/narnaud/git-repos","last_synced_at":"2026-03-01T11:01:04.571Z","repository":{"id":328163476,"uuid":"1108940577","full_name":"narnaud/git-repos","owner":"narnaud","description":"Scan and manage git repositories with ease","archived":false,"fork":false,"pushed_at":"2026-02-28T16:56:50.000Z","size":380,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-28T16:57:09.461Z","etag":null,"topics":["cli","git","repository","rust"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/narnaud.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-12-03T05:54:45.000Z","updated_at":"2026-02-28T16:56:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/narnaud/git-repos","commit_stats":null,"previous_names":["narnaud/git-repos"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/narnaud/git-repos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narnaud%2Fgit-repos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narnaud%2Fgit-repos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narnaud%2Fgit-repos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narnaud%2Fgit-repos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/narnaud","download_url":"https://codeload.github.com/narnaud/git-repos/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/narnaud%2Fgit-repos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29967930,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T10:55:55.490Z","status":"ssl_error","status_checked_at":"2026-03-01T10:55:55.175Z","response_time":124,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","git","repository","rust"],"created_at":"2026-03-01T11:00:52.671Z","updated_at":"2026-03-01T11:01:04.554Z","avatar_url":"https://github.com/narnaud.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Git-Repos - 🔍 Scan and manage git repositories\n\n![Demo](assets/demo.gif)\n\n## About This Project\n\nThis project is an **experimentation** built entirely using **vibe-coding** with GitHub Copilot. The goal was to explore how easy it is to develop a complete TUI application using only AI assistance, and to evaluate whether the resulting code is maintainable and follows good practices.\n\n**Vibe-coding approach:**\n\n- All code was generated through natural language conversations with GitHub Copilot\n- Features were added incrementally by describing the desired functionality\n- The AI handled architecture decisions, refactoring, and code organization\n- Following the DTDP (Detailed Technical Development Process) with investigation, discussion, action, and summary phases\n\n**Key learnings:**\n\n- TUI development with `ratatui` was straightforward through conversation\n- Code quality remained high with proper use of Rust idioms (edition 2024)\n- Refactoring and separation of concerns was handled naturally\n- Git commits followed conventional commits format consistently\n\nThe project serves as a case study for AI-assisted development and demonstrates that maintainable, well-structured code can be created through conversational programming.\n\n\u003e [!NOTE]\n\u003e Even the README has been AI generated, except for this line. Apparently Copilot has a high opinion of itself :laughing:\n\n---\n\n## Overview\n\nGit-Repos is a command-line tool with a Text User Interface (TUI) that helps you discover and manage git repositories on your system. It recursively scans directories to find all git repositories and displays them in an interactive table with current branch information.\n\n## Features\n\n- 🔎 **Recursive scanning** - Find all git repositories in a directory tree\n- 🎯 **Smart filtering** - Excludes nested repositories (submodules) for cleaner results\n- 📊 **Interactive TUI** - Beautiful table interface with rounded borders\n- 🌿 **Branch detection** - Shows the current branch for each repository\n- 📡 **Remote status** - Displays ahead/behind status, local-only, or up-to-date\n- 📝 **Working tree status** - Shows clean, modified, or staged changes\n- 📅 **Last commit info** - Display last commit time (relative) and author\n- ⚡ **Async loading** - Fast startup with background data loading\n- 🔄 **Auto-fetch** - Automatically fetch all repositories with remotes asynchronously\n- 🔀 **Auto-update** - Optionally fast-forward merge local branches after fetch\n- 🔍 **Search filter** - Press `/` to search repositories by name\n- 📋 **View modes** - Filter repositories by: All, No Upstream, Behind, Modified\n- 🎨 **Color-coded display** - Visual indicators for repository states\n- ⌨️ **Keyboard navigation** - Vim-style (j/k) and arrow key navigation\n- 🚀 **Quick navigation** - Press Enter to change directory to selected repository\n- 💾 **Persistent cache** - Saves repository list for cross-machine sharing\n- 🗑️ **Repository management** - Delete repositories with 'd' key\n- 📥 **Clone missing repos** - Clone repositories marked as missing with 'c' key\n- 🔧 **Configuration** - Set root path and auto-update preferences\n- ⚡ **Fast and efficient** - Written in Rust for optimal performance\n\n## Installation\n\n### Installation via [Cargo](https://doc.rust-lang.org/cargo/)\n\n```\ncargo install git-repos-manager\n```\n\n### Installation via [Scoop](https://scoop.sh/)\n\nInstall **git-repos** with [scoop](\u003chttps://scoop.sh/\u003e):\n\n```powershell\nscoop bucket add narnaud https://github.com/narnaud/scoop-bucket\nscoop install git-repos\n```\n\n### Prebuilt binaries\n\nDownload the latest archive for your platform from the [Releases](https://github.com/narnaud/git-repos/releases) page, extract it, and add the binary to your PATH.\n\n| Platform      | Archive                                  |\n|---------------|------------------------------------------|\n| Windows (x86_64) | `git-repos-x86_64-pc-windows-msvc.zip` |\n| Linux (x86_64) | `git-repos-x86_64-unknown-linux-gnu.tar.gz` |\n| Linux (aarch64) | `git-repos-aarch64-unknown-linux-gnu.tar.gz` |\n| macOS (Apple Silicon) | `git-repos-aarch64-apple-darwin.tar.gz` |\n\n### Build from source\n\n```powershell\ngit clone https://github.com/narnaud/git-repos.git\ncd git-repos\ncargo build --release\n```\n\nThe compiled binary will be in `target/release/git-repos.exe`\n\n## Usage\n\n### Basic usage\n\nScan the current directory:\n\n```powershell\ngit-repos\n```\n\nScan a specific directory:\n\n```powershell\ngit-repos D:\\projects\n```\n\nBy default, the tool automatically fetches all repositories with remotes. To disable this:\n\n```powershell\ngit-repos --no-fetch\n```\n\nTo also update local branches with fast-forward merge after fetching:\n\n```powershell\ngit-repos --update\n```\n\nWhen auto-fetch is enabled (default), the tool runs `git fetch --all --prune` for each repository that has a remote configured. A spinner animation in the status bar shows the progress. With `--update`, it also performs `git merge --ff-only` to update local branches when possible.\n\n### Configuration\n\nSet the root path to scan by default:\n\n```powershell\ngit-repos set root D:\\projects\n```\n\nEnable auto-update by default (fast-forward merge after fetch):\n\n```powershell\ngit-repos set update true\n```\n\nThe configuration is stored in:\n\n- Windows: `%APPDATA%\\git-repos\\config.toml`\n- Linux/macOS: `~/.config/git-repos/config.toml`\n\n### Repository cache\n\nThe tool maintains a cache of discovered repositories in `repos.yaml` (same directory as config). This cache:\n\n- Saves the list of all repositories with their remote URLs\n- Persists across sessions for cross-machine sharing\n- Tracks deleted repositories as \"missing\" (shown in gray)\n- Merges with newly discovered repositories when scanning\n\nMissing repositories can be:\n\n- Cloned back using the 'c' key\n- Permanently removed from cache using the 'd' key\n\n### Shell integration (recommended)\n\nShell integration (recommended)\n--------------------------------\n\nSince a program cannot change the shell's working directory, you need a wrapper that uses a temp file and the `--cwd-file` flag.\n\n#### PowerShell\n\nAdd this to your PowerShell profile (`$PROFILE`):\n\n```powershell\nfunction gr {\n    $tmp = \"$env:TEMP\\git-repos-cwd.txt\"\n    Remove-Item $tmp -ErrorAction SilentlyContinue\n    git-repos --cwd-file $tmp $args\n    if (Test-Path $tmp) {\n        $path = Get-Content $tmp -Raw\n        if ($path) { Set-Location $path }\n        Remove-Item $tmp\n    }\n}\n```\n\n#### Bash/Zsh\n\nAdd this to your `.bashrc` or `.zshrc`:\n\n```bash\ngr() {\n    tmp=\"/tmp/git-repos-cwd.txt\"\n    rm -f \"$tmp\"\n    git-repos --cwd-file \"$tmp\" \"$@\"\n    if [ -s \"$tmp\" ]; then\n        cd \"$(cat \"$tmp\")\"\n        rm -f \"$tmp\"\n    fi\n}\n```\n\nNow you can use `gr` to interactively select and navigate to a repository:\n\n```powershell\ngr              # Scan current directory\ngr D:\\projects  # Scan specific directory\n```\n\n### Keyboard controls\n\n- **↑/↓** or **j/k** - Navigate through the repository list\n- **[** / **]** - Switch between view modes (All, Needs Attention, Behind, Modified)\n- **/** - Enter search mode to filter repositories by name\n- **Esc** - Exit search mode and clear search filter\n- **d** - Delete selected repository (marks as missing) or remove from cache if already missing\n- **c** - Clone selected missing repository (auto-detects GitHub for `gh` vs `git clone`)\n- **u** - Update selected repository (fetch + status)\n- **Enter** - Change directory to selected repository (exits the app)\n- **q** or **Ctrl-C** - Quit the application\n\n### View Modes\n\n- **All** - Show all repositories\n- **No Upstream** - Show repositories that are local-only or have no tracking branch\n- **Behind** - Show only repositories that are behind their upstream\n- **Modified** - Show only repositories with uncommitted changes\n\nThe current mode is highlighted at the bottom right of the table.\n\n### Example output\n\n```text\n╭─ Git Repositories - D:\\projects ────────────────────────────────────────────────────────────────────────╮\n│ Repository              │ Branch  │ Remote Status │ Status     │ Last Commit                          │\n├─────────────────────────┼─────────┼───────────────┼────────────┼──────────────────────────────────────┤\n│ \u003e kdab/knut             │ main    │ ↑2 ↓0         │ 3M         │ 2 days ago by John Doe               │\n│   kdab/training-material│ develop │ up-to-date    │ clean      │ 1 week ago by Jane Smith             │\n│   narnaud/git-repos     │ main    │ local-only    │ 1S 2M      │ 5 minutes ago by Nicolas Arnaud      │\n│   oss/ratatui           │ main    │ ⟳ loading...  │ clean      │ ⟳ loading...                         │\n│   user/deleted-repo     │ -       │ -             │ missing    │ -                                    │\n├─────────────────────────┴─────────┴───────────────┴────────────┴──All─[No Upstream]─Behind─Modified────┤\n╰──────────────────────────────────────────────────────────────────────────────────────────────────────────╯\nFound 5 repositories (1 missing) | ⠋ Fetching 2 repositories... | Mode: [/] | Search: / | Quit: q or Ctrl-C\n```\n\n#### Color indicators\n\n**Remote Status:**\n\n- 🟢 Green - `up-to-date`\n- 🔵 Cyan - `↑X ↓Y` (ahead/behind)\n- 🟡 Yellow - `no-tracking`\n- 🔴 Red - `local-only`\n- ⚫ DarkGray - `⟳ loading...`\n\n**Working Tree Status:**\n\n- 🟢 Green - `clean`\n- 🟡 Yellow - `XM` (modified), `XS` (staged), `XS YM` (both)\n- ⚫ DarkGray - `⟳ loading...` or `unknown`\n\n**Missing Repositories:**\n\n- ⚫ DarkGray - Repository deleted or not present on this machine\n- ⚪ White - Missing repository when selected (for better visibility)\n\n### Repository lifecycle\n\n**Deleting repositories:**\n\n1. Select a repository and press 'd'\n2. Confirm the deletion (default: No)\n3. The repository is deleted from disk and marked as \"missing\" in the cache\n4. Missing repositories appear in gray at the bottom of the list\n\n**Cloning missing repositories:**\n\n1. Select a missing repository (shown in gray)\n2. Press 'c' to clone it back\n3. The tool automatically detects GitHub repos and uses `gh repo clone` if available\n4. Progress is shown with an animated spinner\n5. Once cloned, the repository appears normally in the list\n\n**Removing from cache:**\n\n1. Select a missing repository\n2. Press 'd' again to permanently remove it from the cache\n3. It will no longer appear in the list\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\nMIT License - Copyright (c) Nicolas Arnaud-Cormos\n\nSee [LICENSE](LICENSE) file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarnaud%2Fgit-repos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnarnaud%2Fgit-repos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnarnaud%2Fgit-repos/lists"}