Status: v0.2.1 released with prune command and sync fixes
Critical Issues: 0 (all P0 issues resolved)
Pending Enhancements: 2 (single-file patch, fzf improvements)
- Go Implementation (Primary) - Feature parity achieved.
- Justfile/Fish - Fully functional original version.
- Rust Implementation (Experimental/WIP) - Refactored to
git2andduct.
- Create ADR for Go-primary implementation strategy.
- Implement GitHub Release builds for Go (via GoReleaser).
- Implement GitHub Release builds for Rust (via Matrix/Artifacts).
- Update README and status to reflect implementation priorities.
- Setup unified Release workflow.
- Refactor remaining Rust commands to use
ductfor better error visibility. - Complete
pushcommand verification in native implementations. - Integrate integration tests (001-009) into a unified test runner.
- Implement
cross installcommand in Go to handle Git alias setup. - Implement
cross initto setup a new project with Crossfile. - Update In README.md, an example how users can implement their "post-hook" actions.
- Implement the test 006 for "push" command.
- Implement the test 007 for "status" command.
- Wire test 7 to github CI workflow.
- Implement "cross" command in Rust.
- Implement "cross" command in Golang.
- Update AGENTS.md, specs/ and .specify/ to reflect new implementations.
- Implement
cross prune [remote name]- Remove git remote registration from "cross use" command and ask user whether to remove all git remotes without active cross patches (like after: cross remove), thengit worktree pruneto remove all worktrees. Optional argument (a remote repo alias/name) would enforce removal of all its patches together with worktrees and remotes.- Effort: 3-4 hours (completed 2025-01-06)
- Files:
src-go/main.go,src-rust/src/main.rs,Justfile.cross,test/015_prune.sh - Implementation:
- ✅ Justfile.cross (lines 230-303): Full interactive prune with confirmation
- ✅ Go (src-go/main.go): Cobra command with same logic
- ✅ Rust (src-rust/src/main.rs): Clap command with same logic
- ✅ Test coverage (test/015_prune.sh): 3 test scenarios
- Behavior:
cross prune: Finds unused remotes, asks for confirmation, removes them, prunes stale worktreescross prune <remote>: Removes all patches for that remote, then removes the remote itself
- Status: COMPLETE - Ready for v0.2.1 release
-
Fix
cross cdandcross wtcommands - Correct behavior for navigation- Issue: Commands needed proper separation of concerns and clipboard functionality
- Design Intent:
cross wt [path]→ Navigate to WORKTREE (.git/cross/worktrees/) - for git history operationscross cd [path]→ Navigate to LOCAL_PATH (patched directory) - for editing files- With explicit path: Open subshell in target directory
- Without path (fzf): Copy selected path to clipboard for flexibility
- Implemented Behavior:
- With path argument: Opens subshell in target directory (cd → local_path, wt → worktree)
- Without path argument: Uses fzf to select patch, then copies path to clipboard
- Rationale: User with explicit path wants immediate access; user selecting needs flexibility
- Clipboard Support:
- macOS: Uses
pbcopy - Linux: Uses
xcliporxsel(with fallback) - Shows success message: "Path copied to clipboard: "
- macOS: Uses
- Implementation:
- ✅ Justfile.cross (lines 754-865): Simplified
_open_shellwith path-based logic - ✅ Go (src-go/main.go lines 681-818): Removed
--copyflag, path-based behavior - ✅ Rust (src-rust/src/main.rs lines 424-525, 905-910): Added clipboard support, path-based logic
- ✅ Test coverage (test/017_cd_wt_fix.sh): Basic functionality and error handling
- ✅ Justfile.cross (lines 754-865): Simplified
- Effort: 3 hours (completed 2025-01-06)
- Files:
Justfile.cross,src-go/main.go,src-rust/src/main.rs,test/common.sh,test/017_cd_wt_fix.sh - Impact: HIGH - Fixes command behavior, adds clipboard workflow for flexibility
- Status: COMPLETE - All three implementations updated with feature parity
-
Single file patch capability - Review and propose implementation (tool and test) to be able to patch even single file. If not easily possible without major refactoring, evaluate new command "patch-file".
- Effort: 4-6 hours (includes research)
-
Improve interactive
fzfselection in native implementations - Better UI, preview panes, multi-select for batch operations.- Effort: 3-5 hours
- Context-aware
cross diffcommand - Smart diff behavior based on current working directory- Issue: Currently
cross diffshows diffs for ALL patches regardless of PWD - Desired Behavior:
- When executed inside a patched local_path: Show diff only for that specific patch
- When executed outside any patch (anywhere in repo): Show diffs for all patches
- When given explicit path argument: Show diff for that specific patch with informative header
- Effort: 4-6 hours (includes complexity analysis and implementation)
- Files:
Justfile.cross,src-go/main.go,src-rust/src/main.rs,test/016_diff_context.sh - Complexity Analysis Required:
- Current Implementation:
- Justfile: Uses
_resolve_context2to resolve patch from path/PWD (lines 578-592) - Go: Iterates all patches, filters by explicit path arg only (lines 880-911)
- Rust: Same as Go - no PWD detection (lines 1194-1214)
- Justfile: Uses
- Required Changes:
- Low complexity for Justfile (already has PWD resolution via
_resolve_context2) - Medium complexity for Go/Rust (need to add PWD detection logic)
- Need to add: Get PWD → Check if inside patch → Filter patches accordingly
- Low complexity for Justfile (already has PWD resolution via
- Implementation Strategy:
- Detect current working directory relative to repo root
- Check if CWD is within any patch's local_path
- Filter patches based on context:
- If inside patch + no explicit arg → show only that patch
- If outside patches + no explicit arg → show all patches
- If explicit arg provided → show only that patch (current behavior)
- Add informative header: "Diff for patch: {local_path}" when contextual
- Impact Assessment:
- User Experience: HIGH - More intuitive, reduces noise
- Breaking Changes: NONE - Backwards compatible (explicit args work same)
- Code Complexity: LOW to MEDIUM
- Justfile: ~10-15 lines (reuse existing
_resolve_context2) - Go: ~20-30 lines (add
getCurrentPath()helper) - Rust: ~20-30 lines (add
get_current_path()helper)
- Justfile: ~10-15 lines (reuse existing
- Testing: MEDIUM - Need scenarios for:
- Diff from inside patch (should show only that patch)
- Diff from outside patches (should show all)
- Diff with explicit arg (should show specified patch)
- Diff from nested subdirectory within patch (should resolve parent patch)
- Edge Cases:
- CWD inside nested subdirectory of patch (needs parent resolution)
- Multiple patches in nested directories (resolve closest parent)
- Symlinked directories (should follow symlinks)
- Current Implementation:
- Priority Rationale: Low priority - UX improvement, not a bug
- Status: Documented for future implementation
- Issue: Currently
- Issue: The
cross synccommand in Go (and Rust) did not preserve local uncommitted changes. When users modified files in patched directory and ran sync, changes were lost/reverted.
Fix Applied (2025-01-06):
- ✅ Go implementation (
src-go/main.go): Added complete stash/restore workflow - ✅ Rust implementation (
src-rust/src/main.rs): Added complete stash/restore workflow - ✅ Justfile implementation (
Justfile.cross): Added explicit stash/restore workflow with file deletion detection - ✅ Test coverage enhanced (
test/004_sync.sh): 6 comprehensive test scenarios - ✅ Added cleanup logic between tests to handle conflicted worktree states
- ✅ Added file deletion detection: removes local files that were deleted upstream
Workflow Now:
1. Detect uncommitted changes (including untracked files) in local_path
2. Rsync git-tracked files WITH current uncommitted content: local_path → worktree
3. Stash uncommitted changes in local_path (with --include-untracked)
4. Commit changes in worktree
5. Check worktree state (recover from detached HEAD, abort in-progress operations)
6. Pull --rebase from upstream
7. Handle conflicts (exit if detected)
8. Detect and remove local files that were deleted upstream
9. Rsync worktree → local_path
10. Restore stashed changes
11. Detect and report merge conflicts
Test Scenarios Covered:
- ✅ Basic sync with no local changes
- ✅ Sync with uncommitted local changes (preserves them)
- ✅ Sync with committed local changes
- ✅ Sync with conflicting changes (graceful failure)
- ✅ Sync with deleted upstream file (removes locally)
- ✅ Sync with new upstream file (adds locally)
Testing: Run just cross-test 004 to validate all scenarios
Impact: Data loss risk eliminated, file synchronization complete
Status: FIXED - Ready for v0.2.1 release
- Updates to Crossfile can create duplicit lines (especially if user add spaces between remote_spec and local_spec.) Ideally we shall only check whether the local/path is already specified, and if yes then avoid update and avoid patch (as path exist.)
- Extend the tests, start using https://github.com/runtipi/runtipi-appstore/ and sub-path apps/ for "patches". Document this in test-case design.
- Looks like the worktree created dont have any more "sparse checkout". Extend the validation, ie: that no other top-level files present in checkouts (assuming sub-path is used on remote repo)
- If remote_spec contains "khue:master:/metal" the first slash shall be auto-removed
- Remove " [branch]" string at end of some commented examples under ./examples, branch is now part of remote_spec.
- on Golang implementation, the use command fails to autodetect and use real branch. example:
❯ git cross use bill https://github.com/billimek/k8s-gitops
==> Adding remote bill (https://github.com/billimek/k8s-gitops)...
==> Autodetecting default branch...
==> Detected default branch: main
Error: exit status 128 - fatal: couldn't find remote ref main- on Golang implementation, the patch command can't properly use recognized branch, failed example:
❯ git cross patch khue:/metal deploy/metal
==> Patching khue:/metal to deploy/metal
==> Syncing files to deploy/metal...
Error: rsync failed: exit status 23
Log: {rsync: [sender] change_dir "/Users/p.michalec/Work/gitlab-f5-xc/f5/volterra/ves.io/sre/sre-ai/work/git-cross/testdir/sandbox/.git/cross/worktrees/khue_5a7cd8e3//metal" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1358) [sender=3.4.1]
sending incremental file list
sent 19 bytes received 12 bytes 62.00 bytes/sec
total size is 0 speedup is 0.00
}
Usage:
git-cross patch [spec] [local_path] [flags]
Flags:
-h, --help help for patch- on Golang implementation, the patch command doesn't accept properly the branch name in remote_spec.
git cross patch khue:main:/metal deploy/metal
==> Patching khue:main:/metal to deploy/metal
==> Syncing files to deploy/metal...
Error: rsync failed: exit status 23
Log: {rsync: [sender] change_dir "/Users/p.michalec/Work/gitlab-f5-xc/f5/volterra/ves.io/sre/sre-ai/work/git-cross/testdir/sandbox/.git/cross/worktrees/khue_5f54dee3/main" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1358) [sender=3.4.1]
sending incremental file list