From c9867f410fbe03a38c62c6d74bdf4536fd65cc13 Mon Sep 17 00:00:00 2001 From: Daniel Tomlinson Date: Sat, 11 Apr 2026 14:47:36 +0100 Subject: [PATCH] Initial commit --- README.md | 217 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 0000000..d5016cc --- /dev/null +++ b/README.md @@ -0,0 +1,217 @@ +# gitlocal + +A CLI tool for managing nested git repositories by converting `.git` directories to `.gitlocal`, allowing parent repos to track nested project files. + +## Problem + +When you have a parent git repository (like a knowledge base or personal monorepo) that contains nested projects with their own `.git` directories, Git and GUI tools like GitKraken won't let you commit those nested directories. Git treats them as submodules or gitlinks. + +## Solution + +`gitlocal` renames `.git` → `.gitlocal` in nested projects, which: +- Allows the parent repo to track all files normally +- Preserves the nested repo's git history in `.gitlocal` +- Lets you use git commands locally via the `git-local` alias + +## Installation + +```bash +go install git.membo.co.uk/dtomlinson/gitlocal@latest +``` + +Make sure `$HOME/go/bin` is in your `PATH`. + +## Commands + +### Convert a single repository + +```bash +# Convert .git → .gitlocal in current directory +gitlocal convert + +# Convert specific directory +gitlocal convert /path/to/nested/repo +``` + +### Convert all nested repositories + +```bash +# Recursively find and convert all nested .git directories +gitlocal convert --recursive + +# Dry run to see what would be converted +gitlocal convert --recursive --dry-run +``` + +### Revert back to .git + +```bash +# Revert .gitlocal → .git in current directory +gitlocal revert + +# Revert all tracked repositories +gitlocal revert --all +``` + +### Show converted repositories + +```bash +gitlocal status +``` + +Example output: +``` +Converted Repositories (2): + + /Users/you/tembo/work/2026/03_March/midnight_season_1_tanking_summaries + Converted: 2 days ago + Remote: git@github.com:user/repo.git + Branch: main + + /Users/you/tembo/work/2025/12_December/trilium_next_theme/Trilium + Converted: 2 days ago + Remote: https://github.com/trilium/trilium.git + Branch: master +``` + +## Using git with .gitlocal + +Add this alias to your `.zshrc` or `.bashrc`: + +```bash +alias git-local='git --git-dir=.gitlocal --work-tree=.' +``` + +Then use `git-local` instead of `git` in converted repos: + +```bash +cd /path/to/converted/repo +git-local status +git-local log +git-local commit -am "Update" +git-local push +``` + +## Configuration + +`gitlocal` tracks converted repositories in `~/.gitlocal.yml`: + +```yaml +version: "1" +repos: + - path: /absolute/path/to/repo + converted_at: 2026-04-07T14:30:00Z + original_remote: git@github.com:user/repo.git + original_branch: main +``` + +## Development + +### Requirements +- Go 1.19 or later +- Git (for running tests) + +### Building from Source + +```bash +# Clone the repository +git clone https://git.membo.co.uk/dtomlinson/gitlocal.git +cd gitlocal + +# Install dependencies +go mod download + +# Build the binary +go build -o gitlocal + +# Or install directly to $GOPATH/bin +go install +``` + +### Running Tests + +```bash +# Run all tests +go test ./... + +# Run tests with verbose output +go test -v ./... + +# Run tests with coverage +go test -coverprofile=coverage.out ./... +go tool cover -func=coverage.out + +# View coverage in browser +go tool cover -html=coverage.out + +# Run tests for a specific package +go test ./internal/git +go test -v ./cmd +``` + +### Test Coverage + +Current test coverage: **71%** + +- `internal/git`: 94.7% +- `internal/scanner`: 86.4% +- `internal/config`: 80.6% +- `cmd`: 60.0% + +Tests use temporary directories and real git operations to ensure correctness. + +## Workflow Example + +1. You have a knowledge base at `~/kb/` with nested projects: + ``` + ~/kb/ + ├── .git/ # Parent repo + ├── projects/ + │ ├── my-app/ + │ │ └── .git/ # Nested repo - can't commit! + │ └── another-project/ + │ └── .git/ # Nested repo - can't commit! + ``` + +2. Convert all nested repos: + ```bash + cd ~/kb + gitlocal convert --recursive + ``` + +3. Now the structure is: + ``` + ~/kb/ + ├── .git/ # Parent repo + ├── projects/ + │ ├── my-app/ + │ │ └── .gitlocal/ # Can commit from parent! + │ └── another-project/ + │ └── .gitlocal/ # Can commit from parent! + ``` + +4. Commit from parent repo: + ```bash + git add . + git commit -m "Add nested projects" + git push + ``` + +5. Work on nested project: + ```bash + cd ~/kb/projects/my-app + git-local status + git-local commit -am "Update feature" + ``` + +6. If you need to use GitKraken on a nested project: + ```bash + cd ~/kb/projects/my-app + gitlocal revert + # Use GitKraken + gitlocal convert + ``` + +## License + +MIT