This file captures friction points, feature ideas, and bugs discovered while using gr.
Items here should be reviewed before creating GitHub issues.
Note: Historical entries may reference
cr(the old command name). The current command isgr.
Merge Conflicts: When rebasing feature branches, you may encounter merge conflicts in this file when other PRs also add entries. This is expected behavior. To resolve:
- Use
git rebase --skipto skip documentation-only commits from other branches- Or manually merge both sets of entries
- The alternative would be to use a dedicated documentation file, but we accept this tradeoff for now
See issue #143 for context.
Completed: 2026-02-02
Problem: gr pr create consistently times out (~30s) even when:
gh auth statusshows authenticated user withreposcope- Git operations work (push, status, diff)
- Other
grcommands work normally
Root Cause: HTTP clients (octocrab for GitHub, reqwest for GitLab/Azure/Bitbucket) had no explicit timeout configuration, relying on OS-level TCP timeouts (~30s) which made debugging difficult.
Solution: Added explicit timeout configurations to all platform adapters:
- Connect timeout: 10 seconds (fail fast on connection issues)
- Read/Write timeout: 30 seconds (reasonable for API operations)
This provides:
- Faster failure detection when connection issues occur
- Clearer error messages indicating timeout vs other failures
- Consistent behavior across all platforms
Files Changed:
src/platform/github.rs- Added timeouts to Octocrab builder and helperhttp_client()methodsrc/platform/gitlab.rs- Added timeouts to reqwest Clientsrc/platform/azure.rs- Added timeouts to reqwest Clientsrc/platform/bitbucket.rs- Added timeouts via helperhttp_client()method
Closes #63
Completed: 2026-01-31
Added gr completions <shell> command using clap_complete crate.
- Supports: bash, zsh, fish, elvish, powershell
- Usage:
gr completions bash > ~/.local/share/bash-completion/completions/gr - Or eval:
eval "$(gr completions bash)"
Completed: 2026-01-31
- Added
test_gitlab_full_pr_workflowtest - Fixed GitLab token parsing to find "Token found:" pattern from glab
- Changed GitLab API auth from PRIVATE-TOKEN to Bearer auth (works for OAuth2 tokens from glab)
- Azure DevOps tests added but require user to complete interactive browser login once
Completed: 2026-01-31
- Fixed "fatal: this operation must be run in a work tree" errors in griptrees
- Changed all git CLI calls to use
repo.workdir()instead ofrepo.path().parent() repo.path()returns.git/worktrees/<name>for worktrees, which broke git commandsrepo.workdir()correctly returns the actual working directory for both regular repos and worktrees- Affected commands:
gr sync,gr add,gr commit,gr push,gr status, etc.
Discovered: 2026-02-08
Problem: Needed to update issue #253 with the concrete command design, but had to use raw gh issue comment since gr has no issue commenting/editing command.
Suggested fix:
- Add
gr issue commentandgr issue editwrappers (or a minimalgr issuesubcommand).
Status: ✅ COMPLETED - Implemented in PR #131 (v0.5.6)
Discovered: 2026-02-01
Problem: gr sync reports "X failed" with no details about which repositories failed or why.
Solution: Now shows per-repo status with clear indicators:
Syncing 8 repositories...
✓ tooling: synced
✓ codex: synced
⚠ opencode: not cloned
✗ private: failed - Failed to fetch: authentication required
Status: ✅ COMPLETED - Implemented in PR #141 (v0.5.6)
Discovered: 2026-02-01
Problem: gr push reports "X failed, Y skipped" with no details about which repositories failed or were skipped.
Solution: Now shows detailed results with per-repo status:
Pushing 8 repositories...
✓ tooling: pushed to feat/my-feature
✓ codex: pushed to feat/my-feature
⚠ opencode: skipped (no changes)
✗ private: failed - authentication required
Status: ✅ COMPLETED - Implemented in PR for v0.5.4
Discovered: 2026-02-01 during Rust migration planning
Problem: When adding reference implementations to a workspace (e.g., opencode, codex, crush), these repos are only for reading/learning - we never plan to edit them or create PRs. Previously gr branch created branches across all repos, and gr pr create would try to create PRs in all repos with the branch.
Solution: Added reference: true flag in manifest to mark repos as read-only:
repos:
opencode:
url: https://github.com/anomalyco/opencode.git
path: ./ref/opencode
reference: true # Excluded from branch/PR operationsBehavior: Reference repos still sync and show in status (with [ref] indicator) but are skipped in branch/checkout and PR operations.
Status: ✅ COMPLETED - Implemented in PR for v0.5.3
Discovered: 2026-01-31
Problem: gr status showed local uncommitted changes but didn't show how the current branch compares to main/upstream. This made it hard to know if you need to rebase before creating a PR or if main has moved ahead.
Solution: Added "vs main" column showing ahead/behind status:
Repo Branch Status vs main
------------ --------------- ------ -------
tooling feat/new-api ~3 ↑2 ↓5
frontend feat/new-api ✓ ↑4
backend main ✓ -
3/3 cloned | 1 with changes | 2 ahead of main
↑N= N commits ahead of default branch (your changes)↓N= N commits behind default branch (need to rebase/merge)-= on default branch, no comparison needed↑N ↓M= both ahead and behind (diverged)
Status: ✅ COMPLETED - Implemented in PR #167
Discovered: 2026-01-29 during centralized griptree metadata implementation
Problem: Accidentally committed to main instead of a feature branch.
Solution: Added --move flag to gr branch:
gr branch feat/x --move --repo toolingThis creates the new branch at HEAD, resets current branch to origin/main, and checkouts the new branch.
Status: ✅ COMPLETED - Implemented
Discovered: 2026-01-29 during PR creation
Problem: gr pr create -t "title" prompted interactively for the PR body. This blocked automation and required falling back to raw gh pr create with --body flag.
Solution: Added -b/--body flag to gr pr create:
gr pr create -t "title" -b "body content"Status: ✅ COMPLETED - Already implemented in main.rs
Discovered: 2026-01-29 during sync fix + repo add implementation
Problem: Wanted to amend a commit after review found minor issues (unused import, misleading comment). However, --amend flag was already available but not documented in IMPROVEMENTS.md.
Solution Verified: The --amend flag already existed and works correctly:
# Amend with new message
gr commit --amend -m "Updated message"
# Keep same message (still requires -m flag)
gr commit --amend -m "Updated message"Implementation
- CLI:
#[arg(long)] amend: boolin main.rs - Backend:
create_commit()handles amend correctly - Tests: Unit test
test_amend_commitpasses
Closes #59
Status: ✅ COMPLETED - Already implemented
Discovered: 2026-01-29 during PR review workflow
Problem: Wanted to check CI status across all repos with PRs, assumed it wasn't implemented.
Solution Verified: gr pr checks command already exists and works:
gr pr checks # Pretty output
gr pr checks --json # JSON output for scriptingOutput Format:
CI/CD Check Status
● strategy
● homebrew-tap #9
● public #253
● Type Check queued
● Test (ubuntu-latest) queued
✓ Test (macos-latest) success
Summary: 3 passed, 0 failed, 3 pending
Features:
- Shows all linked PRs for current branch
- Aggregates status across repos (GitHub/GitLab/AzureDevOps)
- Lists individual checks with indicators
- Summary with counts
- JSON output for scripts
- Exit code non-zero if checks failing
Closes #60
Status: ✅ COMPLETED - Implemented in PR #165
Discovered: 2026-01-29 during workflow discussion
Problem: gr forall -c "pnpm test" runs in ALL repos, even ones with no changes. This wastes time running tests in repos that haven't been modified. Running in all repos should be opt-in, not the default.
Solution: Default changed to repos with changes only:
# Only run in repos with changes (NEW DEFAULT)
gr forall -c "pnpm test"
# Explicitly run in ALL repos
gr forall -c "pnpm test" --allBreaking change: Yes, use --all for previous behavior.
Task: Fix #93 - gr pr merge doesn't recognize passing GitHub checks
Overall Assessment: gr workflow was smooth, minor friction with PR creation body flag.
gr branch- Created feature branch across all repos seamlesslygr add- Staged changes correctly in tooling repogr commit- Committed with descriptive messagegr pr create(via gh) - Created PR successfully
| Issue | Title |
|---|---|
| #63 | fix: gr pr create command times out |
| Raw Command | Why gr Couldn't Handle It |
Issue |
|---|---|---|
gh pr create --body |
gr pr create lacks --body flag for PR body |
#58 |
| Observation | Notes |
|---|---|
gr sync - 1 failed |
"7 synced, 1 failed" with no details on which repo failed |
gr push - 2 failed |
"5 pushed, 2 failed, 1 skipped" with no error details |
Overall Assessment: gr worked smoothly for this feature. No raw git or gh commands were needed.
gr branch- Created feature branch across all reposgr add,gr commit,gr push- Smooth workflow for iterative commitsgr pr create- Created PR correctlygr pr merge --force- Merged successfullygr checkout main && gr sync- Clean return to main after merge
| Issue | Title |
|---|---|
| #34 | feat: Add Bitbucket platform support |
| #35 | feat: Use GitHub Check Runs API for better status checks |
| #36 | feat: Add retry logic with exponential backoff |
| #37 | feat: Add rate limiting handling |
| #39 | feat: improve check status messaging in gr pr merge |
| Observation | Notes |
|---|---|
| Check status messaging | gr pr merge showed "checks not passing" when check was actually SKIPPED. Issue #39 created. |
Task: Add homebrew-tap repo to workspace and update formula for v0.3.0
| Issue | Title |
|---|---|
| #43 | feat: add gr repo add command for adding new repos to workspace |
| #44 | fix: gr sync should not discard uncommitted manifest changes |
| Raw Command | Why gr Couldn't Handle It |
Issue |
|---|---|---|
git clone git@github.com:laynepenney/homebrew-tap.git |
No command to add new repo to workspace | #43 |
cd .gitgrip/manifests && git add && git commit |
Manifest changes needed manual handling after sync reset | #44 |
cd homebrew-tap && git checkout -b && git push |
New repo not yet managed by gr | #43 |
Overall Assessment: cr worked very well for this multi-repo workflow. The core commands handled the majority of operations smoothly.
cr branch- Created branches across all 4 repos seamlesslycr status- Excellent visibility into repo states, showed changes clearlycr add,cr commit,cr push- Worked exactly as expected across reposcr pr create- Created linked PRs in both codi and codi-private correctlycr pr status- Showed PR status with checks, approval, mergeable statecr sync- Pulled and synced repos correctly after mergescr checkout main- Switched all repos back to main after mergecr diff --stat- Useful for reviewing changes before commit
| Issue | Title |
|---|---|
| #25 | fix: improve error handling for cr pr merge failures |
| #26 | fix: cr pr status shows stale check status |
| #27 | feat: add cr branch --delete for cleanup |
| #28 | feat: add cr rebase with upstream branch tracking |
| #29 | feat: add cr pr diff to show combined PR diff |
| #30 | feat: add cr pr checks to show CI status |
| Raw Command | Why cr Couldn't Handle It |
Issue |
|---|---|---|
git fetch origin main && git rebase origin/main |
No rebase command | #28 |
git push --force-with-lease |
No force push after rebase | #28 |
gh pr merge 209 --squash |
cr pr merge failed with 405 |
#25 |
gh pr diff 209 |
No PR diff command | #29 |
gh pr checks 209 |
No PR checks command | #30 |
git branch -d feat/... |
No branch delete command | #27 |
git push origin --delete feat/... |
No remote branch delete | #27 |
No items approved.
Items that have been implemented. Keep for historical reference.
- Added in: PR #21
- Description:
cr pr statusandcr pr mergenow find PRs by checking each repo's own branch. Repos on their default branch are skipped.
- Added in: PR #19
- Description:
cr pr createnow only checks branch consistency for repos with changes. Repos onmainwith no changes no longer block PR creation.
- Added in: PR #17
- Description: Run arbitrary commands in each repository with
cr forall -c "command". Supports--repo,--include-manifest, and--continue-on-errorflags.
- Added in: PR #12
- Description: Manifest repo (
.codi-repo/manifests/) is now automatically included in allcrcommands when it has changes.cr statusshows manifest in a separate section.cr branch --include-manifestexplicitly includes manifest.cr pr create/status/mergehandle manifest PRs.
- Added in: PR #10
- Description:
cr syncnow automatically recovers when manifest's upstream branch was deleted after PR merge
- Added in: PR #10
- Description: Commit staged changes across all repos with
cr commit -m "message"
- Added in: PR #10
- Description: Push current branch across all repos with
cr push
- Added in: PR #1
- Description: Benchmark workspace operations with
cr bench
- Added in: PR #1
- Description: Global
--timingflag shows operation timing breakdown
- Added in: PR #11
- Description: Stage changes across all repos with
cr add .orcr add <files>
- Added in: PR #11
- Description: Show diff across all repos with
cr diff, supports--staged,--stat,--name-only
- Added in: PR #11
- Description: Create branches in specific repos only with
cr branch feat/x --repo tooling
| Issue # | Title |
|---|---|
| #58 | feat: add --body flag to gr pr create |
| #59 | feat: add --amend flag to gr commit |
| #60 | feat: add gr pr checks command |
| #61 | feat: gr forall should default to changed repos only |
| #62 | feat: add single-repo branch creation for fixing commits |
| #63 | fix: gr pr create command times out |
| #99 | fix: gr pr merge doesn't recognize passing checks |
| #112 | fix: gr repo add corrupts manifest YAML structure |
| #113 | feat: add reference repos (read-only repos excluded from branch/PR operations) |
| #129 | fix: gr push shows 'failed' for repos with no changes to push |
| #130 | fix: gr pr merge reports 'checks failing' when checks actually passed |
Created: 2025-12-05 Updated: 2026-02-01
Status: ✅ COMPLETED - Fixed in PR for v0.5.6
Discovered: 2026-02-01 during reference repo addition
Problem: gr repo add placed the new repo entry between version: and manifest: sections instead of under repos:. This caused manifest parsing to fail.
Solution: YAML insertion logic now correctly places repos under repos: section.
Status: ✅ COMPLETED - Already working correctly
Discovered: 2026-02-01 during sync no-upstream fix
Problem: Assumed repos without changes showed as "failed" instead of "skipped".
Verified Working: Current behavior correctly handles this:
$ gr push
Pushing changes...
ℹ tooling: nothing to push
ℹ public: nothing to push
Nothing to push.Implementation Verified:
has_commits_to_push()checks for commits ahead of remote- Repos with nothing to push show "ℹ {repo}: nothing to push"
- Summary correctly shows "Nothing to push." when all skipped
- Error handling distinguishes between "nothing to push" and actual failures
Closes #129
Status: ✅ COMPLETED - Fixed in PR
Discovered: 2026-02-01 during sync no-upstream fix (PR #127)
Problem: gr pr merge reported "checks failing" when:
- GitHub API returned 404/no checks found (API errors treated as failing)
- Checks were actually passing but API query failed
- Had to fall back to
gh pr merge --admin
Root Cause: In merge.rs, the code treated ALL errors from get_status_checks() as "checks failing":
Err(_) => false, // Bug: Any API error = checks failingSolution: Added proper error handling with CheckStatus enum:
Passing- Checks succeededFailing- Checks actually failing (blocks merge)Pending- Checks still running (blocks merge with warning)Unknown- Could not determine status (warns but allows merge)
Now API errors (404, network issues, etc.) show a warning but don't block merge:
Err(e) => {
Output::warning(&format!(
"{}: Could not check CI status for PR #{}: {}",
repo.name, pr.number, e
));
CheckStatus::Unknown
}Benefits:
- No longer blocked by transient API issues
- Clear distinction between "checks failing" vs "can't check"
- Better messaging for pending/running checks
- Users can still
--forceif needed
Closes #130
Status: ✅ COMPLETED - Already implemented in tree.rs
Discovered: 2026-01-31 during Rust migration testing
Problem: The Rust implementation stores griptrees in .gitgrip/griptrees.json, but the TypeScript version stored a .griptree marker file in each griptree directory. Existing griptrees from the TypeScript version don't show up in gr tree list.
Solution: gr tree list now automatically discovers unregistered griptrees:
- Scans sibling directories for
.griptreepointer files - Checks if they point to the current workspace
- Shows discovered griptrees with "unregistered" status
- Provides guidance on how to add them to griptrees.json
Output Example:
Griptrees
feat-auth -> /Users/example/Development/feat-auth
⚠ Found unregistered griptrees:
codi-dev -> /Users/example/Development/codi-dev (unregistered)
These griptrees point to this workspace but are not in griptrees.json.
You can manually add them to griptrees.json if needed.
Implementation: discover_legacy_griptrees() function in src/cli/commands/tree.rs
Completed: 2026-02-02
Discovered: 2026-02-02 during PR #118, #141 work
Problem: When a branch is checked out in another worktree, git gives a cryptic error:
fatal: 'main' is already used by worktree at '/Users/example/Development/codi-workspace/gitgrip'
Solution: Enhanced error handling in checkout_branch() and create_and_checkout_branch() to detect worktree conflicts and provide actionable guidance:
Branch 'main' is checked out in another worktree at '/path/to/worktree'.
Either use that worktree or create a new branch with 'gr branch <name>'
Files Changed: src/git/branch.rs
Note: This is a git limitation - the same branch cannot be checked out in multiple worktrees simultaneously. The improved error message helps users understand the situation and suggests alternatives.
Discovered: 2026-02-02 during multiple PR rebases
Problem: When rebasing feature branches, kept hitting merge conflicts in IMPROVEMENTS.md because documentation commits from other PRs were also on main.
Reproduction:
gr branch fix/pr-merge-check-runs
# ... work on PR ...
git fetch origin main && git rebase origin/main
# CONFLICT in IMPROVEMENTS.md!Expected behavior: Either:
- Documentation changes don't cause merge conflicts during rebase
- Better tooling to resolve such conflicts
Suggested fix: Consider whether documentation should be kept in a separate file/location, or document this as expected behavior and provide conflict resolution helpers.
Discovered: 2026-02-02 during PR #141 merge
Problem: PR showed "Repository rule violations found - Required status check 'CI' is expected" even though tests were passing. Had to wait significantly longer for the CI check to actually complete.
Reproduction:
gh pr checks 141
# Shows: Check pass, Clippy pass, Tests pass...
# But merge fails with: "Required status check 'CI' is expected"
# Wait 2+ minutes...
gh pr view 141 --json mergeStateStatus # Still shows CLEAN, but CI pendingExpected behavior: Either:
- Better visibility of which specific CI check is pending
- Merge blocked with clearer message about what's pending
- Auto-wait for CI to complete before reporting block
Suggested fix: Improve status reporting in CLI to show pending CI jobs more prominently.
Discovered: 2026-02-02 during PR #138, #140 work
Problem: Had to run cargo fmt multiple times as formatting kept failing CI even though it passed locally once.
Reproduction:
cargo fmt # Passes locally
gr push # CI fails on Format check
# Fix formatting locally again
cargo fmt # Now finds more issuesExpected behavior: cargo fmt should be deterministic and produce consistent results in CI.
Suggested fix: Add pre-commit hook for formatting, or ensure CI uses same rust-toolchain as local.
Discovered: 2026-02-02 during PR #140 → #141
Problem: Created PR #140 with github.rs changes that belonged to PR #118. Had to close it and create a clean PR #141 with only push.rs changes.
Reproduction:
# Working on two branches
gr branch fix/push-nothing-to-push # For push count fix
gr branch fix/pr-merge-check-runs # For check runs fix
# Changes from fix/pr-merge-check-runs got committed to fix/push branch
gh pr create # PR #140 contains both fixes mixed togetherExpected behavior: Either:
- Branch isolation prevents cross-contamination
- Clear visual indicator of which files changed in PR diff before creating
Suggested fix: Better branch management, or PR preview before creation showing all modified files.
Discovered: 2026-02-03 while merging documentation PRs
Problem: Even with --force flag, gr pr merge --force failed because the all-or-nothing merge strategy requires ALL PRs to merge together. When some PRs had false-positive issues ("not approved", "checks still running" for docs repos), the entire merge was blocked.
Error: "Stopping due to all-or-nothing merge strategy. Error: API error: Failed to merge PR"
Workaround used: Had to use individual gh pr merge commands for each PR:
gh pr merge 179 --repo laynepenney/gitgrip --squash --delete-branch
gh pr merge 16 --repo laynepenney/codi-strategy --squash --delete-branchExpected behavior:
--forceshould bypass all checks and merge regardless of strategy- Or have a
--strategy independentflag to merge PRs separately - Documentation-only PRs shouldn't require CI checks
Discovered: 2026-02-03 while adding git-repo reference
Problem: gr pr create reported "No PRs were created" even though the manifest repo had uncommitted changes (manifest.yaml and CODI.md updates). The command pushed branches but failed to create the actual PR.
Workaround used: Had to manually push with git push -u origin codi-gripspace from the manifest directory, then use gh pr create with --repo laynepenney/codi-workspace flag to create the PR.
Raw commands used:
cd /Users/example/Development/codi-gripspace/.gitgrip/manifests
git push -u origin codi-gripspace
gh pr create --title "..." --body "..." --repo laynepenney/codi-workspaceExpected behavior: gr pr create should:
- Detect manifest repo changes like it does for regular repos
- Create the PR automatically without manual intervention
- Handle the manifest repo URL correctly
Additional friction:
- Had to cd to
.gitgrip/manifestsdirectory to run git commands gr push -ushowed "Nothing to push" even though manifest had commits- The manifest repo wasn't being tracked as having changes by
gr
Discovered: 2026-02-05 during PR merge tests implementation
Problem: Feature branch was based on older version of main. When CI failed due to a function signature change on main (new update and auto parameters added to run_pr_merge), needed to rebase onto latest main to get the updated code.
Workaround used: Raw git fetch origin main && git rebase origin/main followed by gr push --force
Raw commands used:
git fetch origin main
git rebase origin/main
gr push --forceExpected behavior: gr rebase main or gr rebase --onto main that:
- Fetches latest from origin
- Rebases current branch onto origin/main across all repos with changes
- Handles conflicts with helpful messaging
Note: This friction occurred twice during the same PR - once after the initial CI failure, and again after the first rebase when function signatures changed further.
Status: 🔴 ACTIVE - Encountered while merging PR #186
Discovered: 2026-02-03
Problem: When trying to merge PR #186 with gr pr merge, got error:
⚠ Some PRs have issues:
- tooling PR #186: not approved
- tooling PR #186: checks still running
Error: API error: Failed to merge PR: GitHub
GitHub error: "head branch is not up to date with the base branch"
Attempted solutions:
gr sync- synced successfully but PR still blockedgr rebase main- Failed with "0 rebased, 2 failed, 10 skipped"- Manual
git rebase origin/main- Not attempted due to complexity
Workaround used: Had to manually investigate with gh pr view and git log to discover:
- Local main branch was 2 commits behind origin/main
- Feature branch was based on old main
- PR branch couldn't merge because it lacked those 2 commits
Root cause: gr sync updates local repos but doesn't rebase feature branches onto latest main. The PR becomes stale relative to the base branch.
Expected behavior: gr should either:
- Automatically rebase feature branches before merge attempt
- Provide a command to update PR branch with latest main
- Show clear guidance on how to fix "branch behind" issues
Raw commands needed:
gh pr view 186 --repo laynepenney/gitgrip # To see PR is BEHIND
git log --oneline main..origin/main # To see missing commitsStatus: 🔴 ACTIVE - Encountered while fixing PR merge
Discovered: 2026-02-03
Problem: When trying to switch from feature branch to main:
gr checkout main
✗ tooling: Operation failed: error: Your local changes to the following files would be overwritten by checkout:
CLAUDE.md
Aborting
Even after gr add . and switching, still blocked because the staged changes were on the wrong branch.
Workaround: Had to:
- Switch back to feature branch
- Commit the changes there
- Then switch to main
Expected behavior: gr checkout should either:
- Automatically stash/unstash changes when switching
- Prompt user to commit or stash
- Show clearer error about which branch has the changes