Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 23 additions & 9 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,22 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-latest]
steps:
- uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable

- name: Cache cargo
uses: Swatinem/rust-cache@v2

- name: Run tests
run: cargo test --all-features

test-windows:
name: Test (windows-latest)
runs-on: windows-latest
steps:
- uses: actions/checkout@v4

Expand All @@ -83,10 +98,7 @@ jobs:
- name: Run tests
run: cargo test --all-features
env:
# Windows: link advapi32 for libgit2-sys (needed for test crates that
# don't go through build.rs) and increase stack to 8 MB (debug builds
# overflow the default 1 MB Windows stack during clap parsing)
RUSTFLAGS: ${{ matrix.os == 'windows-latest' && '-C link-arg=advapi32.lib -C link-arg=/STACK:8388608' || '' }}
RUSTFLAGS: '-C link-arg=advapi32.lib -C link-arg=/STACK:8388608'

build:
name: Build Release
Expand Down Expand Up @@ -149,14 +161,16 @@ jobs:
- name: Run spawn integration tests
run: GR=./target/debug/gr ./tests/spawn_graceful_shutdown.sh

# Summary job for branch protection - requires all other jobs to pass
# Summary job for branch protection - requires all jobs except Windows to pass.
# Windows tests run separately (test-windows) and are visible but non-blocking,
# since they are significantly slower and should not gate PR merges.
ci:
name: CI
runs-on: ubuntu-latest
needs: [check, fmt, clippy, test, build, bench, integration]
if: always()
steps:
- name: Check all jobs passed
- name: Check all required jobs passed
run: |
if [[ "${{ needs.check.result }}" != "success" ]] || \
[[ "${{ needs.fmt.result }}" != "success" ]] || \
Expand All @@ -165,7 +179,7 @@ jobs:
[[ "${{ needs.build.result }}" != "success" ]] || \
[[ "${{ needs.bench.result }}" != "success" ]] || \
[[ "${{ needs.integration.result }}" != "success" ]]; then
echo "One or more jobs failed"
echo "One or more required jobs failed"
exit 1
fi
echo "All jobs passed"
echo "All required jobs passed"
19 changes: 19 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ readme = "README.md"
keywords = ["git", "monorepo", "workflow", "multi-repo", "cli"]
categories = ["development-tools", "command-line-utilities"]

[workspace]
members = ["gr2"]

[[bin]]
name = "gr"
path = "src/main.rs"
Expand All @@ -21,6 +24,10 @@ path = "src/main.rs"
name = "gitgrip"
path = "src/main.rs"

[[bin]]
name = "gr2"
path = "src/bin/gr2.rs"

[lib]
name = "gitgrip"
path = "src/lib.rs"
Expand All @@ -40,6 +47,7 @@ release-logs = ["tracing/release_max_level_info"]
max-perf = ["tracing/max_level_off"]

[dependencies]
gr2_cli = { package = "gr2-cli", path = "gr2" }
# Async runtime
tokio = { version = "1", features = ["rt-multi-thread", "macros", "process", "time", "net", "io-util", "sync"] }
uuid = { version = "1", features = ["v4"] }
Expand Down Expand Up @@ -85,6 +93,9 @@ quick-xml = { version = "0.37", features = ["serialize"] }
# TOML parsing
toml = "0.8"

# Glob patterns (for linkfile/copyfile glob expansion)
glob = "0.3"

# Misc
once_cell = "1"
regex = "1"
Expand Down
85 changes: 85 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ gr sync
| `gr branch [name]` | Create or list branches |
| `gr checkout <branch>` | Checkout branch across repos |
| `gr checkout -b <branch>` | Create and checkout branch in one command |
| `gr checkout add <name>` | Create an independent child checkout from cached repos |
| `gr add [files]` | Stage changes across repos |
| `gr diff` | Show diff across repos |
| `gr commit -m "msg"` | Commit across repos |
Expand Down Expand Up @@ -183,6 +184,9 @@ gr sync
| `gr link` | Manage file links |
| `gr run <script>` | Run workspace scripts |
| `gr env` | Show environment variables |
| `gr cache status` | Show machine-level cache state for workspace repos |
| `gr cache bootstrap` | Materialize missing machine-level repo caches |
| `gr cache update` | Fetch updates into existing machine-level repo caches |
| `gr bench` | Run performance benchmarks |
| `gr completions <shell>` | Generate shell completions |

Expand Down Expand Up @@ -223,6 +227,34 @@ Pull latest changes from the manifest and all repositories. Syncs in parallel by

Show status of all repositories including branch, changes, and sync state.

#### `gr cache <subcommand>`

Manage the machine-level bare-repo cache used by workspace repos.

By default caches live under `~/.grip/cache/`, keyed by canonical repo identity.
You can override the cache root with `GRIP_CACHE_DIR` when you need a custom or
isolated cache location.

| Subcommand | Description |
|-----------|-------------|
| `gr cache status` | Show whether each workspace repo has a cache and where it lives |
| `gr cache bootstrap` | Create missing caches without touching existing ones |
| `gr cache update` | Fetch updates into existing caches |
| `gr cache remove <repo>` | Remove one repo cache explicitly |

**Examples:**

```bash
# See where caches are currently resolved
gr cache status

# Create missing caches before materializing child checkouts
gr cache bootstrap

# Use a custom cache root for an isolated environment
GRIP_CACHE_DIR=/tmp/grip-cache gr cache status
```

#### `gr checkout <branch>`

Checkout a branch across all repos. Can also create branches with the `-b` flag.
Expand All @@ -232,6 +264,59 @@ Checkout a branch across all repos. Can also create branches with the `-b` flag.
| `-b` | Create branch if it doesn't exist |
| `--base` | Checkout the griptree base branch (griptree workspaces only) |

#### `gr checkout add <name>`

Create an independent child checkout under `.grip/checkouts/<name>/` using the
workspace cache as an accelerator.

Unlike `gr tree add`, this creates normal child clones with their own `.git`
directories. The checkout keeps the canonical remote URL as `origin`; the cache
is only used to speed up materialization.

| Option | Description |
|--------|-------------|
| `--repo <name>` | Only materialize specific repos |
| `--group <name>` | Only materialize repos in a group |

**Examples:**

```bash
# Materialize all repos into an independent child checkout
gr checkout add sandbox

# Materialize only the docs group
gr checkout add docs-only --group docs

# Materialize just one repo
gr checkout add app-only --repo app
```

#### `gr checkout list`

Show the currently materialized child checkouts under
`.grip/checkouts/`.

**Examples:**

```bash
# List all materialized child checkouts
gr checkout list
```

#### `gr checkout remove <name>`

Remove a materialized child checkout under `.grip/checkouts/<name>/`.

This deletes the child clone only. It does not delete the shared cache under
`~/.grip/cache/`.

**Examples:**

```bash
# Remove a disposable child checkout
gr checkout remove sandbox
```

#### `gr branch [name]`

Create a new branch across all repositories, or list existing branches. Manifest repo is always included.
Expand Down
Loading
Loading