Provides a `gitlocal version` command to display the application's version, commit hash, and build date. Introduces a `Makefile` to automate builds, installations, and tests. The Makefile dynamically extracts version, commit, and date from git tags, commit hashes, and build timestamps, injecting this metadata into the Go binary via `ldflags`. Updates the `README.md` to document the new command and recommended build process using the Makefile.
247 lines
5.1 KiB
Markdown
247 lines
5.1 KiB
Markdown
# 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
|
|
```
|
|
|
|
### Show version information
|
|
|
|
```bash
|
|
gitlocal version
|
|
```
|
|
|
|
Example output:
|
|
```
|
|
gitlocal version v0.1.0
|
|
Commit: a1b2c3d
|
|
Built: 2026-04-11T14:30:00Z
|
|
```
|
|
|
|
## 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 with version info (recommended - uses Makefile)
|
|
make build
|
|
|
|
# Or install to $GOPATH/bin with version info
|
|
make install
|
|
|
|
# Build without version info (not recommended)
|
|
go build -o gitlocal
|
|
|
|
# Check version that would be built
|
|
make version
|
|
```
|
|
|
|
The Makefile automatically injects version information from git tags:
|
|
- `Version`: Git tag (e.g., `v0.1.0`) or commit hash if no tag exists
|
|
- `Commit`: Short commit hash
|
|
- `Date`: Build timestamp
|
|
|
|
Check the version after installing:
|
|
```bash
|
|
gitlocal version
|
|
```
|
|
|
|
### 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
|