|
1 | 1 | # TODO - git-cross |
2 | 2 |
|
| 3 | +## Summary |
| 4 | + |
| 5 | +**Status:** v0.2.1 released with prune command and sync fixes |
| 6 | +**Critical Issues:** 0 (all P0 issues resolved) |
| 7 | +**Pending Enhancements:** 2 (single-file patch, fzf improvements) |
| 8 | + |
3 | 9 | ## Core Implementation Status |
4 | 10 |
|
5 | 11 | - [x] Go Implementation (Primary) - Feature parity achieved. |
|
31 | 37 |
|
32 | 38 | ## Future Enhancements / Backlog |
33 | 39 |
|
34 | | -- [x] `cross list` comand shall either print all cross remote repositories (REMOTE (alias), GIT URL) in separate table above the table with patches. Or directly inline with each patch. |
35 | | -- [x] Implement `cross remove` patch, to remove local_pathch patch and it's worktree. Finally clean up the Metadata an Crossfile. Once physically removed, `git worktree prune` will clenaup git itself. |
36 | | -- [ ] Implement `cross prune [remote name]` to remove git remote repo registration from "cross use" command and ask user whether either remove all git remotes without active cross patches (like after: cross remove), then `git worktree prune` to remove all worktrees. optional argument (an remote repo alias/name would enforce either removal of all it's patches altogther with worktrees and remotes) |
37 | | -- [x] Re-implement `wt` (worktree) command in Go and Rust with full test coverage (align logic with Justfile). |
38 | | -- [ ] Refactor `cross cd` to target local patched folder and output path (no subshell), supporting fzf. |
39 | | -- [ ] Review and propose implementation (tool and test) to be able patch even single file. If not easily possible without major refactoring, then evaluate new command "patch-file". |
40 | | -- [ ] Improve interactive `fzf` selection in native implementations. |
| 40 | +### P1: High Priority |
| 41 | +- [x] **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), then `git worktree prune` to remove all worktrees. Optional argument (a remote repo alias/name) would enforce removal of all its patches together with worktrees and remotes. |
| 42 | + - **Effort:** 3-4 hours (completed 2025-01-06) |
| 43 | + - **Files:** `src-go/main.go`, `src-rust/src/main.rs`, `Justfile.cross`, `test/015_prune.sh` |
| 44 | + - **Implementation:** |
| 45 | + - ✅ Justfile.cross (lines 230-303): Full interactive prune with confirmation |
| 46 | + - ✅ Go (src-go/main.go): Cobra command with same logic |
| 47 | + - ✅ Rust (src-rust/src/main.rs): Clap command with same logic |
| 48 | + - ✅ Test coverage (test/015_prune.sh): 3 test scenarios |
| 49 | + - **Behavior:** |
| 50 | + - `cross prune`: Finds unused remotes, asks for confirmation, removes them, prunes stale worktrees |
| 51 | + - `cross prune <remote>`: Removes all patches for that remote, then removes the remote itself |
| 52 | + - **Status:** COMPLETE - Ready for v0.2.1 release |
| 53 | + |
| 54 | +### P2: Medium Priority |
| 55 | +- [x] **Fix `cross cd` and `cross wt` commands** - Correct behavior for navigation |
| 56 | + - **Issue:** Commands needed proper separation of concerns and clipboard functionality |
| 57 | + - **Design Intent:** |
| 58 | + - `cross wt [path]` → Navigate to WORKTREE (`.git/cross/worktrees/`) - for git history operations |
| 59 | + - `cross cd [path]` → Navigate to LOCAL_PATH (patched directory) - for editing files |
| 60 | + - With explicit path: Open subshell in target directory |
| 61 | + - Without path (fzf): Copy selected path to clipboard for flexibility |
| 62 | + - **Implemented Behavior:** |
| 63 | + - **With path argument:** Opens subshell in target directory (cd → local_path, wt → worktree) |
| 64 | + - **Without path argument:** Uses fzf to select patch, then copies path to clipboard |
| 65 | + - **Rationale:** User with explicit path wants immediate access; user selecting needs flexibility |
| 66 | + - **Clipboard Support:** |
| 67 | + - macOS: Uses `pbcopy` |
| 68 | + - Linux: Uses `xclip` or `xsel` (with fallback) |
| 69 | + - Shows success message: "Path copied to clipboard: <path>" |
| 70 | + - **Implementation:** |
| 71 | + - ✅ Justfile.cross (lines 754-865): Simplified `_open_shell` with path-based logic |
| 72 | + - ✅ Go (src-go/main.go lines 681-818): Removed `--copy` flag, path-based behavior |
| 73 | + - ✅ Rust (src-rust/src/main.rs lines 424-525, 905-910): Added clipboard support, path-based logic |
| 74 | + - ✅ Test coverage (test/017_cd_wt_fix.sh): Basic functionality and error handling |
| 75 | + - **Effort:** 3 hours (completed 2025-01-06) |
| 76 | + - **Files:** `Justfile.cross`, `src-go/main.go`, `src-rust/src/main.rs`, `test/common.sh`, `test/017_cd_wt_fix.sh` |
| 77 | + - **Impact:** HIGH - Fixes command behavior, adds clipboard workflow for flexibility |
| 78 | + - **Status:** COMPLETE - All three implementations updated with feature parity |
| 79 | + |
| 80 | +- [ ] **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". |
| 81 | + - **Effort:** 4-6 hours (includes research) |
| 82 | + |
| 83 | +- [ ] **Improve interactive `fzf` selection** in native implementations - Better UI, preview panes, multi-select for batch operations. |
| 84 | + - **Effort:** 3-5 hours |
| 85 | + |
| 86 | +### P3: Low Priority (UX Improvements) |
| 87 | + |
| 88 | +- [ ] **Context-aware `cross diff` command** - Smart diff behavior based on current working directory |
| 89 | + - **Issue:** Currently `cross diff` shows diffs for ALL patches regardless of PWD |
| 90 | + - **Desired Behavior:** |
| 91 | + - When executed inside a patched local_path: Show diff only for that specific patch |
| 92 | + - When executed outside any patch (anywhere in repo): Show diffs for all patches |
| 93 | + - When given explicit path argument: Show diff for that specific patch with informative header |
| 94 | + - **Effort:** 4-6 hours (includes complexity analysis and implementation) |
| 95 | + - **Files:** `Justfile.cross`, `src-go/main.go`, `src-rust/src/main.rs`, `test/016_diff_context.sh` |
| 96 | + - **Complexity Analysis Required:** |
| 97 | + - **Current Implementation:** |
| 98 | + - Justfile: Uses `_resolve_context2` to resolve patch from path/PWD (lines 578-592) |
| 99 | + - Go: Iterates all patches, filters by explicit path arg only (lines 880-911) |
| 100 | + - Rust: Same as Go - no PWD detection (lines 1194-1214) |
| 101 | + - **Required Changes:** |
| 102 | + - **Low complexity** for Justfile (already has PWD resolution via `_resolve_context2`) |
| 103 | + - **Medium complexity** for Go/Rust (need to add PWD detection logic) |
| 104 | + - Need to add: Get PWD → Check if inside patch → Filter patches accordingly |
| 105 | + - **Implementation Strategy:** |
| 106 | + 1. Detect current working directory relative to repo root |
| 107 | + 2. Check if CWD is within any patch's local_path |
| 108 | + 3. Filter patches based on context: |
| 109 | + - If inside patch + no explicit arg → show only that patch |
| 110 | + - If outside patches + no explicit arg → show all patches |
| 111 | + - If explicit arg provided → show only that patch (current behavior) |
| 112 | + 4. Add informative header: "Diff for patch: {local_path}" when contextual |
| 113 | + - **Impact Assessment:** |
| 114 | + - **User Experience:** HIGH - More intuitive, reduces noise |
| 115 | + - **Breaking Changes:** NONE - Backwards compatible (explicit args work same) |
| 116 | + - **Code Complexity:** LOW to MEDIUM |
| 117 | + - Justfile: ~10-15 lines (reuse existing `_resolve_context2`) |
| 118 | + - Go: ~20-30 lines (add `getCurrentPath()` helper) |
| 119 | + - Rust: ~20-30 lines (add `get_current_path()` helper) |
| 120 | + - **Testing:** MEDIUM - Need scenarios for: |
| 121 | + 1. Diff from inside patch (should show only that patch) |
| 122 | + 2. Diff from outside patches (should show all) |
| 123 | + 3. Diff with explicit arg (should show specified patch) |
| 124 | + 4. Diff from nested subdirectory within patch (should resolve parent patch) |
| 125 | + - **Edge Cases:** |
| 126 | + - CWD inside nested subdirectory of patch (needs parent resolution) |
| 127 | + - Multiple patches in nested directories (resolve closest parent) |
| 128 | + - Symlinked directories (should follow symlinks) |
| 129 | + - **Priority Rationale:** Low priority - UX improvement, not a bug |
| 130 | + - **Status:** Documented for future implementation |
| 131 | + |
| 132 | +### Completed Enhancements |
41 | 133 |
|
42 | 134 | ## Known Issues (To FIX) |
43 | 135 |
|
| 136 | +### ✅ P0: Sync Command Data Loss (FIXED) |
| 137 | + |
| 138 | +- [x] **Issue:** The `cross sync` command in Go (and Rust) did not preserve local uncommitted changes. When users modified files in patched directory and ran sync, changes were lost/reverted. |
| 139 | + |
| 140 | +**Fix Applied (2025-01-06):** |
| 141 | +- ✅ Go implementation (`src-go/main.go`): Added complete stash/restore workflow |
| 142 | +- ✅ Rust implementation (`src-rust/src/main.rs`): Added complete stash/restore workflow |
| 143 | +- ✅ Justfile implementation (`Justfile.cross`): Added explicit stash/restore workflow with file deletion detection |
| 144 | +- ✅ Test coverage enhanced (`test/004_sync.sh`): 6 comprehensive test scenarios |
| 145 | +- ✅ Added cleanup logic between tests to handle conflicted worktree states |
| 146 | +- ✅ Added file deletion detection: removes local files that were deleted upstream |
| 147 | + |
| 148 | +**Workflow Now:** |
| 149 | +``` |
| 150 | +1. Detect uncommitted changes (including untracked files) in local_path |
| 151 | +2. Rsync git-tracked files WITH current uncommitted content: local_path → worktree |
| 152 | +3. Stash uncommitted changes in local_path (with --include-untracked) |
| 153 | +4. Commit changes in worktree |
| 154 | +5. Check worktree state (recover from detached HEAD, abort in-progress operations) |
| 155 | +6. Pull --rebase from upstream |
| 156 | +7. Handle conflicts (exit if detected) |
| 157 | +8. Detect and remove local files that were deleted upstream |
| 158 | +9. Rsync worktree → local_path |
| 159 | +10. Restore stashed changes |
| 160 | +11. Detect and report merge conflicts |
| 161 | +``` |
| 162 | + |
| 163 | +**Test Scenarios Covered:** |
| 164 | +1. ✅ Basic sync with no local changes |
| 165 | +2. ✅ Sync with uncommitted local changes (preserves them) |
| 166 | +3. ✅ Sync with committed local changes |
| 167 | +4. ✅ Sync with conflicting changes (graceful failure) |
| 168 | +5. ✅ Sync with deleted upstream file (removes locally) |
| 169 | +6. ✅ Sync with new upstream file (adds locally) |
| 170 | + |
| 171 | +**Testing:** Run `just cross-test 004` to validate all scenarios |
| 172 | +**Impact:** Data loss risk eliminated, file synchronization complete |
| 173 | +**Status:** FIXED - Ready for v0.2.1 release |
44 | 174 | - [x] 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.) |
45 | 175 | - [x] Extend the tests, start using <https://github.com/runtipi/runtipi-appstore/> and sub-path apps/ for "patches". Document this in test-case design. |
46 | 176 | - [x] 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) |
|
0 commit comments