From f70af9b185a355873b1a780fa1b02f58b35aa654 Mon Sep 17 00:00:00 2001 From: Adam Jeniski Date: Wed, 21 Jan 2026 11:27:51 -0500 Subject: [PATCH] init --- .gitignore | 9 + CLAUDE.md | 179 ++ PRD.md | 851 ++++++++++ bb.edn | 10 + src/lazygitclj/core.clj | 938 ++++++++++ src/lazygitclj/git.clj | 428 +++++ .../e2e/aspect-ratio/lazygit-classic-4-3.tape | 15 + .../aspect-ratio/lazygit-standard-16-9.tape | 15 + test/e2e/aspect-ratio/lazygit-tall-9-16.tape | 15 + .../aspect-ratio/lazygit-ultrawide-32-9.tape | 15 + test/e2e/aspect-ratio/lazygit-wide-21-9.tape | 15 + .../aspect-ratio/lazygitclj-classic-4-3.tape | 17 + .../lazygitclj-standard-16-9.tape | 17 + .../aspect-ratio/lazygitclj-tall-9-16.tape | 17 + .../lazygitclj-ultrawide-32-9.tape | 17 + .../aspect-ratio/lazygitclj-wide-21-9.tape | 17 + test/e2e/branch-operations.tape | 68 + test/e2e/branches-tabs.tape | 48 + test/e2e/branches.tape | 39 + test/e2e/commit-verify.tape | 85 + test/e2e/commit.tape | 50 + test/e2e/commits-tabs.tape | 46 + test/e2e/debug.tape | 31 + test/e2e/file1.txt | 0 test/e2e/help-panel.tape | 50 + test/e2e/navigation.tape | 73 + test/e2e/reset-menu.tape | 57 + test/e2e/run-all.sh | 54 + test/e2e/setup-test-repo.sh | 47 + test/e2e/staging.tape | 45 + test/e2e/stash-menu.tape | 50 + test/e2e/stash-operations.tape | 52 + .../test/e2e/output/branch-operations.ascii | 1176 +++++++++++++ test/e2e/test/e2e/output/branches-tabs.ascii | 816 +++++++++ test/e2e/test/e2e/output/branches.ascii | 696 ++++++++ test/e2e/test/e2e/output/commit-verify.ascii | 1506 +++++++++++++++++ test/e2e/test/e2e/output/commit.ascii | 906 ++++++++++ test/e2e/test/e2e/output/commits-tabs.ascii | 816 +++++++++ test/e2e/test/e2e/output/debug.ascii | 636 +++++++ test/e2e/test/e2e/output/help-panel.ascii | 756 +++++++++ test/e2e/test/e2e/output/navigation.ascii | 1296 ++++++++++++++ test/e2e/test/e2e/output/reset-menu.ascii | 876 ++++++++++ test/e2e/test/e2e/output/staging.ascii | 816 +++++++++ test/e2e/test/e2e/output/stash-menu.ascii | 756 +++++++++ .../test/e2e/output/stash-operations.ascii | 876 ++++++++++ test/e2e/test/e2e/output/undo-redo.ascii | 1176 +++++++++++++ test/e2e/undo-redo.tape | 59 + test/lazygitclj/core_test.clj | 288 ++++ test/lazygitclj/git_test.clj | 323 ++++ test/run-tests.clj | 22 + 50 files changed, 17166 insertions(+) create mode 100644 .gitignore create mode 100644 CLAUDE.md create mode 100644 PRD.md create mode 100644 bb.edn create mode 100644 src/lazygitclj/core.clj create mode 100644 src/lazygitclj/git.clj create mode 100644 test/e2e/aspect-ratio/lazygit-classic-4-3.tape create mode 100644 test/e2e/aspect-ratio/lazygit-standard-16-9.tape create mode 100644 test/e2e/aspect-ratio/lazygit-tall-9-16.tape create mode 100644 test/e2e/aspect-ratio/lazygit-ultrawide-32-9.tape create mode 100644 test/e2e/aspect-ratio/lazygit-wide-21-9.tape create mode 100644 test/e2e/aspect-ratio/lazygitclj-classic-4-3.tape create mode 100644 test/e2e/aspect-ratio/lazygitclj-standard-16-9.tape create mode 100644 test/e2e/aspect-ratio/lazygitclj-tall-9-16.tape create mode 100644 test/e2e/aspect-ratio/lazygitclj-ultrawide-32-9.tape create mode 100644 test/e2e/aspect-ratio/lazygitclj-wide-21-9.tape create mode 100644 test/e2e/branch-operations.tape create mode 100644 test/e2e/branches-tabs.tape create mode 100644 test/e2e/branches.tape create mode 100644 test/e2e/commit-verify.tape create mode 100644 test/e2e/commit.tape create mode 100644 test/e2e/commits-tabs.tape create mode 100644 test/e2e/debug.tape create mode 100644 test/e2e/file1.txt create mode 100644 test/e2e/help-panel.tape create mode 100644 test/e2e/navigation.tape create mode 100644 test/e2e/reset-menu.tape create mode 100755 test/e2e/run-all.sh create mode 100755 test/e2e/setup-test-repo.sh create mode 100644 test/e2e/staging.tape create mode 100644 test/e2e/stash-menu.tape create mode 100644 test/e2e/stash-operations.tape create mode 100644 test/e2e/test/e2e/output/branch-operations.ascii create mode 100644 test/e2e/test/e2e/output/branches-tabs.ascii create mode 100644 test/e2e/test/e2e/output/branches.ascii create mode 100644 test/e2e/test/e2e/output/commit-verify.ascii create mode 100644 test/e2e/test/e2e/output/commit.ascii create mode 100644 test/e2e/test/e2e/output/commits-tabs.ascii create mode 100644 test/e2e/test/e2e/output/debug.ascii create mode 100644 test/e2e/test/e2e/output/help-panel.ascii create mode 100644 test/e2e/test/e2e/output/navigation.ascii create mode 100644 test/e2e/test/e2e/output/reset-menu.ascii create mode 100644 test/e2e/test/e2e/output/staging.ascii create mode 100644 test/e2e/test/e2e/output/stash-menu.ascii create mode 100644 test/e2e/test/e2e/output/stash-operations.ascii create mode 100644 test/e2e/test/e2e/output/undo-redo.ascii create mode 100644 test/e2e/undo-redo.tape create mode 100644 test/lazygitclj/core_test.clj create mode 100644 test/lazygitclj/git_test.clj create mode 100644 test/run-tests.clj diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..20ae152 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +.cpcache/ +.nrepl-port +target/ +*.jar + +# Generated test outputs +*.gif +*.png +test/e2e/output/ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..32e108e --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,179 @@ +# Claude Code Instructions for lazygitclj + +## Clojure Development + +- Use Clojure skills (nREPL evaluation) when editing code to verify changes compile and work correctly +- Evaluate code in the REPL to test functions before committing changes +- Run `bb start` to launch the application, `bb test` for unit tests + +## Local TUI Library + +- The TUI library is at `../clojure-tui/` (local dependency in bb.edn) +- You have access to edit the local TUI library in conjunction with this repo +- Use this access to debug issues, support new features, and simplify code +- Look for opportunities to create better abstraction primitives for TUI layout + +## Testing with VHS + +- Use VHS to test all changes and verify behavior before finishing any task +- Run `bb test:e2e` to run VHS tape tests +- Run VHS tape files to capture terminal recordings and validate UI behavior +- Do not consider a task complete until changes have been verified with VHS + +## Understanding Expected Behavior + +- Reference the lazygit repository and documentation to understand expected behaviors +- Use VHS locally with lazygit to compare and verify that lazygitclj matches expected interaction patterns +- When implementing features, check how lazygit handles the same functionality +- See `PRD.md` for detailed lazygit behavior documentation + +--- + +## Project Overview + +lazygitclj is a lazygit-inspired TUI for Git written in Clojure, targeting Babashka for fast startup. It follows the Elm Architecture pattern (Model-Update-View). + +## Project Structure + +``` +src/lazygitclj/ +├── core.clj # Main TUI app: views, update logic, keybindings (883 lines) +├── git.clj # Git operations wrapper via shell commands (478 lines) +└── debug_tui.clj # Layout debugging utility +test/ +├── lazygitclj/ +│ ├── core_test.clj # Model/update function tests +│ └── git_test.clj # Git operations tests (uses temp repo fixture) +└── run-tests.clj # Test runner +``` + +## Build Commands + +| Command | Purpose | +|---------|---------| +| `bb start` | Run lazygitclj TUI | +| `bb debug` | Debug TUI layout issues | +| `bb test` | Run unit tests | +| `bb test:e2e` | Run VHS tape tests | + +## Architecture: Elm Pattern + +```clojure +(tui/run {:init (initial-model) + :update update-model + :view view}) +``` + +- **Model**: Application state as a map +- **Update**: Pure functions returning `[new-model command]` tuples +- **View**: Pure functions rendering hiccup-style VDom + +## Model Structure + +```clojure +{:panel :files ;; Current panel: :files, :branches, :commits, :stash + :cursor 0 ;; Cursor position in current panel + :message nil ;; Transient message display + :input-mode nil ;; :commit, :new-branch, :rename-branch, etc. + :input-buffer "" ;; Text input during modal entry + :menu-mode nil ;; :stash-options, :reset-options, :help + :commits-tab :commits ;; :commits or :reflog + :branches-tab :local ;; :local, :remotes, or :tags + :branch "main" ;; Current branch + :sha "abc1234" ;; HEAD SHA + :ahead-behind [0 0] ;; [ahead, behind] upstream + :staged [...] ;; Staged files + :unstaged [...] ;; Unstaged/untracked files + :commits [...] ;; Recent commits + :branches [...] ;; Local branches + :remote-branches [...] ;; Remote branches + :tags [...] ;; Tags + :stashes [...] ;; Stash entries + :reflog [...] ;; Reflog for undo/redo + :diff nil} ;; Currently displayed diff +``` + +## Key Functions in core.clj + +| Function | Purpose | +|----------|---------| +| `initial-model` | Create initial application state | +| `load-git-data` | Load all git state via git.clj | +| `refresh` | Reload git data and update diff | +| `update-model` | Main dispatcher for keyboard input | +| `update-files` | Handle files panel (stage, unstage, commit) | +| `update-commits` | Handle commits panel (checkout, cherry-pick, revert) | +| `update-branches` | Handle branches panel (checkout, create, delete, merge) | +| `update-stash` | Handle stash panel (apply, pop, drop) | +| `file-items` | Combine staged/unstaged files with type metadata | +| `current-items` | Get items for current panel | +| `view` | Render UI based on state and dimensions | + +## Keybindings + +**Global**: `q` quit, `?` help, `r` refresh, `h/l` panel nav, `j/k` cursor, `z/Z` undo/redo, `p/P` pull/push, `D` reset menu + +**Files**: `space` stage/unstage, `a` stage all, `c` commit, `d` discard, `s/S` stash + +**Commits**: `space` checkout, `g` reset to, `C` cherry-pick, `t` revert, `r` reword, `[/]` tabs + +**Branches**: `enter` checkout, `n` new, `d` delete, `R` rename, `M` merge, `f` fast-forward, `[/]` tabs + +**Stash**: `space` apply, `g` pop, `d` drop, `n` branch from stash + +## Git Operations (git.clj) + +All git operations wrap `babashka.process/shell` and return `nil` on error. + +**Categories**: +- Status: `current-branch`, `head-sha`, `ahead-behind` +- Files: `status-files`, `staged-files`, `unstaged-files` +- Staging: `stage-file`, `unstage-file`, `stage-all` +- Diff: `diff-file`, `diff-staged`, `show-commit`, `diff-branch` +- Actions: `commit`, `discard-file`, `pull`, `push` +- Stash: `stash-list`, `stash-push`, `stash-pop`, `stash-apply`, `stash-drop` +- Reset: `reset-soft`, `reset-mixed`, `reset-hard` +- Branches: `create-branch`, `checkout-branch`, `delete-branch`, `merge-branch` +- Tags: `list-tags`, `create-tag`, `delete-tag` + +## TUI Library Primitives + +```clojure +;; Containers +[:row {:widths [30 :flex] :gap 1} left right] +[:col {:heights [3 :flex :flex 4]} top mid1 mid2 bottom] +[:box {:border :double :title "Title"} content] + +;; Text with styling +[:text {:fg :green :bold true} "content"] +``` + +- `:flex` keyword items share remaining space equally +- Borders: `:single`, `:double`, `:rounded` +- Colors: `:red`, `:green`, `:yellow`, `:blue`, `:magenta`, `:cyan`, `:white` + +## Responsive Layout + +- **Narrow (< 70 cols)**: Single-column stacked layout +- **Wide (>= 70 cols)**: Two-column (left panels 30 cols, right diff flex) + +## File Status Format + +Files parsed from `git status --porcelain`: +```clojure +{:index \M :worktree \space :path "file.txt"} +``` + +## Diff Coloring + +- `+` lines: green (additions) +- `-` lines: red (deletions) +- `@@` lines: cyan (hunk headers) +- `diff`/`commit` lines: yellow (headers) + +## Conventions + +- Predicates end with `?` (e.g., `can-fast-forward?`) +- Private functions prefixed with `-` (e.g., `-sh`, `-parse-status-line`) +- Update functions return `[new-model command]` tuples +- Messages are transient (cleared on next refresh) diff --git a/PRD.md b/PRD.md new file mode 100644 index 0000000..c6c372a --- /dev/null +++ b/PRD.md @@ -0,0 +1,851 @@ +# lazygit - Product Requirements Document + +## Overview + +**lazygit** is a simple terminal UI for git commands, written in Go. It provides an intuitive, keyboard-driven interface for managing git repositories without memorizing complex git commands. + +- **Version**: 0.58.1 +- **Author**: Jesse Duffield +- **Repository**: https://github.com/jesseduffield/lazygit +- **License**: MIT + +## Table of Contents + +1. [Core Concepts](#core-concepts) +2. [User Interface](#user-interface) +3. [Panel System](#panel-system) +4. [Keybindings](#keybindings) +5. [Git Operations](#git-operations) +6. [Configuration](#configuration) +7. [CLI Interface](#cli-interface) +8. [Automation with VHS](#automation-with-vhs) + +--- + +## Core Concepts + +### Design Philosophy + +- **Keyboard-first**: All operations accessible via keyboard shortcuts +- **Context-aware**: Keybindings change based on focused panel and selected item +- **Visual feedback**: Real-time diff views, color-coded file states +- **Non-destructive**: Confirmation prompts for dangerous operations +- **Discoverable**: Built-in help system (`?`) shows available actions + +### File States + +| Indicator | Meaning | +|-----------|---------| +| `M` | Modified (tracked file changed) | +| `A` | Added (new file staged) | +| `D` | Deleted | +| `R` | Renamed | +| `C` | Copied | +| `??` | Untracked (new file not staged) | +| `UU` | Unmerged (conflict) | + +--- + +## User Interface + +### Layout Overview + +``` ++--[1]-Status---------+--[0]-Main View (Diff/Log/Patch)--------+ +| repo-name -> branch | | ++--[2]-Files----------+ | +| Files/Worktrees/ | | +| Submodules | | ++--[3]-Branches-------+ | +| Local/Remotes/Tags | | ++--[4]-Commits--------+-----------------------------------------+ +| Commits/Reflog |--Command log---------------------------+| ++--[5]-Stash----------+ || +| Stash entries | || ++---------------------+----------------------------------------++ +| Status bar: Quick actions | Keybindings: ? | Version 0.58.1| ++------------------------------------------------------------------+ +``` + +### Panel Numbers + +| # | Panel | Description | +|---|-------|-------------| +| 0 | Main View | Displays diffs, logs, patches, commit details | +| 1 | Status | Repository name and current branch | +| 2 | Files | Working tree changes, worktrees, submodules | +| 3 | Branches | Local branches, remotes, tags | +| 4 | Commits | Commit history, reflog | +| 5 | Stash | Stash entries | + +### Navigation Between Panels + +| Key | Action | +|-----|--------| +| `1-5` | Jump directly to panel by number | +| `0` | Focus main view | +| `h/l` or `Left/Right` | Move between panels | +| `Tab` | Toggle between side panels and main view | +| `[` / `]` | Switch tabs within a panel | + +### Screen Modes + +| Key | Mode | Description | +|-----|------|-------------| +| `+` | Next screen mode | Cycles: normal -> half -> full | +| `_` | Previous screen mode | Cycles backwards | + +--- + +## Panel System + +### Panel 1: Status + +Displays the repository name and current branch. + +**Actions:** +| Key | Action | +|-----|--------| +| `Enter` | Recent repositories | +| `a` | All branches log graph | +| `u` | Check for updates | + +### Panel 2: Files / Worktrees / Submodules + +**Tabs:** Files | Worktrees | Submodules + +#### Files Tab + +**File Operations:** +| Key | Action | +|-----|--------| +| `Space` | Stage/unstage file | +| `a` | Stage/unstage all files | +| `Enter` | Enter staging view (line-by-line staging) | +| `d` | Discard changes | +| `D` | Reset options menu | +| `e` | Edit file | +| `o` | Open file | +| `i` | Ignore file (.gitignore) | +| `r` | Refresh files | +| `` ` `` | Toggle file tree view | +| `-` | Collapse all directories | +| `=` | Expand all directories | + +**Commit Operations:** +| Key | Action | +|-----|--------| +| `c` | Commit staged changes | +| `C` | Commit with editor | +| `w` | Commit without pre-commit hook | +| `A` | Amend last commit | +| `Ctrl+f` | Find base commit for fixup | + +**Stash Operations:** +| Key | Action | +|-----|--------| +| `s` | Stash all changes | +| `S` | Stash options menu | + +**Stash Options Menu:** +- `a` - Stash all changes +- `i` - Stash all changes and keep index +- `U` - Stash all changes including untracked files +- `s` - Stash staged changes +- `u` - Stash unstaged changes + +**Reset Options Menu (`D`):** +- `u` - Discard unstaged changes (`git checkout -- .`) +- `d` - Discard untracked files (`git clean -fd`) +- `S` - Discard staged changes (`stash staged and drop stash`) +- `s` - Soft reset (`git reset --soft HEAD`) +- `m` - Mixed reset (`git reset --mixed HEAD`) +- `h` - Hard reset (`git reset --hard HEAD`) + +#### Worktrees Tab + +| Key | Action | +|-----|--------| +| `n` | New worktree | +| `Space` | Switch to worktree | +| `d` | Remove worktree | +| `w` | View worktree options | + +#### Submodules Tab + +| Key | Action | +|-----|--------| +| `i` | Initialize submodule | +| `u` | Update submodule | +| `b` | Bulk menu | +| `Enter` | Enter submodule | + +### Panel 3: Local Branches / Remotes / Tags + +**Tabs:** Local branches | Remotes | Tags + +#### Local Branches Tab + +| Key | Action | +|-----|--------| +| `Space` | Checkout branch | +| `n` | New branch | +| `d` | Delete branch | +| `r` | Rebase current branch onto selected | +| `R` | Rename branch | +| `M` | Merge selected into current branch | +| `f` | Fast-forward branch | +| `F` | Force checkout | +| `-` | Checkout previous branch | +| `u` | Set upstream | +| `i` | View git-flow options | +| `o` | Create pull request | +| `O` | View pull request options | +| `Ctrl+y` | Copy pull request URL | +| `T` | Create tag | +| `s` | Sort order | + +**Rebase Menu (`r`):** +- `s` - Simple rebase onto selected branch +- `i` - Interactive rebase onto selected branch +- `b` - Rebase onto base branch + +#### Remotes Tab + +| Key | Action | +|-----|--------| +| `Enter` | View branches | +| `n` | New remote | +| `d` | Remove remote | +| `e` | Edit remote | +| `f` | Fetch from remote | +| `F` | Add fork remote | + +#### Tags Tab + +| Key | Action | +|-----|--------| +| `Ctrl+o` | Copy tag to clipboard | +| `Space` | Checkout tag | +| `n` | New tag | +| `d` | Delete tag | +| `P` | Push tag | +| `g` | Reset to tag | +| `Enter` | View commits | +| `w` | View worktree options | + +### Panel 4: Commits / Reflog + +**Tabs:** Commits | Reflog + +#### Commits Tab + +**Navigation & Selection:** +| Key | Action | +|-----|--------| +| `j/k` | Move up/down | +| `Space` | Checkout commit | +| `Enter` | View commit files | +| `v` | Toggle range select | +| `*` | Select commits of current branch | + +**Commit Manipulation:** +| Key | Action | +|-----|--------| +| `r` | Reword commit message | +| `R` | Reword with editor | +| `e` | Edit commit (start interactive rebase) | +| `d` | Drop commit | +| `s` | Squash down | +| `S` | Squash all above commits | +| `f` | Mark as fixup | +| `F` | Create fixup commit | +| `p` | Pick commit | +| `Ctrl+j` | Move commit down | +| `Ctrl+k` | Move commit up | +| `i` | Start interactive rebase | + +**Advanced Operations:** +| Key | Action | +|-----|--------| +| `A` | Amend commit with staged changes | +| `a` | Reset commit author | +| `t` | Revert commit | +| `T` | Tag commit | +| `C` | Cherry-pick copy | +| `V` | Paste (cherry-pick) commits | +| `Ctrl+R` | Reset cherry-pick selection | +| `B` | Mark as base for rebase | +| `b` | View bisect options | +| `g` | View reset options | +| `y` | Copy commit attribute to clipboard | +| `o` | Open commit in browser | +| `Ctrl+l` | Open log menu | +| `n` | Create new branch off commit | + +**Bisect Menu (`b`):** +- `b` - Mark commit as bad (start bisect) +- `g` - Mark commit as good (start bisect) +- `t` - Choose bisect terms +- Cancel + +#### Reflog Tab + +Shows the reference log for recovering lost commits. + +| Key | Action | +|-----|--------| +| `Space` | Checkout reflog entry | +| `g` | View reset options | +| `C` | Cherry-pick copy | +| `V` | Paste commits | + +### Panel 5: Stash + +| Key | Action | +|-----|--------| +| `Space` | Apply stash | +| `g` | Pop stash | +| `d` | Drop stash | +| `n` | New branch from stash | +| `r` | Rename stash | +| `Enter` | View stash files | + +--- + +## Keybindings + +### Global Keybindings + +**Navigation:** +| Key | Action | +|-----|--------| +| `j/k` or `Up/Down` | Move up/down in list | +| `h/l` or `Left/Right` | Move between panels | +| `<` / `>` | Go to top/bottom of list | +| `Home` / `End` | Go to top/bottom of list | +| `,` / `.` | Page up/down | +| `PgUp` / `PgDown` | Scroll main window | +| `J/K` or `Ctrl+u/Ctrl+d` | Scroll main window | +| `H` / `L` | Scroll left/right | + +**Actions:** +| Key | Action | +|-----|--------| +| `?` | Show keybindings help | +| `Enter` | Confirm / Go into | +| `Esc` | Return / Cancel | +| `Space` | Primary action (context-dependent) | +| `/` | Start search | +| `n` / `N` | Next/previous search match | +| `q` | Quit | +| `Q` | Quit without changing directory | +| `Ctrl+c` | Quit (alternative) | +| `Ctrl+z` | Suspend application | + +**Git Operations:** +| Key | Action | +|-----|--------| +| `P` | Push | +| `p` | Pull | +| `f` | Fetch (in files panel) | +| `R` | Refresh | +| `z` | Undo (reflog) | +| `Z` | Redo (reflog) | +| `m` | View merge/rebase options | + +**View Options:** +| Key | Action | +|-----|--------| +| `@` | View command log options | +| `+` / `_` | Next/previous screen mode | +| `\|` | Cycle pagers | +| `W` or `Ctrl+e` | Diffing menu | +| `Ctrl+w` | Toggle whitespace in diff | +| `}` / `{` | Increase/decrease diff context | +| `)` / `(` | Increase/decrease rename similarity threshold | +| `Ctrl+t` | Open external diff tool | +| `Ctrl+s` | Filtering menu | + +**Other:** +| Key | Action | +|-----|--------| +| `:` | Execute shell command | +| `Ctrl+r` | Switch to recent repo | +| `Ctrl+o` | Copy to clipboard | +| `Ctrl+p` | View custom patch options | + +### Staging View Keybindings + +When viewing a file's diff (entered via `Enter` on a file): + +| Key | Action | +|-----|--------| +| `Space` | Stage/unstage line | +| `a` | Toggle select hunk | +| `A` | Stage/unstage all changes | +| `v` | Toggle range select | +| `j/k` | Move up/down | +| `J/K` | Scroll diff up/down | +| `E` | Edit hunk in editor | +| `e` | Edit file | +| `o` | Open file | +| `Esc` | Return to files panel | +| `Tab` | Switch to staged/unstaged changes | +| `b` | Pick both hunks (merge conflicts) | + +--- + +## Git Operations + +### Committing + +1. **Stage changes**: `Space` on files or `a` to stage all +2. **Commit**: `c` to commit with inline message +3. **Commit with editor**: `C` to open editor for commit message +4. **Amend**: `A` to amend the last commit with staged changes +5. **Commit without hooks**: `w` to skip pre-commit hooks + +### Branching + +1. **Create branch**: `n` in branches panel +2. **Checkout**: `Space` on branch +3. **Delete**: `d` on branch +4. **Rename**: `R` on branch +5. **Checkout previous**: `-` in branches panel + +### Merging + +1. Navigate to branches panel (`3`) +2. Select the branch to merge +3. Press `M` to merge into current branch + +**During merge conflicts:** +- Files with `UU` status indicate conflicts +- Enter file to resolve conflicts line-by-line +- Use `b` to pick both sides +- Stage resolved files with `Space` +- Continue merge with `m` -> continue option + +### Rebasing + +**Simple rebase:** +1. Go to branches panel +2. Select target branch +3. Press `r` to open rebase menu +4. Choose rebase type + +**Interactive rebase:** +1. Go to commits panel +2. Navigate to the commit before where you want to start +3. Press `i` to start interactive rebase +4. Use `p` (pick), `s` (squash), `f` (fixup), `d` (drop), `e` (edit) +5. Reorder commits with `Ctrl+j/k` +6. Press `m` to view rebase options and continue/abort + +### Cherry-picking + +1. Navigate to the commit to cherry-pick +2. Press `C` to copy the commit +3. Switch to the target branch +4. Press `V` to paste (cherry-pick) +5. Use `Ctrl+R` to reset cherry-pick selection + +### Stashing + +**Quick stash:** +- `s` in files panel stashes all changes + +**Stash options (`S`):** +- Stash all changes +- Stash including untracked +- Stash only staged +- Stash only unstaged +- Keep index + +**Using stashes:** +- `Space` - Apply stash (keep stash) +- `g` - Pop stash (apply and remove) +- `d` - Drop stash + +### Bisecting + +1. Go to commits panel +2. Press `b` to open bisect menu +3. Mark a known bad commit with `b` +4. Mark a known good commit with `g` +5. Test each commit lazygit checks out +6. Mark as good/bad until bug is found +7. Reset bisect when done + +### Working with Remotes + +**Push:** +- `P` globally pushes current branch +- Force push available in push options menu + +**Pull:** +- `p` globally pulls current branch +- Configurable pull strategy (merge/rebase) + +**Fetch:** +- `f` in files panel fetches from remote +- Auto-fetch configurable in settings + +--- + +## Configuration + +### Configuration File Location + +```bash +lazygit --print-config-dir # Shows config directory +# Usually: ~/.config/lazygit/config.yml +``` + +### Key Configuration Options + +```yaml +gui: + # Panel sizing + sidePanelWidth: 0.3333 + expandFocusedSidePanel: false + mainPanelSplitMode: flexible # flexible | horizontal | vertical + + # Display options + showFileTree: true + showIcons: false + nerdFontsVersion: "" # Set to "3" for nerd fonts v3 + showCommandLog: true + showBottomLine: true + showPanelJumps: true + + # Behavior + mouseEvents: true + skipDiscardChangeWarning: false + skipStashWarning: false + + # Theme colors + theme: + activeBorderColor: + - green + - bold + inactiveBorderColor: + - default + selectedLineBgColor: + - blue + unstagedChangesColor: + - red + +git: + # Auto operations + autoFetch: true + autoRefresh: true + fetchAll: true + + # Commit settings + commit: + signOff: false + autoWrapCommitMessage: true + autoWrapWidth: 72 + + # Merge settings + merging: + manualCommit: false + args: "" + + # Main branches for rebase targets + mainBranches: + - master + - main + + # Log display + log: + order: topo-order # topo-order | date-order | author-date-order + showGraph: always # always | never | when-maximised + +# Refresh intervals (seconds) +refresher: + refreshInterval: 10 + fetchInterval: 60 + +# Confirmation settings +confirmOnQuit: false +quitOnTopLevelReturn: false + +# Custom commands (advanced) +customCommands: [] +``` + +### Custom Keybindings + +Keybindings can be customized in `config.yml`: + +```yaml +keybinding: + universal: + quit: q + return: + togglePanel: + prevItem: + nextItem: + # ... etc + files: + commitChanges: c + amendLastCommit: A + # ... etc + branches: + createPullRequest: o + rebaseBranch: r + # ... etc +``` + +### Custom Commands + +Define custom commands accessible via keybindings: + +```yaml +customCommands: + - key: "C" + command: "git cz" # Commitizen + context: "files" + loadingText: "Opening commitizen" + subprocess: true + - key: "b" + command: "git blame {{.SelectedFile.Name}}" + context: "files" + loadingText: "Blaming file" +``` + +--- + +## CLI Interface + +### Basic Usage + +```bash +lazygit # Open in current directory +lazygit -p /path/to/repo # Open specific repository +lazygit status # Focus status panel on open +lazygit branch # Focus branch panel on open +lazygit log # Focus log panel on open +lazygit stash # Focus stash panel on open +``` + +### Command Line Flags + +| Flag | Description | +|------|-------------| +| `-h, --help` | Display help | +| `-v, --version` | Print version | +| `-p, --path PATH` | Path to git repo | +| `-f, --filter PATH` | Filter log by path | +| `-c, --config` | Print default config | +| `-cd, --print-config-dir` | Print config directory | +| `-ucd, --use-config-dir DIR` | Override config directory | +| `-ucf, --use-config-file FILES` | Comma-separated config files | +| `-w, --work-tree PATH` | Git work-tree argument | +| `-g, --git-dir PATH` | Git git-dir argument | +| `-sm, --screen-mode MODE` | Initial screen mode: normal, half, full | +| `-d, --debug` | Run in debug mode with logging | +| `-l, --logs` | Tail lazygit logs | +| `--profile` | Start profiler on port 6060 | + +### Examples + +```bash +# Open repo at specific path +lazygit -p ~/projects/myrepo + +# Filter commits by file path +lazygit -f src/main.js + +# Use custom config +lazygit -ucf ~/.config/lazygit/work-config.yml + +# Start in full screen mode +lazygit -sm full + +# Debug mode +lazygit -d +# In another terminal: +lazygit -l # Watch logs +``` + +--- + +## Automation with VHS + +[VHS](https://github.com/charmbracelet/vhs) can be used to programmatically control lazygit for demos, testing, and documentation. + +### VHS Tape Syntax + +```tape +# Configure output +Output "demo.gif" +Set Shell "bash" +Set FontSize 14 +Set Width 1200 +Set Height 800 + +# Launch lazygit +Type "cd /path/to/repo && lazygit" +Enter +Sleep 2s + +# Navigate with keyboard +Type "2" # Go to files panel +Sleep 500ms +Type "j" # Move down +Sleep 500ms +Space # Stage file +Sleep 500ms +Type "c" # Start commit +Sleep 1s +Type "Add new feature" +Enter +Sleep 1s + +# Capture screenshots +Screenshot "commit-complete.png" + +# Quit +Type "q" +``` + +### VHS Commands for lazygit + +| Command | Usage | Description | +|---------|-------|-------------| +| `Type "x"` | `Type "c"` | Type character (triggers keybinding) | +| `Enter` | `Enter` | Press Enter key | +| `Escape` | `Escape` | Press Escape key | +| `Space` | `Space` | Press Space key | +| `Tab` | `Tab` | Press Tab key | +| `Up/Down/Left/Right` | `Down` | Arrow keys | +| `Sleep Xs` | `Sleep 500ms` | Wait for UI | +| `Screenshot "file.png"` | `Screenshot "/tmp/shot.png"` | Capture frame | + +### Example: Automated Commit Demo + +```tape +Output "lazygit-commit-demo.gif" +Set Shell "bash" +Set Width 1200 +Set Height 800 +Set Framerate 10 + +# Setup +Type "cd /tmp/test-repo && lazygit" +Enter +Sleep 2s + +# Show modified files +Type "2" +Sleep 1s + +# Stage all changes +Type "a" +Sleep 500ms + +# Open commit dialog +Type "c" +Sleep 1s + +# Type commit message +Type "feat: add new authentication module" +Enter +Sleep 1s + +# Show result +Screenshot "commit-complete.png" +Sleep 2s + +# Quit +Type "q" +``` + +### Running VHS Tapes + +```bash +# Run tape and generate output +vhs demo.tape + +# Validate tape without running +vhs validate demo.tape + +# Record a new tape interactively +vhs record + +# Publish GIF to share +vhs publish demo.gif +``` + +--- + +## Tips and Tricks + +### Productivity Tips + +1. **Use panel numbers**: Press `1-5` to jump directly to panels +2. **Toggle views**: Press `+` to maximize the current panel +3. **Filter commits**: Use `/` to search in any list +4. **Quick stash**: Press `s` to stash all changes instantly +5. **Undo mistakes**: Press `z` to undo via reflog +6. **Copy commit hash**: Press `y` on a commit for copy options +7. **Open in browser**: Press `o` on a commit to view on GitHub/GitLab + +### Advanced Usage + +1. **Patch mode**: Use `Ctrl+p` to create partial patches from commits +2. **Custom commands**: Define frequently used git aliases +3. **Multiple configs**: Use `-ucf` for project-specific settings +4. **Filter mode**: Use `-f` to focus on specific file history + +### Keyboard Navigation Summary + +``` +┌─────────────────────────────────────────┐ +│ PANEL NAVIGATION │ +├─────────────────────────────────────────┤ +│ 1-5: Jump to panel Tab: Toggle view │ +│ h/l: Move left/right [/]: Switch tabs │ +│ j/k: Move up/down : Top/bottom │ +├─────────────────────────────────────────┤ +│ COMMON ACTIONS │ +├─────────────────────────────────────────┤ +│ Space: Primary action Enter: Go into │ +│ c: Commit P: Push p: Pull │ +│ s: Stash z: Undo ?: Help │ +│ /: Search q: Quit │ +└─────────────────────────────────────────┘ +``` + +--- + +## Comparison with Other Tools + +| Feature | lazygit | tig | gitui | git CLI | +|---------|---------|-----|-------|---------| +| TUI Interface | Yes | Yes | Yes | No | +| Staging View | Line-level | Hunk-level | Line-level | Hunk-level | +| Interactive Rebase | Visual | No | Visual | Editor | +| Merge Conflict UI | Yes | No | Yes | No | +| Customizable | YAML config | Limited | TOML config | Aliases | +| Language | Go | C | Rust | C | +| Cross-platform | Yes | Yes | Yes | Yes | + +--- + +## Resources + +- **Documentation**: https://github.com/jesseduffield/lazygit/blob/master/docs/keybindings +- **Configuration**: https://github.com/jesseduffield/lazygit/blob/v0.58.1/docs/Config.md +- **Tutorial Video**: https://youtu.be/VDXvbHZYeKY +- **Issues**: https://github.com/jesseduffield/lazygit/issues +- **Releases**: https://github.com/jesseduffield/lazygit/releases +- **Sponsor**: https://github.com/sponsors/jesseduffield + +--- + +*Document generated through programmatic exploration of lazygit v0.58.1 using VHS automation.* diff --git a/bb.edn b/bb.edn new file mode 100644 index 0000000..3b55277 --- /dev/null +++ b/bb.edn @@ -0,0 +1,10 @@ +{:paths ["src" "test"] + :deps {io.github.ajet/clojure-tui {:local/root "../clojure-tui"}} + :tasks {start {:doc "Run lazygitclj" + :task (exec 'lazygitclj.core/-main)} + test {:doc "Run unit tests" + :task (load-file "test/run-tests.clj")} + test:unit {:doc "Run unit tests" + :task (load-file "test/run-tests.clj")} + test:e2e {:doc "Run e2e VHS tests" + :task (shell "test/e2e/run-all.sh")}}} diff --git a/src/lazygitclj/core.clj b/src/lazygitclj/core.clj new file mode 100644 index 0000000..850beb6 --- /dev/null +++ b/src/lazygitclj/core.clj @@ -0,0 +1,938 @@ +(ns lazygitclj.core + "lazygitclj - A lazygit-inspired TUI for git." + (:require [tui.simple :as tui] + [tui.core :refer [quit]] + [lazygitclj.git :as git] + [clojure.string :as str])) + +;; === Model === + +(defn load-git-data [] + {:branch (git/current-branch) + :sha (git/head-sha) + :ahead-behind (git/ahead-behind) + :staged (git/staged-files) + :unstaged (git/unstaged-files) + :commits (git/recent-commits 15) + :branches (git/branches) + :remote-branches (git/remote-branches) + :tags (git/list-tags) + :stashes (git/stash-list) + :reflog (git/reflog 50) + :diff nil}) + +;; initial-model is defined after helpers/update functions (needs update-diff) + +;; === Helpers === + +(defn file-items [model] + (let [staged (mapv #(assoc % :type :staged) (:staged model)) + unstaged (mapv #(assoc % :type :unstaged) (:unstaged model))] + (vec (concat staged unstaged)))) + +(defn current-items [model] + (case (:panel model) + :files (file-items model) + :commits (if (= (:commits-tab model) :reflog) + (:reflog model) + (:commits model)) + :branches (case (:branches-tab model) + :local (:branches model) + :remotes (:remote-branches model) + :tags (:tags model) + (:branches model)) + :stash (:stashes model) + [])) + +(defn clamp-cursor [model] + (let [items (current-items model) + max-idx (max 0 (dec (count items)))] + (update model :cursor #(min max-idx (max 0 %))))) + +(defn truncate [s max-len] + (if (and s (> (count s) max-len)) + (str (subs s 0 max-len) "...") + s)) + +(defn visible-window + "Calculate the visible window of items for scrolling. + Returns {:items visible-items :start-idx start-index :total total-count} + Keeps cursor visible by scrolling the window." + [items cursor max-visible] + (let [total (count items) + max-visible (max 1 max-visible)] + (if (<= total max-visible) + ;; All items fit, no scrolling needed + {:items items :start-idx 0 :total total} + ;; Need to scroll - calculate window that keeps cursor visible + (let [;; Simple approach: cursor should be in the middle when possible + half (quot max-visible 2) + ;; Calculate start index + start-idx (cond + ;; Cursor near start - show from beginning + (<= cursor half) 0 + ;; Cursor near end - show end portion + (>= cursor (- total half)) (- total max-visible) + ;; Cursor in middle - center it + :else (- cursor half)) + start-idx (max 0 (min start-idx (- total max-visible))) + visible-items (subvec (vec items) start-idx (+ start-idx max-visible))] + {:items visible-items :start-idx start-idx :total total})))) + +(defn get-current-diff + "Get the diff for the currently selected item based on panel and cursor." + [model] + (let [panel (:panel model) + items (current-items model) + cursor (:cursor model) + item (get (vec items) cursor)] + (case panel + :files + (when item + (if (= (:type item) :staged) + (git/diff-staged-file (:path item)) + (git/diff-unstaged (:path item)))) + + :commits + (when-let [sha (:sha item)] + (git/show-commit sha)) + + :branches + (when item + (case (:branches-tab model) + :local (git/diff-branch item) + :remotes nil + :tags nil + nil)) + + :stash + (when-let [ref (:ref item)] + (git/stash-show ref)) + + nil))) + +;; === Update === + +(defn update-diff [model] + (assoc model :diff (get-current-diff model))) + +(defn initial-model [] + (let [base (merge + {:panel :files + :cursor 0 + :message nil + :input-mode nil + :input-buffer "" + :input-context nil + :menu-mode nil + :commits-tab :commits + :branches-tab :local + :reflog-index 0} + (load-git-data))] + (update-diff base))) + +(defn refresh [model] + (-> model + (merge (load-git-data)) + clamp-cursor + (assoc :message nil) + update-diff)) + +(defn update-files [model msg] + (let [items (file-items model) + cursor (:cursor model) + item (get items cursor)] + (cond + (tui/key= msg " ") + (if item + (do + (if (= (:type item) :staged) + (git/unstage-file (:path item)) + (git/stage-file (:path item))) + [(refresh model) nil]) + [model nil]) + + (tui/key= msg "a") + (if (and (seq (:staged model)) (empty? (:unstaged model))) + ;; All files are staged - unstage all + (do + (git/reset-staged) + [(refresh model) nil]) + ;; Some files are unstaged - stage all + (do + (git/stage-all) + [(refresh model) nil])) + + (tui/key= msg "d") + (if (and item (= (:type item) :unstaged) (not= (:index item) \?)) + (do + (git/discard-file (:path item)) + [(refresh model) nil]) + [(assoc model :message "Can only discard unstaged changes") nil]) + + ;; s: Quick stash all changes + (tui/key= msg "s") + (do + (git/stash-all) + [(-> model refresh (assoc :message "Stashed all changes")) nil]) + + ;; S: Stash options menu + (tui/key= msg "S") + [(assoc model :menu-mode :stash-options) nil] + + :else + [model nil]))) + +(defn update-commits [model msg] + (let [items (current-items model) + cursor (:cursor model) + item (get (vec items) cursor) + sha (when item (:sha item))] + (cond + ;; Space: Checkout commit/reflog entry + (tui/key= msg " ") + (if sha + (do + (git/checkout-reflog-entry sha) + [(-> model refresh (assoc :message (str "Checked out " sha))) nil]) + [model nil]) + + ;; g: Reset to this commit + (tui/key= msg "g") + (if sha + (do + (git/reset-to-reflog sha) + [(-> model refresh (assoc :message (str "Reset to " sha))) nil]) + [model nil]) + + ;; C: Cherry-pick commit + (tui/key= msg "C") + (if sha + (do + (git/cherry-pick-commit sha) + [(-> model refresh (assoc :message (str "Cherry-picked " sha))) nil]) + [model nil]) + + ;; t: Revert commit + (tui/key= msg "t") + (if sha + (do + (git/revert-commit sha) + [(-> model refresh (assoc :message (str "Reverted " sha))) nil]) + [model nil]) + + ;; r: Reword commit (HEAD only) + (tui/key= msg "r") + (if sha + [(assoc model :input-mode :reword :input-buffer "" :input-context sha) nil] + [model nil]) + + ;; y: Copy SHA + (tui/key= msg "y") + (if sha + [(assoc model :message (str "SHA: " sha " (not copied - no clipboard support)")) nil] + [model nil]) + + :else + [model nil]))) + +(defn update-branches [model msg] + (let [items (current-items model) + cursor (:cursor model) + item (get (vec items) cursor) + tab (:branches-tab model)] + (cond + ;; Enter: checkout branch/tag + (tui/key= msg :enter) + (cond + (and (= tab :local) item (not= item (:branch model))) + (do + (git/checkout-branch item) + [(-> model refresh (assoc :message (str "Checked out " item))) nil]) + + (and (= tab :tags) item) + (do + (git/checkout-tag item) + [(-> model refresh (assoc :message (str "Checked out tag " item))) nil]) + + :else [model nil]) + + ;; n: new branch (local tab only) + (and (tui/key= msg "n") (= tab :local)) + [(assoc model :input-mode :new-branch :input-buffer "") nil] + + ;; d: delete branch (local tab only) + (and (tui/key= msg "d") (= tab :local) item (not= item (:branch model))) + (do + (git/delete-branch item) + [(-> model refresh (assoc :message (str "Deleted branch " item))) nil]) + + ;; R: rename branch (local tab only) + (and (tui/key= msg "R") (= tab :local) item) + [(assoc model :input-mode :rename-branch :input-buffer "" :input-context item) nil] + + ;; M: merge branch into current + (and (tui/key= msg "M") (= tab :local) item (not= item (:branch model))) + (do + (git/merge-branch item) + [(-> model refresh (assoc :message (str "Merged " item))) nil]) + + ;; f: fast-forward branch + (and (tui/key= msg "f") (= tab :local) item) + (do + (git/fast-forward-branch item) + [(-> model refresh (assoc :message (str "Fast-forwarded " item))) nil]) + + ;; Tab switching with [ and ] + (tui/key= msg "[") + [(-> model + (update :branches-tab #(case % :local :tags :remotes :local :tags :remotes)) + (assoc :cursor 0) + clamp-cursor) nil] + + (tui/key= msg "]") + [(-> model + (update :branches-tab #(case % :local :remotes :remotes :tags :tags :local)) + (assoc :cursor 0) + clamp-cursor) nil] + + :else + [model nil]))) + +(defn update-stash [model msg] + (let [stashes (:stashes model) + cursor (:cursor model) + stash (get (vec stashes) cursor) + ref (when stash (:ref stash))] + (cond + ;; Space: apply stash (keep in list) + (tui/key= msg " ") + (if ref + (do + (git/stash-apply ref) + [(-> model refresh (assoc :message (str "Applied " ref))) nil]) + [model nil]) + + ;; g: pop stash (apply and remove) + (tui/key= msg "g") + (if ref + (do + (git/stash-pop ref) + [(-> model refresh (assoc :message (str "Popped " ref))) nil]) + [model nil]) + + ;; d: drop stash + (tui/key= msg "d") + (if ref + (do + (git/stash-drop ref) + [(-> model refresh (assoc :message (str "Dropped " ref))) nil]) + [model nil]) + + ;; n: new branch from stash + (and (tui/key= msg "n") ref) + [(assoc model :input-mode :stash-branch :input-buffer "" :input-context ref) nil] + + :else + [model nil]))) + +(defn update-input-mode [model msg] + (cond + (tui/key= msg :escape) + [(assoc model :input-mode nil :input-buffer "" :input-context nil) nil] + + (tui/key= msg :enter) + (let [buf (:input-buffer model) + ctx (:input-context model)] + (case (:input-mode model) + :commit + (if (str/blank? buf) + [(assoc model :message "Commit message cannot be empty") nil] + (do + (git/commit buf) + [(-> model + (assoc :input-mode nil :input-buffer "" :input-context nil) + refresh + (assoc :message "Committed!")) nil])) + + :new-branch + (if (str/blank? buf) + [(assoc model :message "Branch name cannot be empty") nil] + (do + (git/create-branch buf) + [(-> model + (assoc :input-mode nil :input-buffer "" :input-context nil) + refresh + (assoc :message (str "Created branch " buf))) nil])) + + :rename-branch + (if (str/blank? buf) + [(assoc model :message "New name cannot be empty") nil] + (do + (git/rename-branch ctx buf) + [(-> model + (assoc :input-mode nil :input-buffer "" :input-context nil) + refresh + (assoc :message (str "Renamed " ctx " to " buf))) nil])) + + :stash-branch + (if (str/blank? buf) + [(assoc model :message "Branch name cannot be empty") nil] + (do + (git/stash-branch buf ctx) + [(-> model + (assoc :input-mode nil :input-buffer "" :input-context nil) + refresh + (assoc :message (str "Created branch " buf " from stash"))) nil])) + + :reword + (if (str/blank? buf) + [(assoc model :message "Message cannot be empty") nil] + (if (git/reword-commit ctx buf) + [(-> model + (assoc :input-mode nil :input-buffer "" :input-context nil) + refresh + (assoc :message "Rewrote commit message")) nil] + [(assoc model :input-mode nil :input-buffer "" :input-context nil + :message "Can only reword HEAD commit") nil])) + + [model nil])) + + (tui/key= msg :backspace) + [(update model :input-buffer #(if (empty? %) % (subs % 0 (dec (count %))))) nil] + + ;; Character input - key format is [:key {:char \a}] + (and (= (first msg) :key) + (map? (second msg)) + (:char (second msg)) + (not (:ctrl (second msg))) + (not (:alt (second msg)))) + [(update model :input-buffer str (:char (second msg))) nil] + + :else + [model nil])) + +(defn update-stash-menu [model msg] + (cond + (tui/key= msg :escape) + [(assoc model :menu-mode nil) nil] + + ;; a: Stash all changes + (tui/key= msg "a") + (do + (git/stash-all) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Stashed all changes")) nil]) + + ;; i: Stash all changes and keep index + (tui/key= msg "i") + (do + (git/stash-keep-index) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Stashed all changes (kept index)")) nil]) + + ;; U: Stash all including untracked files + (tui/key= msg "U") + (do + (git/stash-include-untracked) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Stashed all changes (including untracked)")) nil]) + + ;; s: Stash staged changes only + (tui/key= msg "s") + (do + (git/stash-staged) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Stashed staged changes only")) nil]) + + ;; u: Stash unstaged changes only + (tui/key= msg "u") + (do + (git/stash-unstaged) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Stashed unstaged changes only")) nil]) + + :else + [model nil])) + +(defn update-reset-menu [model msg] + (cond + (tui/key= msg :escape) + [(assoc model :menu-mode nil) nil] + + ;; s: Soft reset (keep staged) + (tui/key= msg "s") + (do + (git/reset-soft) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Soft reset to HEAD~1")) nil]) + + ;; m: Mixed reset (unstage) + (tui/key= msg "m") + (do + (git/reset-mixed) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Mixed reset to HEAD~1")) nil]) + + ;; h: Hard reset (discard all) + (tui/key= msg "h") + (do + (git/reset-hard) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Hard reset to HEAD~1")) nil]) + + ;; u: Unstage all + (tui/key= msg "u") + (do + (git/reset-staged) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Unstaged all changes")) nil]) + + ;; d: Discard unstaged changes + (tui/key= msg "d") + (do + (git/discard-all-unstaged) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Discarded unstaged changes")) nil]) + + ;; c: Clean untracked files + (tui/key= msg "c") + (do + (git/clean-untracked) + [(-> model (assoc :menu-mode nil) refresh (assoc :message "Cleaned untracked files")) nil]) + + :else + [model nil])) + +(defn update-help [model msg] + (cond + (or (tui/key= msg :escape) (tui/key= msg "?") (tui/key= msg "q")) + [(assoc model :menu-mode nil) nil] + + :else + [model nil])) + +(defn update-model [model msg] + (cond + ;; Menu modes take priority + (= (:menu-mode model) :stash-options) + (update-stash-menu model msg) + + (= (:menu-mode model) :reset-options) + (update-reset-menu model msg) + + (= (:menu-mode model) :help) + (update-help model msg) + + (:input-mode model) + (update-input-mode model msg) + + (or (tui/key= msg "q") (tui/key= msg [:ctrl \c])) + [model quit] + + (tui/key= msg "r") + [(refresh model) nil] + + ;; Help panel + (tui/key= msg "?") + [(assoc model :menu-mode :help) nil] + + ;; Reset options menu + (tui/key= msg "D") + [(assoc model :menu-mode :reset-options) nil] + + ;; Panel jump keys (matching lazygit: 2=Files, 3=Branches, 4=Commits, 5=Stash) + (tui/key= msg "2") + [(-> model (assoc :panel :files :cursor 0) clamp-cursor update-diff) nil] + + (tui/key= msg "3") + [(-> model (assoc :panel :branches :cursor 0) clamp-cursor update-diff) nil] + + (tui/key= msg "4") + [(-> model (assoc :panel :commits :cursor 0) clamp-cursor update-diff) nil] + + (tui/key= msg "5") + [(-> model (assoc :panel :stash :cursor 0) clamp-cursor update-diff) nil] + + ;; h/l or Left/Right: move between panels (order: files → branches → commits → stash) + (or (tui/key= msg "h") (tui/key= msg :left)) + [(-> model + (update :panel #(case % :files :stash :branches :files :commits :branches :stash :commits)) + (assoc :cursor 0) + clamp-cursor + update-diff) nil] + + (or (tui/key= msg "l") (tui/key= msg :right)) + [(-> model + (update :panel #(case % :files :branches :branches :commits :commits :stash :stash :files)) + (assoc :cursor 0) + clamp-cursor + update-diff) nil] + + (or (tui/key= msg :up) (tui/key= msg "k")) + [(-> model (update :cursor dec) clamp-cursor update-diff) nil] + + (or (tui/key= msg :down) (tui/key= msg "j")) + [(-> model (update :cursor inc) clamp-cursor update-diff) nil] + + (and (tui/key= msg "c") (= (:panel model) :files)) + (if (empty? (:staged model)) + [(assoc model :message "Nothing staged to commit") nil] + [(assoc model :input-mode :commit :input-buffer "") nil]) + + (tui/key= msg "P") + (do + (git/push) + [(assoc model :message "Pushed!") nil]) + + (tui/key= msg "p") + (do + (git/pull) + [(-> model refresh (assoc :message "Pulled!")) nil]) + + ;; Tab switching with [ and ] (for commits panel) + (and (tui/key= msg "[") (= (:panel model) :commits)) + [(-> model + (update :commits-tab #(if (= % :reflog) :commits :reflog)) + (assoc :cursor 0) + clamp-cursor) nil] + + (and (tui/key= msg "]") (= (:panel model) :commits)) + [(-> model + (update :commits-tab #(if (= % :commits) :reflog :commits)) + (assoc :cursor 0) + clamp-cursor) nil] + + ;; Global undo (z): Reset to previous reflog entry + (tui/key= msg "z") + (let [reflog (:reflog model) + current-idx (or (:reflog-index model) 0) + next-idx (inc current-idx)] + (if (< next-idx (count reflog)) + (let [entry (get (vec reflog) next-idx)] + (git/reset-to-reflog (:ref entry)) + [(-> model + refresh + (assoc :reflog-index next-idx) + (assoc :message (str "Undo: reset to " (:ref entry)))) nil]) + [(assoc model :message "Nothing to undo") nil])) + + ;; Global redo (Z): Reset forward in reflog + (tui/key= msg "Z") + (let [current-idx (or (:reflog-index model) 0)] + (if (> current-idx 0) + (let [prev-idx (dec current-idx) + reflog (:reflog model) + entry (get (vec reflog) prev-idx)] + (git/reset-to-reflog (:ref entry)) + [(-> model + refresh + (assoc :reflog-index prev-idx) + (assoc :message (str "Redo: reset to " (:ref entry)))) nil]) + [(assoc model :message "Nothing to redo") nil])) + + :else + (case (:panel model) + :files (update-files model msg) + :commits (update-commits model msg) + :branches (update-branches model msg) + :stash (update-stash model msg) + [model nil]))) + +;; === Views === + +(defn file-status-char [{:keys [index worktree]}] + (str index worktree)) + +;; Panel 1: Status +(defn status-panel [{:keys [branch sha ahead-behind panel]}] + (let [[ahead behind] ahead-behind + sync-info (when (and ahead behind (or (pos? ahead) (pos? behind))) + (str "↑" ahead "↓" behind))] + [:box {:border (if (= panel :status) :double :single) + :title "1 Status" :padding [0 1] :width :fill :height :fill} + (into [:row {:gap 1}] + (remove nil? + [[:text {:fg :magenta :bold true} (truncate (or branch "?") 12)] + [:text "→"] + [:text {:fg :yellow} (or sha "?")] + (when sync-info [:text {:fg :cyan} sync-info])]))])) + +;; Panel 2: Files +(defn files-panel [{:keys [staged unstaged cursor panel]} max-visible] + (let [active? (= panel :files) + all-files (into (mapv #(assoc % :section :staged) staged) + (mapv #(assoc % :section :unstaged) unstaged)) + {:keys [items start-idx total]} (visible-window all-files (if active? cursor 0) max-visible)] + [:box {:border (if active? :double :single) + :title (str "2 Files (" total ")") + :padding [0 1] :width :fill :height :fill} + (if (empty? all-files) + [:text {:fg :gray} "No changes"] + (into [:col] + (for [[local-idx file] (map-indexed vector items)] + (let [global-idx (+ start-idx local-idx) + is-cursor (and active? (= global-idx cursor)) + color (if (= (:section file) :staged) :green :red)] + [:row {:gap 1} + [:text {:fg color} (file-status-char file)] + [:text {:fg (if is-cursor :cyan color) :bold is-cursor :inverse is-cursor} + (truncate (:path file) 20)]]))))])) + +;; Panel 3: Branches +(defn branches-panel [{:keys [branches remote-branches tags branch branches-tab cursor panel]} max-visible] + (let [active? (= panel :branches) + all-items (case branches-tab :local branches :remotes remote-branches :tags tags branches) + {:keys [items start-idx total]} (visible-window all-items (if active? cursor 0) max-visible) + tab-str (case branches-tab :local "[L] R T" :remotes "L [R] T" :tags "L R [T]")] + [:box {:border (if active? :double :single) + :title (str "3 Branches " tab-str) + :padding [0 1] :width :fill :height :fill} + (if (empty? all-items) + [:text {:fg :gray} (str "No " (name branches-tab))] + (into [:col] + (for [[local-idx item] (map-indexed vector items)] + (let [global-idx (+ start-idx local-idx) + is-cursor (and active? (= global-idx cursor)) + is-current (and (= branches-tab :local) (= item branch)) + fg (cond is-current :green is-cursor :cyan :else :white)] + [:text {:fg fg :bold (or is-current is-cursor) :inverse is-cursor} + (str (if is-current "* " " ") (truncate item 22))]))))])) + +;; Panel 4: Commits +(defn commits-panel [{:keys [commits reflog commits-tab cursor panel]} max-visible] + (let [active? (= panel :commits) + reflog? (= commits-tab :reflog) + all-items (if reflog? reflog commits) + {:keys [items start-idx total]} (visible-window all-items (if active? cursor 0) max-visible)] + [:box {:border (if active? :double :single) + :title (str "4 Commits " (if reflog? "C [R]" "[C] R")) + :padding [0 1] :width :fill :height :fill} + (if (empty? all-items) + [:text {:fg :gray} "No commits"] + (into [:col] + (for [[local-idx {:keys [sha action subject]}] (map-indexed vector items)] + (let [global-idx (+ start-idx local-idx) + is-cursor (and active? (= global-idx cursor))] + [:row {:gap 1} + [:text {:fg :yellow} (or sha "?")] + [:text {:fg (if is-cursor :cyan :white) :bold is-cursor :inverse is-cursor} + (truncate (if reflog? (str action ": " subject) (or subject "")) 14)]]))))])) + +;; Panel 5: Stash +(defn stash-panel [{:keys [stashes cursor panel]} max-visible] + (let [active? (= panel :stash) + {:keys [items start-idx total]} (visible-window stashes (if active? cursor 0) max-visible)] + [:box {:border (if active? :double :single) + :title (str "5 Stash (" total ")") + :padding [0 1] :width :fill :height :fill} + (if (empty? stashes) + [:text {:fg :gray} "No stashes"] + (into [:col] + (for [[local-idx {:keys [index message]}] (map-indexed vector items)] + (let [global-idx (+ start-idx local-idx) + is-cursor (and active? (= global-idx cursor))] + [:row {:gap 1} + [:text {:fg :yellow} (str (or index global-idx))] + [:text {:fg (if is-cursor :cyan :white) :bold is-cursor :inverse is-cursor} + (truncate (or message "") 20)]]))))])) + +;; Panel 0: Main View (Diff) +(defn main-view-panel [{:keys [diff]}] + (let [lines (when diff (str/split-lines diff))] + [:box {:border :single :title "0 Main" :padding [0 1] :width :fill :height :fill} + (if (empty? lines) + [:text {:fg :gray} "Select an item to view diff"] + [:col + (for [line lines] + [:text {:fg (cond + (str/starts-with? line "+") :green + (str/starts-with? line "-") :red + (str/starts-with? line "@@") :cyan + (or (str/starts-with? line "diff") + (str/starts-with? line "commit")) :yellow + :else :white)} + line])])])) + +;; Command Log (placeholder) +(defn command-log-panel [] + [:box {:border :single :title "Command Log" :padding [0 1] :width :fill :height :fill} + [:text {:fg :gray} ""]]) + +;; Bottom help bar +(defn help-bar [model] + (let [panel (:panel model) + panel-help (case panel + :files "spc:stage a:all c:commit" + :commits "[]:tabs spc:checkout" + :branches "[]:tabs n:new d:del" + :stash "spc:apply g:pop d:drop" + "")] + (into [:row {:gap 1}] + (remove nil? + [[:text {:fg :gray} "q:quit"] + [:text {:fg :gray} "?:help"] + [:text {:fg :gray} "h/l:panels"] + [:text {:fg :gray} "j/k:nav"] + (when (seq panel-help) + [:text {:fg :gray} panel-help]) + [:text {:fg :gray} "p/P:pull/push"]])))) + +(defn stash-menu-view [{:keys [menu-mode]}] + (when (= menu-mode :stash-options) + [:box {:border :double :title "Stash Options" :padding [0 1]} + [:col + [:text {:fg :cyan} "a - Stash all changes"] + [:text {:fg :cyan} "i - Stash all changes and keep index"] + [:text {:fg :cyan} "U - Stash all including untracked files"] + [:text {:fg :yellow} "s - Stash staged changes only"] + [:text {:fg :yellow} "u - Stash unstaged changes only"] + [:text ""] + [:text {:fg :gray} "esc - Cancel"]]])) + +(defn reset-menu-view [{:keys [menu-mode]}] + (when (= menu-mode :reset-options) + [:box {:border :double :title "Reset Options" :padding [0 1]} + [:col + [:text {:fg :yellow} "s - Soft reset (uncommit, keep staged)"] + [:text {:fg :yellow} "m - Mixed reset (uncommit, unstage)"] + [:text {:fg :red} "h - Hard reset (discard all changes)"] + [:text ""] + [:text {:fg :cyan} "u - Unstage all staged changes"] + [:text {:fg :cyan} "d - Discard all unstaged changes"] + [:text {:fg :red} "c - Clean untracked files"] + [:text ""] + [:text {:fg :gray} "esc - Cancel"]]])) + +(defn help-view [{:keys [menu-mode]}] + (when (= menu-mode :help) + [:box {:border :double :title "Help - Keybindings" :padding [0 1]} + [:col + [:text {:fg :cyan :bold true} "Global:"] + [:text " q - Quit r - Refresh"] + [:text " h/l - Prev/Next panel 2-5 - Jump to panel"] + [:text " j/k - Move down/up z/Z - Undo/Redo"] + [:text " p - Pull P - Push"] + [:text " ? - Help D - Reset options"] + [:text ""] + [:text {:fg :green :bold true} "Files (2):"] + [:text " space - Stage/unstage a - Stage all"] + [:text " c - Commit d - Discard file"] + [:text " s - Quick stash S - Stash options"] + [:text ""] + [:text {:fg :yellow :bold true} "Branches (3):"] + [:text " [/] - Switch tabs enter - Checkout"] + [:text " n - New branch d - Delete branch"] + [:text " R - Rename M - Merge"] + [:text " f - Fast-forward"] + [:text ""] + [:text {:fg :magenta :bold true} "Commits (4):"] + [:text " [/] - Switch tabs space - Checkout"] + [:text " g - Reset to C - Cherry-pick"] + [:text " t - Revert r - Reword (HEAD only)"] + [:text " y - Show SHA"] + [:text ""] + [:text {:fg :blue :bold true} "Stash (5):"] + [:text " space - Apply g - Pop (apply+drop)"] + [:text " d - Drop n - Branch from stash"] + [:text ""] + [:text {:fg :gray} "Press ?, q, or esc to close"]]])) + +(defn input-view [{:keys [input-mode input-buffer input-context]}] + (when input-mode + (let [title (case input-mode + :commit "Commit Message" + :new-branch "New Branch Name" + :rename-branch (str "Rename " input-context " to") + :stash-branch "Branch Name from Stash" + :reword "Reword Commit Message" + (name input-mode))] + [:box {:border :rounded :title title :padding [0 1] :width 50} + [:input {:value input-buffer}]]))) + +(defn message-view [{:keys [message]}] + (when message + [:text {:fg :yellow :bold true} (str " " message)])) + +(defn main-grid-view + "Render the main lazygit-style grid layout." + [model width height] + (let [has-message? (some? (:message model)) + narrow? (< width 70) + ;; Calculate available height for panels + ;; Wide layout: left column has [3 :flex :flex :flex :flex] + ;; So 4 flex panels share (height - status(3) - help-bar(1) - message?) + ;; Each panel total height = remaining / 4 + ;; Inner height = panel total - 2 (borders) + remaining-height (- height 3 1 (if has-message? 1 0)) + panel-total-height (quot remaining-height 4) + ;; Inner height is total minus borders (2 rows) + panel-inner-height (if narrow? + ;; Narrow: 6 sections share height + (max 1 (- (quot remaining-height 6) 2)) + ;; Wide: 4 panels share remaining height + (max 1 (- panel-total-height 2))) + content (if narrow? + ;; NARROW: Single column stacked + [:col {:heights [3 :flex :flex :flex 3 :flex 4]} + (status-panel model) + (files-panel model panel-inner-height) + (branches-panel model panel-inner-height) + (commits-panel model panel-inner-height) + (stash-panel model panel-inner-height) + (main-view-panel model) + (command-log-panel)] + ;; WIDE: Two columns + [:row {:gap 1 :widths [30 :flex]} + [:col {:heights [3 :flex :flex :flex :flex]} + (status-panel model) + (files-panel model panel-inner-height) + (branches-panel model panel-inner-height) + (commits-panel model panel-inner-height) + (stash-panel model panel-inner-height)] + [:col {:heights [:flex 4]} + (main-view-panel model) + (command-log-panel)]])] + (if has-message? + [:col {:width width :height height :heights [1 :flex 1]} + (message-view model) + content + (help-bar model)] + [:col {:width width :height height :heights [:flex 1]} + content + (help-bar model)]))) + +(defn view [model {:keys [width height] :or {width 120 height 30}}] + (let [background (main-grid-view model width height)] + (cond + ;; Help menu modal overlay + (= (:menu-mode model) :help) + [:modal {} + background + (help-view model)] + + ;; Stash options menu modal overlay + (= (:menu-mode model) :stash-options) + [:modal {} + background + (stash-menu-view model)] + + ;; Reset options menu modal overlay + (= (:menu-mode model) :reset-options) + [:modal {} + background + (reset-menu-view model)] + + ;; Input mode modal overlay (commit message, etc.) + (:input-mode model) + [:modal {} + background + (input-view model)] + + ;; Default grid view + :else + background))) + +;; === Main === + +(defn -main [& _args] + (if (git/repo-root) + (do + (println "Starting lazygitclj...") + (tui/run {:init (initial-model) + :update update-model + :view view}) + (println "Goodbye!")) + (do + (println "Error: Not a git repository") + (System/exit 1)))) diff --git a/src/lazygitclj/git.clj b/src/lazygitclj/git.clj new file mode 100644 index 0000000..cc3be4d --- /dev/null +++ b/src/lazygitclj/git.clj @@ -0,0 +1,428 @@ +(ns lazygitclj.git + "Git operations via shell commands." + (:require [babashka.process :refer [shell]] + [clojure.string :as str])) + +(defn- sh + "Run shell command, return stdout or nil on error." + [& args] + (try + (-> (apply shell {:out :string :err :string} args) + :out + str/trim-newline) + (catch Exception _ nil))) + +(defn- lines [s] + (if (str/blank? s) [] (str/split-lines s))) + +;; === Status === + +(defn current-branch [] + (sh "git" "branch" "--show-current")) + +(defn head-sha [] + (sh "git" "rev-parse" "--short" "HEAD")) + +(defn repo-root [] + (sh "git" "rev-parse" "--show-toplevel")) + +(defn ahead-behind + "Returns [ahead behind] commit counts relative to upstream." + [] + (when-let [out (sh "git" "rev-list" "--left-right" "--count" "HEAD...@{upstream}")] + (let [[ahead behind] (str/split out #"\t")] + [(parse-long ahead) (parse-long behind)]))) + +;; === Files === + +(defn- parse-status-line [line] + (when (>= (count line) 3) + (let [index (nth line 0) + worktree (nth line 1) + path (subs line 3)] + {:index index + :worktree worktree + :path path}))) + +(defn status-files + "Returns list of files with their status." + [] + (->> (sh "git" "status" "--porcelain") + lines + (map parse-status-line) + (remove nil?))) + +(defn staged-files [] + (->> (status-files) + (filter #(not= (:index %) \space)) + (filter #(not= (:index %) \?)))) + +(defn unstaged-files [] + (->> (status-files) + (filter #(or (not= (:worktree %) \space) + (= (:index %) \?))))) + +(defn untracked-files [] + (->> (status-files) + (filter #(= (:index %) \?)))) + +;; === Commits === + +(defn- parse-log-line [line] + (let [[sha date author subject] (str/split line #"\|" 4)] + {:sha sha + :date date + :author author + :subject subject})) + +(defn recent-commits + "Returns recent commits." + ([] (recent-commits 20)) + ([n] + (->> (sh "git" "log" (str "-" n) "--pretty=format:%h|%cr|%an|%s") + lines + (map parse-log-line)))) + +;; === Branches === + +(defn branches + "Returns list of local branches." + [] + (->> (sh "git" "branch" "--format=%(refname:short)") + lines)) + +(defn remote-branches [] + (->> (sh "git" "branch" "-r" "--format=%(refname:short)") + lines)) + +;; === Actions === + +(defn stage-file [path] + (sh "git" "add" path)) + +(defn unstage-file [path] + (sh "git" "reset" "HEAD" path)) + +(defn stage-all [] + (sh "git" "add" "-A")) + +(defn checkout-branch [branch] + (sh "git" "checkout" branch)) + +(defn create-branch [name] + (sh "git" "checkout" "-b" name)) + +(defn commit [message] + (sh "git" "commit" "-m" message)) + +(defn discard-file [path] + (sh "git" "checkout" "--" path)) + +(defn diff-file [path] + (sh "git" "diff" path)) + +(defn diff-staged [path] + (sh "git" "diff" "--cached" path)) + +(defn pull [] + (sh "git" "pull")) + +(defn push [] + (sh "git" "push")) + +;; === Diffs === + +(defn diff-unstaged + "Show unstaged changes for a file, or all if no path given." + ([] (sh "git" "diff")) + ([path] (sh "git" "diff" "--" path))) + +(defn diff-staged-file + "Show staged changes for a file, or all if no path given." + ([] (sh "git" "diff" "--cached")) + ([path] (sh "git" "diff" "--cached" "--" path))) + +(defn show-commit + "Show commit details and diff." + [sha] + (sh "git" "show" "--stat" "--patch" sha)) + +(defn diff-branch + "Show diff between current branch and another branch." + [branch] + (sh "git" "diff" (str branch "...HEAD") "--stat")) + +;; === Reset Operations === + +(defn discard-all-unstaged + "Discard all unstaged changes (git checkout -- .)." + [] + (sh "git" "checkout" "--" ".")) + +(defn clean-untracked + "Remove untracked files (git clean -fd)." + [] + (sh "git" "clean" "-fd")) + +(defn reset-staged + "Unstage all staged changes (git reset HEAD)." + [] + (sh "git" "reset" "HEAD")) + +(defn reset-soft + "Soft reset to previous commit (git reset --soft HEAD~1)." + [] + (sh "git" "reset" "--soft" "HEAD~1")) + +(defn reset-mixed + "Mixed reset to previous commit (git reset --mixed HEAD~1)." + [] + (sh "git" "reset" "--mixed" "HEAD~1")) + +(defn reset-hard + "Hard reset to previous commit (git reset --hard HEAD~1)." + [] + (sh "git" "reset" "--hard" "HEAD~1")) + +;; === Commit Operations === + +(defn get-full-sha + "Get the full SHA for a short SHA." + [short-sha] + (sh "git" "rev-parse" short-sha)) + +(defn revert-commit + "Create a revert commit for the given SHA. + Uses --no-edit to avoid interactive prompts." + [sha] + (sh "git" "revert" "--no-edit" sha)) + +(defn cherry-pick-commit + "Cherry-pick the given commit SHA onto the current branch." + [sha] + (sh "git" "cherry-pick" sha)) + +(defn reword-commit + "Reword the commit message for a given SHA. + Note: This only works for the HEAD commit using --amend. + For non-HEAD commits, interactive rebase is required which + cannot be automated non-interactively. Returns success only for HEAD." + [sha new-message] + (let [head-sha (sh "git" "rev-parse" "--short" "HEAD")] + (if (= sha head-sha) + ;; Can only reword HEAD commit non-interactively + (sh "git" "commit" "--amend" "-m" new-message) + ;; For non-HEAD commits, we'd need interactive rebase + ;; which isn't practical in a TUI context + nil))) + +;; === Stash === + +(defn- parse-stash-line [line] + (when-let [[_ index branch message] (re-matches #"stash@\{(\d+)\}: (On [^:]+|WIP on [^:]+): (.+)" line)] + {:index (parse-long index) + :ref (str "stash@{" index "}") + :branch (str/replace branch #"^(On |WIP on )" "") + :message message})) + +(defn stash-list + "Returns list of stash entries." + [] + (->> (sh "git" "stash" "list") + lines + (map parse-stash-line) + (remove nil?))) + +(defn stash-push + "Stash all changes with optional message." + ([] (sh "git" "stash" "push")) + ([message] (sh "git" "stash" "push" "-m" message))) + +(defn stash-pop + "Apply stash and remove it from stash list." + ([] (sh "git" "stash" "pop")) + ([stash-ref] (sh "git" "stash" "pop" stash-ref))) + +(defn stash-apply + "Apply stash but keep it in stash list." + ([] (sh "git" "stash" "apply")) + ([stash-ref] (sh "git" "stash" "apply" stash-ref))) + +(defn stash-drop + "Remove a stash entry from stash list." + ([] (sh "git" "stash" "drop")) + ([stash-ref] (sh "git" "stash" "drop" stash-ref))) + +(defn stash-show + "Show stash diff." + ([] (sh "git" "stash" "show" "-p")) + ([stash-ref] (sh "git" "stash" "show" "-p" stash-ref))) + +(defn stash-branch + "Create a new branch from a stash entry." + ([branch-name] (sh "git" "stash" "branch" branch-name)) + ([branch-name stash-ref] (sh "git" "stash" "branch" branch-name stash-ref))) + +(defn stash-all + "Stash all changes (git stash push). Alias for stash-push." + [] + (sh "git" "stash" "push")) + +(defn stash-keep-index + "Stash all changes but keep staged changes in the index (git stash push --keep-index)." + [] + (sh "git" "stash" "push" "--keep-index")) + +(defn stash-include-untracked + "Stash all changes including untracked files (git stash push --include-untracked)." + [] + (sh "git" "stash" "push" "--include-untracked")) + +(defn stash-staged + "Stash only staged changes (git stash push --staged). Requires git 2.35+." + [] + (sh "git" "stash" "push" "--staged")) + +(defn stash-unstaged + "Stash only unstaged changes. + Uses double-stash technique: stash with --keep-index (stashes all, keeps staged in worktree), + then we have only staged changes left. Stash those temporarily, apply the first stash + to restore all changes, drop the staged stash. Finally stash with --keep-index again + to get only unstaged in stash." + [] + ;; Simpler approach: git stash push --keep-index stashes everything but keeps staged in worktree + ;; The resulting stash contains unstaged changes. But wait - that's not quite right either. + ;; + ;; Actually --keep-index: stashes both staged AND unstaged, but leaves staged in worktree. + ;; So the stash has ALL changes, not just unstaged. + ;; + ;; Correct approach for "stash unstaged only": + ;; 1. Stash all with --keep-index (stash has all, worktree has staged) + ;; 2. Stash again (stash has staged from worktree) + ;; 3. Pop stash@{1} (restore all changes to worktree) + ;; 4. Stash with --keep-index (now stash has all, worktree has staged) + ;; 5. Drop stash@{1} (the staged-only stash we don't need) + ;; Result: stash@{0} has all changes (not what we want) + ;; + ;; Different approach - stage everything first, then use --staged: + ;; No, that defeats the purpose. + ;; + ;; Best approach: commit staged, stash unstaged, reset soft + ;; 1. Commit staged changes with temp message + ;; 2. Stash remaining (unstaged) changes + ;; 3. Reset --soft HEAD~1 to uncommit but keep staged + (let [has-staged (not (str/blank? (sh "git" "diff" "--cached" "--stat")))] + (if has-staged + (do + ;; Commit staged temporarily + (sh "git" "commit" "-m" "__lazygitclj_temp_commit__") + ;; Stash unstaged changes + (sh "git" "stash" "push") + ;; Reset soft to restore staged (uncommit) + (sh "git" "reset" "--soft" "HEAD~1")) + ;; No staged changes, just stash everything + (sh "git" "stash" "push")))) + +;; === Branch Operations === + +(defn delete-branch + "Delete a local branch. Returns nil if branch cannot be deleted (e.g., checked out)." + [branch] + (sh "git" "branch" "-d" branch)) + +(defn delete-branch-force + "Force delete a local branch." + [branch] + (sh "git" "branch" "-D" branch)) + +(defn rename-branch + "Rename a branch." + [old-name new-name] + (sh "git" "branch" "-m" old-name new-name)) + +(defn merge-branch + "Merge a branch into the current branch." + [branch] + (sh "git" "merge" branch)) + +(defn can-fast-forward? + "Check if branch can be fast-forwarded to its upstream. + Returns true if branch is behind upstream and can be fast-forwarded." + [branch] + (let [upstream (sh "git" "rev-parse" "--abbrev-ref" (str branch "@{upstream}")) + ;; Get merge-base between branch and upstream + merge-base (when upstream + (sh "git" "merge-base" branch upstream)) + ;; Get the commit SHA of the branch + branch-sha (sh "git" "rev-parse" branch)] + ;; Can fast-forward if branch is at the merge-base (i.e., upstream is ahead) + (and merge-base branch-sha (= merge-base branch-sha)))) + +(defn fast-forward-branch + "Fast-forward a branch to its upstream. Works for non-current branches too." + [branch] + (let [current (current-branch)] + (if (= branch current) + ;; If on the branch, use pull --ff-only + (sh "git" "pull" "--ff-only") + ;; If not on the branch, fetch and update ref + (let [upstream (sh "git" "rev-parse" "--abbrev-ref" (str branch "@{upstream}"))] + (when upstream + (sh "git" "fetch" "origin" (str branch ":" branch))))))) + +;; === Reflog Operations === + +(defn- parse-reflog-line [line] + (when-let [[_ sha ref-selector action subject] (re-matches #"([a-f0-9]+) (HEAD@\{\d+\}): ([^:]+): ?(.*)" line)] + {:sha sha + :ref ref-selector + :action action + :subject (if (str/blank? subject) action subject)})) + +(defn reflog + "Returns reflog entries." + ([] (reflog 50)) + ([n] + (->> (sh "git" "reflog" "-n" (str n)) + lines + (map parse-reflog-line) + (remove nil?)))) + +(defn checkout-reflog-entry + "Checkout a specific reflog entry by its SHA." + [sha] + (sh "git" "checkout" sha)) + +(defn reset-to-reflog + "Reset to a specific reflog entry (git reset --hard )." + [ref] + (sh "git" "reset" "--hard" ref)) + +;; === Tags === + +(defn list-tags + "Returns list of tags." + [] + (->> (sh "git" "tag" "--sort=-creatordate") + lines)) + +(defn create-tag + "Create a new tag." + ([name] (sh "git" "tag" name)) + ([name message] (sh "git" "tag" "-a" name "-m" message))) + +(defn delete-tag + "Delete a tag locally." + [name] + (sh "git" "tag" "-d" name)) + +(defn push-tag + "Push a tag to remote." + ([name] (push-tag name "origin")) + ([name remote] + (sh "git" "push" remote name))) + +(defn checkout-tag + "Checkout a tag (detached HEAD)." + [name] + (sh "git" "checkout" name)) diff --git a/test/e2e/aspect-ratio/lazygit-classic-4-3.tape b/test/e2e/aspect-ratio/lazygit-classic-4-3.tape new file mode 100644 index 0000000..a9d5495 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygit-classic-4-3.tape @@ -0,0 +1,15 @@ +# VHS tape for lazygit - Classic 4:3 aspect ratio (1024x768) +Output lazygit-classic-4-3.gif + +Set Shell "bash" +Set Width 1024 +Set Height 768 +Set FontSize 14 +Set Framerate 10 + +Type "cd /home/ajet/repos/lazygitclj && lazygit" +Enter +Sleep 5s +Screenshot lazygit-classic-4-3.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygit-standard-16-9.tape b/test/e2e/aspect-ratio/lazygit-standard-16-9.tape new file mode 100644 index 0000000..02dec9b --- /dev/null +++ b/test/e2e/aspect-ratio/lazygit-standard-16-9.tape @@ -0,0 +1,15 @@ +# VHS tape for lazygit - Standard 16:9 aspect ratio (1280x720) +Output lazygit-standard-16-9.gif + +Set Shell "bash" +Set Width 1280 +Set Height 720 +Set FontSize 14 +Set Framerate 10 + +Type "cd /home/ajet/repos/lazygitclj && lazygit" +Enter +Sleep 5s +Screenshot lazygit-standard-16-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygit-tall-9-16.tape b/test/e2e/aspect-ratio/lazygit-tall-9-16.tape new file mode 100644 index 0000000..35ba6e3 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygit-tall-9-16.tape @@ -0,0 +1,15 @@ +# VHS tape for lazygit - Tall 9:16 aspect ratio (600x1000) +Output lazygit-tall-9-16.gif + +Set Shell "bash" +Set Width 600 +Set Height 1000 +Set FontSize 14 +Set Framerate 10 + +Type "cd /home/ajet/repos/lazygitclj && lazygit" +Enter +Sleep 5s +Screenshot lazygit-tall-9-16.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygit-ultrawide-32-9.tape b/test/e2e/aspect-ratio/lazygit-ultrawide-32-9.tape new file mode 100644 index 0000000..4935dda --- /dev/null +++ b/test/e2e/aspect-ratio/lazygit-ultrawide-32-9.tape @@ -0,0 +1,15 @@ +# VHS tape for lazygit - Ultrawide 32:9 aspect ratio (1600x450) +Output lazygit-ultrawide-32-9.gif + +Set Shell "bash" +Set Width 1600 +Set Height 450 +Set FontSize 14 +Set Framerate 10 + +Type "cd /home/ajet/repos/lazygitclj && lazygit" +Enter +Sleep 5s +Screenshot lazygit-ultrawide-32-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygit-wide-21-9.tape b/test/e2e/aspect-ratio/lazygit-wide-21-9.tape new file mode 100644 index 0000000..d94a175 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygit-wide-21-9.tape @@ -0,0 +1,15 @@ +# VHS tape for lazygit - Wide 21:9 aspect ratio (1400x600) +Output lazygit-wide-21-9.gif + +Set Shell "bash" +Set Width 1400 +Set Height 600 +Set FontSize 14 +Set Framerate 10 + +Type "cd /home/ajet/repos/lazygitclj && lazygit" +Enter +Sleep 5s +Screenshot lazygit-wide-21-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygitclj-classic-4-3.tape b/test/e2e/aspect-ratio/lazygitclj-classic-4-3.tape new file mode 100644 index 0000000..0977210 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygitclj-classic-4-3.tape @@ -0,0 +1,17 @@ +# VHS tape for lazygitclj - Classic 4:3 aspect ratio (1024x768) +Output lazygitclj-classic-4-3.gif + +Require bb + +Set Shell "bash" +Set Width 1024 +Set Height 768 +Set FontSize 14 +Set Framerate 10 + +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-ar && cd /tmp/lazygitclj-e2e-ar && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 3s +Screenshot lazygitclj-classic-4-3.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygitclj-standard-16-9.tape b/test/e2e/aspect-ratio/lazygitclj-standard-16-9.tape new file mode 100644 index 0000000..b3c41b3 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygitclj-standard-16-9.tape @@ -0,0 +1,17 @@ +# VHS tape for lazygitclj - Standard 16:9 aspect ratio (1280x720) +Output lazygitclj-standard-16-9.gif + +Require bb + +Set Shell "bash" +Set Width 1280 +Set Height 720 +Set FontSize 14 +Set Framerate 10 + +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-ar && cd /tmp/lazygitclj-e2e-ar && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 3s +Screenshot lazygitclj-standard-16-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygitclj-tall-9-16.tape b/test/e2e/aspect-ratio/lazygitclj-tall-9-16.tape new file mode 100644 index 0000000..043d0c1 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygitclj-tall-9-16.tape @@ -0,0 +1,17 @@ +# VHS tape for lazygitclj - Tall 9:16 aspect ratio (600x1000) +Output lazygitclj-tall-9-16.gif + +Require bb + +Set Shell "bash" +Set Width 600 +Set Height 1000 +Set FontSize 14 +Set Framerate 10 + +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-ar && cd /tmp/lazygitclj-e2e-ar && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 3s +Screenshot lazygitclj-tall-9-16.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygitclj-ultrawide-32-9.tape b/test/e2e/aspect-ratio/lazygitclj-ultrawide-32-9.tape new file mode 100644 index 0000000..74ce914 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygitclj-ultrawide-32-9.tape @@ -0,0 +1,17 @@ +# VHS tape for lazygitclj - Ultrawide 32:9 aspect ratio (1600x450) +Output lazygitclj-ultrawide-32-9.gif + +Require bb + +Set Shell "bash" +Set Width 1600 +Set Height 450 +Set FontSize 14 +Set Framerate 10 + +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-ar && cd /tmp/lazygitclj-e2e-ar && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 3s +Screenshot lazygitclj-ultrawide-32-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/aspect-ratio/lazygitclj-wide-21-9.tape b/test/e2e/aspect-ratio/lazygitclj-wide-21-9.tape new file mode 100644 index 0000000..b27b1a6 --- /dev/null +++ b/test/e2e/aspect-ratio/lazygitclj-wide-21-9.tape @@ -0,0 +1,17 @@ +# VHS tape for lazygitclj - Wide 21:9 aspect ratio (1400x600) +Output lazygitclj-wide-21-9.gif + +Require bb + +Set Shell "bash" +Set Width 1400 +Set Height 600 +Set FontSize 14 +Set Framerate 10 + +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-ar && cd /tmp/lazygitclj-e2e-ar && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 3s +Screenshot lazygitclj-wide-21-9.png +Type "q" +Sleep 500ms diff --git a/test/e2e/branch-operations.tape b/test/e2e/branch-operations.tape new file mode 100644 index 0000000..1218a87 --- /dev/null +++ b/test/e2e/branch-operations.tape @@ -0,0 +1,68 @@ +# VHS E2E test for lazygitclj - Branch operations +# Tests branch create, delete, rename, merge, checkout + +Output test/e2e/output/branch-operations.gif +Output test/e2e/output/branch-operations.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# First, clean up working tree by stashing +Type "s" +Sleep 500ms + +# Switch to branches panel +Type "3" +Sleep 500ms + +# Create new branch with 'n' +Type "n" +Sleep 500ms +Set TypingSpeed 50ms +Type "test-branch" +Enter +Sleep 1s + +# Should have created and switched to test-branch +# Go back to main - select main first +Type "j" +Sleep 300ms +Type "j" +Sleep 300ms + +# Enter to checkout main +Enter +Sleep 1s + +# Navigate to test-branch and delete it with 'd' +Type "k" +Sleep 300ms +Type "d" +Sleep 1s + +# Branch should be deleted + +# Merge feature-branch into main +# Navigate to feature-branch +Type "k" +Sleep 300ms + +# Merge with 'M' +Type "M" +Sleep 1s + +# Should show merge message + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/branches-tabs.tape b/test/e2e/branches-tabs.tape new file mode 100644 index 0000000..2b62a75 --- /dev/null +++ b/test/e2e/branches-tabs.tape @@ -0,0 +1,48 @@ +# VHS E2E test for lazygitclj - Branches panel tabs +# Tests tab switching between Local, Remotes, and Tags ([ and ] keys) + +Output test/e2e/output/branches-tabs.gif +Output test/e2e/output/branches-tabs.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo with tags and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-branches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Switch to branches panel with '3' +Type "3" +Sleep 500ms + +# Should show [Local] | Remotes | Tags tab indicator +# Switch to Remotes tab with ']' +Type "]" +Sleep 500ms + +# Should show Local | [Remotes] | Tags +# Note: No remote branches in test repo, so empty +# Switch to Tags with ']' again +Type "]" +Sleep 500ms + +# Should show Local | Remotes | [Tags] with v1.0.0 tag +Type "j" +Sleep 500ms + +# Switch back to Local with '[' +Type "[" +Sleep 500ms +Type "[" +Sleep 500ms + +# Should be back on Local tab +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/branches.tape b/test/e2e/branches.tape new file mode 100644 index 0000000..7988ed5 --- /dev/null +++ b/test/e2e/branches.tape @@ -0,0 +1,39 @@ +# VHS E2E test for lazygitclj - Branch operations +# Tests branch checkout (like lazygit's Enter key on branches) + +Output test/e2e/output/branches.gif +Output test/e2e/output/branches.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo (clean working tree) and run lazygitclj +Type "cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-branch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Switch to Branches panel with '3' (like lazygit number shortcuts) +Type "3" +Sleep 500ms + +# Navigate to feature-branch +Type "j" +Sleep 500ms + +# Checkout branch with Enter +Enter +Sleep 1s + +# Should now be on feature-branch (shown in status bar) +# Switch back to Files panel to verify +Type "1" +Sleep 500ms + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/commit-verify.tape b/test/e2e/commit-verify.tape new file mode 100644 index 0000000..3110820 --- /dev/null +++ b/test/e2e/commit-verify.tape @@ -0,0 +1,85 @@ +# VHS E2E test for lazygitclj - Commit workflow with git verification +# Tests the full commit workflow: stage files, open commit modal, type message, commit +# Verifies the commit was actually made using git CLI + +Output test/e2e/output/commit-verify.gif +Output test/e2e/output/commit-verify.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup: Create a fresh test repo +Type "rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd /tmp/lazygitclj-e2e-commit-verify" +Enter +Sleep 500ms + +# Initialize git repo +Type "git init -b main && git config user.email 'test@example.com' && git config user.name 'Test User'" +Enter +Sleep 500ms + +# Create initial commit +Type "echo 'initial' > README.md && git add . && git commit -m 'Initial commit'" +Enter +Sleep 500ms + +# Create a new file to commit with lazygitclj +Type "echo 'test content for commit' > test-file.txt" +Enter +Sleep 500ms + +# Show the file exists +Type "ls -la" +Enter +Sleep 500ms + +# Run lazygitclj +Type "bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Stage the file with 'a' (stage all) +Type "a" +Sleep 500ms + +# Press 'c' to open commit modal +Type "c" +Sleep 1s + +# Type commit message +Set TypingSpeed 50ms +Type "Add test file via lazygitclj" +Sleep 500ms + +# Press Enter to commit +Enter +Sleep 1s + +# Should see "Committed!" message +# Navigate to commits panel to see the new commit +Type "4" +Sleep 500ms + +# Quit lazygitclj +Type "q" +Sleep 1s + +# Verify the commit was made using git CLI +Type "git log --oneline -2" +Enter +Sleep 500ms + +# Show that the file is tracked +Type "git status" +Enter +Sleep 500ms + +# Show commit details +Type "git show --stat HEAD" +Enter +Sleep 1s diff --git a/test/e2e/commit.tape b/test/e2e/commit.tape new file mode 100644 index 0000000..9522fb6 --- /dev/null +++ b/test/e2e/commit.tape @@ -0,0 +1,50 @@ +# VHS E2E test for lazygitclj - Commit workflow +# Tests committing staged files (like lazygit's c key) + +Output test/e2e/output/commit.gif +Output test/e2e/output/commit.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Stage all files first +Type "a" +Sleep 500ms + +# Press 'c' to start commit (like lazygit) +Type "c" +Sleep 500ms + +# Type commit message (with typing speed set) +Set TypingSpeed 50ms +Type "Add test changes" +Sleep 500ms + +# Press Enter to commit +Enter +Sleep 1s + +# Should see "Committed!" message and files should be cleared +# Check commits panel to verify +Type "2" +Sleep 500ms + +# Navigate commits to see new commit +Type "j" +Sleep 500ms +Type "k" +Sleep 500ms + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/commits-tabs.tape b/test/e2e/commits-tabs.tape new file mode 100644 index 0000000..55e6fd9 --- /dev/null +++ b/test/e2e/commits-tabs.tape @@ -0,0 +1,46 @@ +# VHS E2E test for lazygitclj - Commits panel tabs +# Tests tab switching between Commits and Reflog ([ and ] keys) + +Output test/e2e/output/commits-tabs.gif +Output test/e2e/output/commits-tabs.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-commits-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Switch to commits panel with '2' +Type "2" +Sleep 500ms + +# Should show [Commits] | Reflog tab indicator +# Switch to Reflog tab with ']' +Type "]" +Sleep 500ms + +# Should now show Commits | [Reflog] tab indicator +# Navigate reflog entries +Type "j" +Sleep 500ms +Type "k" +Sleep 500ms + +# Switch back to Commits with '[' +Type "[" +Sleep 500ms + +# Should be back on Commits tab +Type "j" +Sleep 500ms + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/debug.tape b/test/e2e/debug.tape new file mode 100644 index 0000000..8098597 --- /dev/null +++ b/test/e2e/debug.tape @@ -0,0 +1,31 @@ +# VHS debug test - check git status and lazygitclj display + +Output test/e2e/output/debug.gif +Output test/e2e/output/debug.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug" +Enter +Sleep 2s + +# Show git status +Type "cd /tmp/lazygitclj-debug && git status --porcelain" +Enter +Sleep 1s + +# Run lazygitclj +Type "bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/file1.txt b/test/e2e/file1.txt new file mode 100644 index 0000000..e69de29 diff --git a/test/e2e/help-panel.tape b/test/e2e/help-panel.tape new file mode 100644 index 0000000..97da2da --- /dev/null +++ b/test/e2e/help-panel.tape @@ -0,0 +1,50 @@ +# VHS E2E test for lazygitclj - Help panel +# Tests help display (? key shows keybindings) + +Output test/e2e/output/help-panel.gif +Output test/e2e/output/help-panel.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Open help panel with '?' +Type "?" +Sleep 2s + +# Help panel should show keybindings for: +# - Global keys (q, r, tab, 1-4, j/k, z/Z, p, P, ?, D) +# - Files panel (space, a, c, d, s, S) +# - Commits panel ([/], space, g, C, t, r, y) +# - Branches panel ([/], enter, n, d, R, M, f) +# - Stash panel (space, g, d, n) + +# Close help with escape +Escape +Sleep 500ms + +# Verify we're back to normal view +Type "j" +Sleep 500ms + +# Open help again with '?' +Type "?" +Sleep 1s + +# Close with 'q' (also works) +Type "q" +Sleep 500ms + +# Should be back to normal view +# Quit the app +Type "q" +Sleep 1s diff --git a/test/e2e/navigation.tape b/test/e2e/navigation.tape new file mode 100644 index 0000000..72cabf4 --- /dev/null +++ b/test/e2e/navigation.tape @@ -0,0 +1,73 @@ +# VHS E2E test for lazygitclj - Basic navigation +# Tests panel switching and cursor movement (like lazygit) + +Output test/e2e/output/navigation.gif +Output test/e2e/output/navigation.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Should start on Files panel (panel 1) +# Navigate down with j (vim style like lazygit) +Type "j" +Sleep 500ms +Type "j" +Sleep 500ms + +# Navigate up with k +Type "k" +Sleep 500ms + +# Switch to Commits panel with Tab +Tab +Sleep 500ms + +# Navigate commits +Type "j" +Sleep 500ms +Type "k" +Sleep 500ms + +# Switch to Branches panel with Tab +Tab +Sleep 500ms + +# Navigate branches +Type "j" +Sleep 500ms + +# Switch back to Files using number key (like lazygit) +Type "1" +Sleep 500ms + +# Switch to Commits with number key +Type "2" +Sleep 500ms + +# Switch to Branches with number key +Type "3" +Sleep 500ms + +# Test arrow keys too +Up +Sleep 300ms +Down +Sleep 300ms + +# Refresh with r +Type "r" +Sleep 500ms + +# Quit with q +Type "q" +Sleep 1s diff --git a/test/e2e/reset-menu.tape b/test/e2e/reset-menu.tape new file mode 100644 index 0000000..3c217d4 --- /dev/null +++ b/test/e2e/reset-menu.tape @@ -0,0 +1,57 @@ +# VHS E2E test for lazygitclj - Reset options menu +# Tests reset options (D key opens reset menu) + +Output test/e2e/output/reset-menu.gif +Output test/e2e/output/reset-menu.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo with changes and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Open reset options menu with 'D' +Type "D" +Sleep 1s + +# Menu should show: +# s - Soft reset (uncommit, keep staged) +# m - Mixed reset (uncommit, unstage) +# h - Hard reset (discard all) +# u - Unstage all staged changes +# d - Discard all unstaged changes +# c - Clean untracked files + +# Cancel with escape +Escape +Sleep 500ms + +# Open menu again and unstage all with 'u' +Type "D" +Sleep 500ms +Type "u" +Sleep 1s + +# All staged files should now be unstaged +# Verify in files panel +Type "j" +Sleep 500ms + +# Open reset menu again to discard unstaged +Type "D" +Sleep 500ms +Type "d" +Sleep 1s + +# Modified files should be clean now (only untracked remain) + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/run-all.sh b/test/e2e/run-all.sh new file mode 100755 index 0000000..c11c40e --- /dev/null +++ b/test/e2e/run-all.sh @@ -0,0 +1,54 @@ +#!/bin/bash +# Run all VHS e2e tests + +set -e + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo "Running lazygitclj VHS e2e tests..." +echo "=================================" + +# List of test tapes +TESTS=( + "debug.tape" + "navigation.tape" + "staging.tape" + "commit.tape" + "commit-verify.tape" + "branches.tape" + "branch-operations.tape" + "stash-operations.tape" + "stash-menu.tape" + "help-panel.tape" + "reset-menu.tape" + "commits-tabs.tape" + "branches-tabs.tape" + "undo-redo.tape" +) + +PASSED=0 +FAILED=0 + +for tape in "${TESTS[@]}"; do + echo "" + echo "Running: $tape" + echo "---" + + if timeout 60 vhs "$tape" 2>&1; then + echo "PASSED: $tape" + ((PASSED++)) + else + echo "FAILED: $tape" + ((FAILED++)) + fi +done + +echo "" +echo "=================================" +echo "Results: $PASSED passed, $FAILED failed" +echo "=================================" + +if [ $FAILED -gt 0 ]; then + exit 1 +fi diff --git a/test/e2e/setup-test-repo.sh b/test/e2e/setup-test-repo.sh new file mode 100755 index 0000000..d10d78d --- /dev/null +++ b/test/e2e/setup-test-repo.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Setup a test git repository for e2e testing + +set -e + +TEST_REPO="${1:-/tmp/lazygitclj-test-repo}" + +# Clean up if exists +rm -rf "$TEST_REPO" +mkdir -p "$TEST_REPO" +cd "$TEST_REPO" + +# Initialize git repo +git init -b main +git config user.email "test@example.com" +git config user.name "Test User" + +# Create initial files and commit +echo "# Test Project" > README.md +echo "line1" > file1.txt +echo "line1" > file2.txt +git add . +git commit -m "Initial commit" + +# Create a feature branch +git checkout -b feature-branch +echo "feature work" >> file1.txt +git add . +git commit -m "Feature work" +git checkout main + +# Create some unstaged changes +echo "modified" >> file1.txt + +# Create untracked file +echo "new file content" > newfile.txt + +# Stage one file +echo "staged content" >> file2.txt +git add file2.txt + +echo "Test repo created at $TEST_REPO" +echo " - main branch with 1 commit" +echo " - feature-branch with 1 extra commit" +echo " - 1 staged file (file2.txt)" +echo " - 1 unstaged file (file1.txt)" +echo " - 1 untracked file (newfile.txt)" diff --git a/test/e2e/staging.tape b/test/e2e/staging.tape new file mode 100644 index 0000000..f9dba24 --- /dev/null +++ b/test/e2e/staging.tape @@ -0,0 +1,45 @@ +# VHS E2E test for lazygitclj - File staging/unstaging +# Tests staging and unstaging files (like lazygit's space key) + +Output test/e2e/output/staging.gif +Output test/e2e/output/staging.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Should be on Files panel with some staged and unstaged files +# Move to the staged file and unstage it with space +Type " " +Sleep 500ms + +# Move down to an unstaged file +Type "j" +Sleep 500ms + +# Stage it with space +Type " " +Sleep 500ms + +# Stage all with 'a' (like lazygit) +Type "a" +Sleep 500ms + +# Move to a file and discard changes with 'd' +Type "j" +Sleep 500ms +Type "d" +Sleep 500ms + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/stash-menu.tape b/test/e2e/stash-menu.tape new file mode 100644 index 0000000..6b3d4ca --- /dev/null +++ b/test/e2e/stash-menu.tape @@ -0,0 +1,50 @@ +# VHS E2E test for lazygitclj - Stash menu options +# Tests stash options menu (S key opens menu) + +Output test/e2e/output/stash-menu.gif +Output test/e2e/output/stash-menu.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo with changes and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash-menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Open stash options menu with 'S' +Type "S" +Sleep 1s + +# Menu should be visible showing options: +# a - Stash all changes +# i - Stash all and keep index +# U - Stash including untracked +# s - Stash staged only +# u - Stash unstaged only + +# Cancel with escape first +Escape +Sleep 500ms + +# Open menu again +Type "S" +Sleep 500ms + +# Stash all with 'a' +Type "a" +Sleep 1s + +# Files should be clean now +# Check stash panel +Type "4" +Sleep 500ms + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/stash-operations.tape b/test/e2e/stash-operations.tape new file mode 100644 index 0000000..ccb60bc --- /dev/null +++ b/test/e2e/stash-operations.tape @@ -0,0 +1,52 @@ +# VHS E2E test for lazygitclj - Stash operations +# Tests stash functionality (s for quick stash, S for stash menu) + +Output test/e2e/output/stash-operations.gif +Output test/e2e/output/stash-operations.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo with changes and run lazygitclj +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Should be on Files panel with staged and unstaged files +# Quick stash all changes with 's' +Type "s" +Sleep 1s + +# Files panel should now be clean, check stash panel +Type "4" +Sleep 500ms + +# Should see one stash entry +# Navigate to stash and apply it with space +Type " " +Sleep 1s + +# Go back to files panel - should see changes restored +Type "1" +Sleep 500ms + +# Stash again with 's' +Type "s" +Sleep 1s + +# Go to stash panel +Type "4" +Sleep 500ms + +# Pop the stash with 'g' (apply and remove) +Type "g" +Sleep 1s + +# Quit +Type "q" +Sleep 1s diff --git a/test/e2e/test/e2e/output/branch-operations.ascii b/test/e2e/test/e2e/output/branch-operations.ascii new file mode 100644 index 0000000..ca92c05 --- /dev/null +++ b/test/e2e/test/e2e/output/branch-operations.ascii @@ -0,0 +1,1176 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3n + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3n + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3n + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> j + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> j + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> k + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> k + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kd + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kd + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdk + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdk + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdkM + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdkM + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdkMq + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branch-ops && cd /tmp/lazygitclj-e2e-branch +-ops && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s3ntest-branch +bash: s3ntest-branch: command not found +> jj +bash: jj: command not found +> kdkMq + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/branches-tabs.ascii b/test/e2e/test/e2e/output/branches-tabs.ascii new file mode 100644 index 0000000..edd7bb8 --- /dev/null +++ b/test/e2e/test/e2e/output/branches-tabs.ascii @@ -0,0 +1,816 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[[q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-branches-tabs && cd /tmp/lazygitclj-e2e-bra +nches-tabs && git tag v1.0.0 && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 3]]j[[q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/branches.ascii b/test/e2e/test/e2e/output/branches.ascii new file mode 100644 index 0000000..758d157 --- /dev/null +++ b/test/e2e/test/e2e/output/branches.ascii @@ -0,0 +1,696 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> 1 + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> 1 + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> 1q + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> cd /tmp && rm -rf lazygitclj-e2e-branch && git clone /tmp/lazygitclj-e2e-nav lazygitclj-e2e-b +ranch 2>/dev/null && cd lazygitclj-e2e-branch && git checkout main && bb --config /home/ajet/re +pos/lazygitclj/bb.edn start +> 3j +bash: 3j: command not found +> 1q + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/commit-verify.ascii b/test/e2e/test/e2e/output/commit-verify.ascii new file mode 100644 index 0000000..2b052b1 --- /dev/null +++ b/test/e2e/test/e2e/output/commit-verify.ascii @@ -0,0 +1,1506 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ │ +└────────────────────────────┘ │ │ +╔═ 2 Files (1) ══════════════╗ │ │ +║ ?? test-file.txt ║ │ │ +║ ║ │ │ +║ ║ │ │ +║ ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ ╭─ Commit Message ───────────────────────────────╮ │ +└─────────────────────│ █ │ │ +┌─ 4 Commits [C] R ───╰────────────────────────────────────────────────╯ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ ╭─ Commit Message ───────────────────────────────╮ │ +└─────────────────────│ █ │ │ +┌─ 4 Commits [C] R ───╰────────────────────────────────────────────────╯ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ ╭─ Commit Message ───────────────────────────────╮ │ +└─────────────────────│ █ │ │ +┌─ 4 Commits [C] R ───╰────────────────────────────────────────────────╯ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ ╭─ Commit Message ───────────────────────────────╮ │ +└─────────────────────│ Add test file via lazygitclj█ │ │ +┌─ 4 Commits [C] R ───╰────────────────────────────────────────────────╯ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → cf52878 │ │ diff --git a/test-file.txt b/test-file.txt │ +└────────────────────────────┘ │ new file mode 100644 │ +╔═ 2 Files (1) ══════════════╗ │ index 0000000..e11a339 │ +║ A test-file.txt ║ │ --- /dev/null │ +║ ║ │ +++ b/test-file.txt │ +║ ║ │ @@ -0,0 +1 @@ │ +║ ║ │ +test content for commit │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ ╭─ Commit Message ───────────────────────────────╮ │ +└─────────────────────│ Add test file via lazygitclj█ │ │ +┌─ 4 Commits [C] R ───╰────────────────────────────────────────────────╯ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── + Committed! +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → 0563668 │ │ Select an item to view diff │ +└────────────────────────────┘ │ │ +╔═ 2 Files (0) ══════════════╗ │ │ +║ No changes ║ │ │ +║ ║ │ │ +║ ║ │ │ +║ ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ 0563668 Add test file ... │ │ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── + Committed! +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → 0563668 │ │ Select an item to view diff │ +└────────────────────────────┘ │ │ +╔═ 2 Files (0) ══════════════╗ │ │ +║ No changes ║ │ │ +║ ║ │ │ +║ ║ │ │ +║ ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ │ +│ │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ 0563668 Add test file ... │ │ │ +│ cf52878 Initial commit │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── + Committed! +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → 0563668 │ │ commit 0563668991bb1bb5358134fb72669eda32e9076d │ +└────────────────────────────┘ │ Author: Test User │ +┌─ 2 Files (0) ──────────────┐ │ Date: Wed Jan 21 17:44:36 2026 -0500 │ +│ No changes │ │ │ +│ │ │ Add test file via lazygitclj │ +│ │ │ --- │ +│ │ │ test-file.txt | 1 + │ +└────────────────────────────┘ │ 1 file changed, 1 insertion(+) │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ diff --git a/test-file.txt b/test-file.txt │ +│ │ │ new file mode 100644 │ +│ │ │ index 0000000..e11a339 │ +│ │ │ --- /dev/null │ +└────────────────────────────┘ │ +++ b/test-file.txt │ +╔═ 4 Commits [C] R ══════════╗ │ @@ -0,0 +1 @@ │ +║ 0563668 Add test file ... ║ │ +test content for commit │ +║ cf52878 Initial commit ║ │ │ +║ ║ │ │ +║ ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav []:tabs spc:checkout p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── + Committed! +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ main → 0563668 │ │ commit 0563668991bb1bb5358134fb72669eda32e9076d │ +└────────────────────────────┘ │ Author: Test User │ +┌─ 2 Files (0) ──────────────┐ │ Date: Wed Jan 21 17:44:36 2026 -0500 │ +│ No changes │ │ │ +│ │ │ Add test file via lazygitclj │ +│ │ │ --- │ +│ │ │ test-file.txt | 1 + │ +└────────────────────────────┘ │ 1 file changed, 1 insertion(+) │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * main │ │ diff --git a/test-file.txt b/test-file.txt │ +│ │ │ new file mode 100644 │ +│ │ │ index 0000000..e11a339 │ +│ │ │ --- /dev/null │ +└────────────────────────────┘ │ +++ b/test-file.txt │ +╔═ 4 Commits [C] R ══════════╗ │ @@ -0,0 +1 @@ │ +║ 0563668 Add test file ... ║ │ +test content for commit │ +║ cf52878 Initial commit ║ │ │ +║ ║ │ │ +║ ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav []:tabs spc:checkout p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status + + + + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status +On branch main +nothing to commit, working tree clean +> + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status +On branch main +nothing to commit, working tree clean +> + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status +On branch main +nothing to commit, working tree clean +> git show --stat HEAD + +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status +On branch main +nothing to commit, working tree clean +> git show --stat HEAD +commit 0563668991bb1bb5358134fb72669eda32e9076d (HEAD -> main) +──────────────────────────────────────────────────────────────────────────────── +> rm -rf /tmp/lazygitclj-e2e-commit-verify && mkdir -p /tmp/lazygitclj-e2e-commit-verify && cd +/tmp/lazygitclj-e2e-commit-verify +> git init -b main && git config user.email 'test@example.com' && git config user.name 'Test Us +er' +Initialized empty Git repository in /tmp/lazygitclj-e2e-commit-verify/.git/ +> echo 'initial' > README.md && git add . && git commit -m 'Initial commit' +[main (root-commit) cf52878] Initial commit + 1 file changed, 1 insertion(+) + create mode 100644 README.md +> echo 'test content for commit' > test-file.txt +> ls -la +total 52 +drwxrwxr-x 3 ajet ajet 4096 Jan 21 17:44 . +drwxrwxrwt 70 root root 36864 Jan 21 17:44 .. +drwxrwxr-x 8 ajet ajet 4096 Jan 21 17:44 .git +-rw-rw-r-- 1 ajet ajet 8 Jan 21 17:44 README.md +-rw-rw-r-- 1 ajet ajet 24 Jan 21 17:44 test-file.txt +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> git log --oneline -2 +0563668 (HEAD -> main) Add test file via lazygitclj +cf52878 Initial commit +> git status +On branch main +nothing to commit, working tree clean +> git show --stat HEAD +commit 0563668991bb1bb5358134fb72669eda32e9076d (HEAD -> main) +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/commit.ascii b/test/e2e/test/e2e/output/commit.ascii new file mode 100644 index 0000000..dc9fbbe --- /dev/null +++ b/test/e2e/test/e2e/output/commit.ascii @@ -0,0 +1,906 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2 + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2 + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2j + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2j + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2jk + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2jk + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2jkq + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commit && cd /tmp/lazygitclj-e2e-commit && +bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acAdd test changes +bash: acAdd: command not found +> 2jkq + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/commits-tabs.ascii b/test/e2e/test/e2e/output/commits-tabs.ascii new file mode 100644 index 0000000..ef52179 --- /dev/null +++ b/test/e2e/test/e2e/output/commits-tabs.ascii @@ -0,0 +1,816 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2] + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[ + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[jq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-commits-tabs && cd /tmp/lazygitclj-e2e-comm +its-tabs && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> 2]jk[jq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/debug.ascii b/test/e2e/test/e2e/output/debug.ascii new file mode 100644 index 0000000..adf89a4 --- /dev/null +++ b/test/e2e/test/e2e/output/debug.ascii @@ -0,0 +1,636 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +┌─ 1 Status ─────────────────┐ ┌─ 0 Main ─────────────────────────────────────────────────────┐ +│ master → 8b44d40 │ │ │ +└────────────────────────────┘ │ │ +╔═ 2 Files (44) ═════════════╗ │ │ +║ M .gitignore ║ │ │ +║ A CLAUDE.md ║ │ │ +║ A PRD.md ║ │ │ +║ M bb.edn ║ │ │ +╚════════════════════════════╝ │ │ +┌─ 3 Branches [L] R T ───────┐ │ │ +│ * master │ │ │ +│ new-feature │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 4 Commits [C] R ──────────┐ │ │ +│ 8b44d40 Fix syntax err... │ │ │ +│ 5a8629b Initial clajyg... │ │ │ +│ │ │ │ +│ │ │ │ +└────────────────────────────┘ │ │ +┌─ 5 Stash (0) ──────────────┐ │ │ +│ No stashes │ │ │ +│ │ └──────────────────────────────────────────────────────────────┘ +│ │ ┌─ Command Log ────────────────────────────────────────────────┐ +│ │ │ │ +└────────────────────────────┘ │ │ + └──────────────────────────────────────────────────────────────┘ +q:quit ?:help h/l:panels j/k:nav spc:stage a:all c:commit p/P:pull/push +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-debug +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> cd /tmp/lazygitclj-debug && git status --porcelain +bash: cd: /tmp/lazygitclj-debug: No such file or directory +> bb --config /home/ajet/repos/lazygitclj/bb.edn start +Starting lazygitclj... + +Goodbye! +> + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/help-panel.ascii b/test/e2e/test/e2e/output/help-panel.ascii new file mode 100644 index 0000000..174cbcd --- /dev/null +++ b/test/e2e/test/e2e/output/help-panel.ascii @@ -0,0 +1,756 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ?? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ?? + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ??q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ??q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ??qq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-help && cd /tmp/lazygitclj-e2e-help && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ??qq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/navigation.ascii b/test/e2e/test/e2e/output/navigation.ascii new file mode 100644 index 0000000..153dd7e --- /dev/null +++ b/test/e2e/test/e2e/output/navigation.ascii @@ -0,0 +1,1296 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjk + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj1 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj1 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj12 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj12 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123r + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123r + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123rq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-nav && cd /tmp/lazygitclj-e2e-nav && bb --c +onfig /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> jjkjkj123rq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/reset-menu.ascii b/test/e2e/test/e2e/output/reset-menu.ascii new file mode 100644 index 0000000..cff7376 --- /dev/null +++ b/test/e2e/test/e2e/output/reset-menu.ascii @@ -0,0 +1,876 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> D + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Du + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Du + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Duj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Duj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujD + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujD + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujDd + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujDd + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujDdq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-reset && cd /tmp/lazygitclj-e2e-reset && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> DujDdq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/staging.ascii b/test/e2e/test/e2e/output/staging.ascii new file mode 100644 index 0000000..8faf7f7 --- /dev/null +++ b/test/e2e/test/e2e/output/staging.ascii @@ -0,0 +1,816 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j aj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j aj + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j ajd + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j ajd + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j ajdq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stage && cd /tmp/lazygitclj-e2e-stage && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> j ajdq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/stash-menu.ascii b/test/e2e/test/e2e/output/stash-menu.ascii new file mode 100644 index 0000000..2369908 --- /dev/null +++ b/test/e2e/test/e2e/output/stash-menu.ascii @@ -0,0 +1,756 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> S + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa4q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash-menu && cd /tmp/lazygitclj-e2e-stash- +menu && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> Sa4q + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/stash-operations.ascii b/test/e2e/test/e2e/output/stash-operations.ascii new file mode 100644 index 0000000..9e372e4 --- /dev/null +++ b/test/e2e/test/e2e/output/stash-operations.ascii @@ -0,0 +1,876 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4 + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4g + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4g + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4gq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-stash && cd /tmp/lazygitclj-e2e-stash && bb + --config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> s4 1s4gq + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/test/e2e/output/undo-redo.ascii b/test/e2e/test/e2e/output/undo-redo.ascii new file mode 100644 index 0000000..614d593 --- /dev/null +++ b/test/e2e/test/e2e/output/undo-redo.ascii @@ -0,0 +1,1176 @@ +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> a + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> ac + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message + + + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> q + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> q + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start + + + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> a + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> a + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> ac + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> ac + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit + + + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> z + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> z + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> zZ + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> zZ + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> zZq + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── +> ./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb - +-config /home/ajet/repos/lazygitclj/bb.edn start +bash: ./test/e2e/setup-test-repo.sh: No such file or directory +> acFirst commit message +bash: acFirst: command not found +> qecho 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start +bash: qecho: command not found +> acSecond commit +bash: acSecond: command not found +> zZq + + + + + + + + + + + + + + + + + + + +──────────────────────────────────────────────────────────────────────────────── diff --git a/test/e2e/undo-redo.tape b/test/e2e/undo-redo.tape new file mode 100644 index 0000000..76b4c11 --- /dev/null +++ b/test/e2e/undo-redo.tape @@ -0,0 +1,59 @@ +# VHS E2E test for lazygitclj - Undo/Redo operations +# Tests undo (z) and redo (Z) via reflog navigation + +Output test/e2e/output/undo-redo.gif +Output test/e2e/output/undo-redo.ascii + +Require bb + +Set Shell "bash" +Set FontSize 14 +Set Width 1000 +Set Height 600 +Set Framerate 10 + +# Setup test repo and make some changes +Type "./test/e2e/setup-test-repo.sh /tmp/lazygitclj-e2e-undo && cd /tmp/lazygitclj-e2e-undo && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Stage all and commit +Type "a" +Sleep 500ms +Type "c" +Sleep 500ms +Set TypingSpeed 50ms +Type "First commit message" +Enter +Sleep 1s + +# Create another change +# Exit and modify file +Type "q" +Sleep 500ms +Type "echo 'more changes' >> file1.txt && bb --config /home/ajet/repos/lazygitclj/bb.edn start" +Enter +Sleep 2s + +# Stage and commit again +Type "a" +Sleep 500ms +Type "c" +Sleep 500ms +Type "Second commit" +Enter +Sleep 1s + +# Now undo with 'z' - should reset to previous state +Type "z" +Sleep 1s + +# Status bar should show undo message +# Redo with 'Z' +Type "Z" +Sleep 1s + +# Should be back to latest state +# Quit +Type "q" +Sleep 1s diff --git a/test/lazygitclj/core_test.clj b/test/lazygitclj/core_test.clj new file mode 100644 index 0000000..19f7a79 --- /dev/null +++ b/test/lazygitclj/core_test.clj @@ -0,0 +1,288 @@ +(ns lazygitclj.core-test + "Unit tests for lazygitclj.core namespace - model and update functions" + (:require [clojure.test :refer [deftest testing is]] + [lazygitclj.core :as core] + [tui.simple :as tui])) + +;; Helper to create key messages in the format the TUI library uses +(defn key-msg [k] + (cond + (char? k) [:key {:char k}] + (keyword? k) [:key k] + (and (vector? k) (= :ctrl (first k))) [:key {:ctrl true :char (second k)}] + :else [:key k])) + +;; === Model Tests === + +(deftest test-file-items + (testing "combines staged and unstaged files" + (let [model {:staged [{:path "a.txt"} {:path "b.txt"}] + :unstaged [{:path "c.txt"}]} + items (core/file-items model)] + (is (= 3 (count items))) + (is (= :staged (:type (first items)))) + (is (= :unstaged (:type (last items)))))) + + (testing "returns empty vector when no files" + (let [model {:staged [] :unstaged []}] + (is (= [] (core/file-items model)))))) + +(deftest test-current-items + (testing "returns file items for files panel" + (let [model {:panel :files + :staged [{:path "a.txt"}] + :unstaged [{:path "b.txt"}]}] + (is (= 2 (count (core/current-items model)))))) + + (testing "returns commits for commits panel" + (let [model {:panel :commits + :commits-tab :commits + :commits [{:sha "abc123"}] + :reflog []}] + (is (= 1 (count (core/current-items model)))))) + + (testing "returns reflog for commits panel with reflog tab" + (let [model {:panel :commits + :commits-tab :reflog + :commits [] + :reflog [{:sha "def456"} {:sha "ghi789"}]}] + (is (= 2 (count (core/current-items model)))))) + + (testing "returns branches for branches panel" + (let [model {:panel :branches + :branches-tab :local + :branches ["main" "feature"]}] + (is (= 2 (count (core/current-items model)))))) + + (testing "returns remote branches for branches panel with remotes tab" + (let [model {:panel :branches + :branches-tab :remotes + :remote-branches ["origin/main"]}] + (is (= 1 (count (core/current-items model)))))) + + (testing "returns tags for branches panel with tags tab" + (let [model {:panel :branches + :branches-tab :tags + :tags ["v1.0.0" "v2.0.0"]}] + (is (= 2 (count (core/current-items model)))))) + + (testing "returns stashes for stash panel" + (let [model {:panel :stash + :stashes [{:ref "stash@{0}"}]}] + (is (= 1 (count (core/current-items model))))))) + +(deftest test-clamp-cursor + (testing "clamps cursor to valid range" + (let [model {:panel :files + :cursor 10 + :staged [{:path "a.txt"}] + :unstaged []} + clamped (core/clamp-cursor model)] + (is (= 0 (:cursor clamped))))) + + (testing "keeps cursor at valid position" + (let [model {:panel :files + :cursor 1 + :staged [{:path "a.txt"} {:path "b.txt"}] + :unstaged []} + clamped (core/clamp-cursor model)] + (is (= 1 (:cursor clamped))))) + + (testing "handles empty lists" + (let [model {:panel :files + :cursor 5 + :staged [] + :unstaged []} + clamped (core/clamp-cursor model)] + (is (= 0 (:cursor clamped)))))) + +(deftest test-truncate + (testing "truncates long strings" + (is (= "hello..." (core/truncate "hello world" 5)))) + + (testing "keeps short strings" + (is (= "hi" (core/truncate "hi" 10)))) + + (testing "handles nil" + (is (nil? (core/truncate nil 10))))) + +;; === Update Tests === + +(deftest test-update-model-quit + (testing "q returns quit command" + (let [[model cmd] (core/update-model {} (key-msg \q))] + (is (= [:quit] cmd)))) + + (testing "ctrl-c returns quit command" + (let [[model cmd] (core/update-model {} [:key {:ctrl true :char \c}])] + (is (= [:quit] cmd))))) + +(deftest test-update-model-panel-switch + (testing "number keys switch panels (2-5 matching lazygit)" + (let [[model _] (core/update-model {:panel :commits :cursor 0 + :staged [] :unstaged []} (key-msg \2))] + (is (= :files (:panel model)))) + + (let [[model _] (core/update-model {:panel :files :cursor 0 + :branches-tab :local + :branches [] :remote-branches [] + :tags []} (key-msg \3))] + (is (= :branches (:panel model)))) + + (let [[model _] (core/update-model {:panel :files :cursor 0 + :commits-tab :commits + :commits [] :reflog []} (key-msg \4))] + (is (= :commits (:panel model)))) + + (let [[model _] (core/update-model {:panel :files :cursor 0 + :stashes []} (key-msg \5))] + (is (= :stash (:panel model))))) + + (testing "l key cycles panels right (files → branches → commits → stash → files)" + (let [[model _] (core/update-model {:panel :files :cursor 0 + :branches-tab :local + :branches [] :remote-branches [] + :tags []} (key-msg \l))] + (is (= :branches (:panel model)))) + + (let [[model _] (core/update-model {:panel :branches :cursor 0 + :commits-tab :commits + :commits [] :reflog []} (key-msg \l))] + (is (= :commits (:panel model)))) + + (let [[model _] (core/update-model {:panel :commits :cursor 0 + :stashes []} (key-msg \l))] + (is (= :stash (:panel model)))) + + (let [[model _] (core/update-model {:panel :stash :cursor 0 + :staged [] :unstaged []} (key-msg \l))] + (is (= :files (:panel model)))))) + +(deftest test-update-model-cursor-movement + (testing "j moves cursor down" + (let [[model _] (core/update-model {:panel :files :cursor 0 + :staged [{:path "a"} {:path "b"}] + :unstaged []} (key-msg \j))] + (is (= 1 (:cursor model))))) + + (testing "k moves cursor up" + (let [[model _] (core/update-model {:panel :files :cursor 1 + :staged [{:path "a"} {:path "b"}] + :unstaged []} (key-msg \k))] + (is (= 0 (:cursor model))))) + + (testing "down arrow moves cursor down" + (let [[model _] (core/update-model {:panel :files :cursor 0 + :staged [{:path "a"} {:path "b"}] + :unstaged []} (key-msg :down))] + (is (= 1 (:cursor model))))) + + (testing "up arrow moves cursor up" + (let [[model _] (core/update-model {:panel :files :cursor 1 + :staged [{:path "a"} {:path "b"}] + :unstaged []} (key-msg :up))] + (is (= 0 (:cursor model)))))) + +(deftest test-update-model-help-menu + (testing "? opens help menu" + (let [[model _] (core/update-model {:menu-mode nil} (key-msg \?))] + (is (= :help (:menu-mode model)))))) + +(deftest test-update-model-reset-menu + (testing "D opens reset options menu" + (let [[model _] (core/update-model {:menu-mode nil} (key-msg \D))] + (is (= :reset-options (:menu-mode model)))))) + +(deftest test-update-model-input-mode + (testing "c in files panel opens commit input when staged files exist" + (let [[model _] (core/update-model {:panel :files + :staged [{:path "a.txt"}] + :unstaged []} (key-msg \c))] + (is (= :commit (:input-mode model))))) + + (testing "c in files panel shows message when no staged files" + (let [[model _] (core/update-model {:panel :files + :staged [] + :unstaged []} (key-msg \c))] + (is (= "Nothing staged to commit" (:message model)))))) + +(deftest test-update-input-mode + (testing "escape cancels input mode" + (let [[model _] (core/update-input-mode {:input-mode :commit + :input-buffer "test" + :input-context nil} (key-msg :escape))] + (is (nil? (:input-mode model))) + (is (= "" (:input-buffer model))))) + + (testing "backspace removes last character" + (let [[model _] (core/update-input-mode {:input-mode :commit + :input-buffer "abc" + :input-context nil} (key-msg :backspace))] + (is (= "ab" (:input-buffer model)))))) + +(deftest test-update-commits-tabs + (testing "] switches to reflog tab in commits panel" + (let [[model _] (core/update-model {:panel :commits + :commits-tab :commits + :cursor 0 + :commits [] + :reflog []} (key-msg \]))] + (is (= :reflog (:commits-tab model))))) + + (testing "[ switches to commits tab in commits panel" + (let [[model _] (core/update-model {:panel :commits + :commits-tab :reflog + :cursor 0 + :commits [] + :reflog []} (key-msg \[))] + (is (= :commits (:commits-tab model)))))) + +(deftest test-update-branches-tabs + (testing "] cycles branches tabs forward" + (let [[model _] (core/update-branches {:branches-tab :local + :cursor 0 + :branches []} (key-msg \]))] + (is (= :remotes (:branches-tab model)))) + + (let [[model _] (core/update-branches {:branches-tab :remotes + :cursor 0 + :remote-branches []} (key-msg \]))] + (is (= :tags (:branches-tab model)))) + + (let [[model _] (core/update-branches {:branches-tab :tags + :cursor 0 + :tags []} (key-msg \]))] + (is (= :local (:branches-tab model))))) + + (testing "[ cycles branches tabs backward" + (let [[model _] (core/update-branches {:branches-tab :local + :cursor 0 + :tags []} (key-msg \[))] + (is (= :tags (:branches-tab model)))))) + +(deftest test-update-stash-menu + (testing "escape closes stash menu" + (let [[model _] (core/update-stash-menu {:menu-mode :stash-options} (key-msg :escape))] + (is (nil? (:menu-mode model)))))) + +(deftest test-update-reset-menu + (testing "escape closes reset menu" + (let [[model _] (core/update-reset-menu {:menu-mode :reset-options} (key-msg :escape))] + (is (nil? (:menu-mode model)))))) + +(deftest test-update-help + (testing "escape closes help" + (let [[model _] (core/update-help {:menu-mode :help} (key-msg :escape))] + (is (nil? (:menu-mode model))))) + + (testing "q closes help" + (let [[model _] (core/update-help {:menu-mode :help} (key-msg \q))] + (is (nil? (:menu-mode model))))) + + (testing "? closes help" + (let [[model _] (core/update-help {:menu-mode :help} (key-msg \?))] + (is (nil? (:menu-mode model)))))) + +;; Run tests when executed directly +(defn -main [& args] + (clojure.test/run-tests 'lazygitclj.core-test)) diff --git a/test/lazygitclj/git_test.clj b/test/lazygitclj/git_test.clj new file mode 100644 index 0000000..98ced4c --- /dev/null +++ b/test/lazygitclj/git_test.clj @@ -0,0 +1,323 @@ +(ns lazygitclj.git-test + "Unit tests for lazygitclj.git namespace" + (:require [clojure.test :refer [deftest testing is use-fixtures]] + [lazygitclj.git :as git] + [clojure.string :as str] + [babashka.process :refer [shell]])) + +;; === Test Fixtures === + +(def ^:dynamic *test-repo* nil) + +(defn- sh [& args] + (try + (-> (apply shell {:out :string :err :string :dir *test-repo*} args) + :out + str/trim-newline) + (catch Exception _ nil))) + +(defn create-test-repo [] + (let [repo-dir (str "/tmp/lazygitclj-unit-test-" (System/currentTimeMillis))] + (shell "mkdir" "-p" repo-dir) + (shell {:dir repo-dir} "git" "init" "-b" "main") + (shell {:dir repo-dir} "git" "config" "user.email" "test@example.com") + (shell {:dir repo-dir} "git" "config" "user.name" "Test User") + ;; Create initial files + (spit (str repo-dir "/README.md") "# Test Project\n") + (spit (str repo-dir "/file1.txt") "line1\n") + (shell {:dir repo-dir} "git" "add" ".") + (shell {:dir repo-dir} "git" "commit" "-m" "Initial commit") + repo-dir)) + +(defn delete-test-repo [repo-dir] + (shell "rm" "-rf" repo-dir)) + +(defn with-test-repo [f] + (let [repo-dir (create-test-repo)] + (try + (binding [*test-repo* repo-dir] + ;; Change to test repo for git commands + (let [original-dir (System/getProperty "user.dir")] + (System/setProperty "user.dir" repo-dir) + (try + (f) + (finally + (System/setProperty "user.dir" original-dir))))) + (finally + (delete-test-repo repo-dir))))) + +(use-fixtures :each with-test-repo) + +;; === Status Tests === + +(deftest test-current-branch + (testing "returns current branch name" + (is (= "main" (sh "git" "branch" "--show-current"))))) + +(deftest test-head-sha + (testing "returns short SHA of HEAD" + (let [sha (sh "git" "rev-parse" "--short" "HEAD")] + (is (string? sha)) + (is (>= (count sha) 7))))) + +(deftest test-repo-root + (testing "returns repo root directory" + (let [root (sh "git" "rev-parse" "--show-toplevel")] + (is (string? root)) + (is (str/starts-with? root "/tmp/lazygitclj-unit-test-"))))) + +;; === File Status Tests === + +(deftest test-staged-files + (testing "returns empty list when nothing staged" + ;; Modify file but don't stage + (spit (str *test-repo* "/file1.txt") "modified\n") + (let [staged (git/staged-files)] + (is (empty? staged)))) + + (testing "returns staged files after git add" + (spit (str *test-repo* "/file1.txt") "modified\n") + (sh "git" "add" "file1.txt") + (let [staged (git/staged-files)] + (is (= 1 (count staged))) + (is (= "file1.txt" (:path (first staged))))))) + +(deftest test-unstaged-files + (testing "returns modified unstaged files" + (spit (str *test-repo* "/file1.txt") "modified\n") + (let [unstaged (git/unstaged-files)] + (is (= 1 (count unstaged))) + (is (= "file1.txt" (:path (first unstaged)))))) + + (testing "returns untracked files" + (spit (str *test-repo* "/newfile.txt") "new content\n") + (let [unstaged (git/unstaged-files)] + (is (some #(= "newfile.txt" (:path %)) unstaged))))) + +;; === Branch Tests === + +(deftest test-branches + (testing "returns list of local branches" + (let [branches (git/branches)] + (is (vector? branches)) + (is (some #(= "main" %) branches)))) + + (testing "includes newly created branches" + (sh "git" "branch" "feature-branch") + (let [branches (git/branches)] + (is (some #(= "feature-branch" %) branches))))) + +(deftest test-create-branch + (testing "creates a new branch and switches to it" + (git/create-branch "new-feature") + (is (= "new-feature" (sh "git" "branch" "--show-current"))))) + +(deftest test-checkout-branch + (testing "switches to existing branch" + (sh "git" "branch" "other-branch") + (git/checkout-branch "other-branch") + (is (= "other-branch" (sh "git" "branch" "--show-current"))))) + +(deftest test-delete-branch + (testing "deletes a branch" + (sh "git" "branch" "to-delete") + (git/delete-branch "to-delete") + (let [branches (git/branches)] + (is (not (some #(= "to-delete" %) branches)))))) + +(deftest test-rename-branch + (testing "renames a branch" + (sh "git" "branch" "old-name") + (git/rename-branch "old-name" "new-name") + (let [branches (git/branches)] + (is (some #(= "new-name" %) branches)) + (is (not (some #(= "old-name" %) branches)))))) + +;; === Staging Tests === + +(deftest test-stage-file + (testing "stages a modified file" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/stage-file "file1.txt") + (let [staged (git/staged-files)] + (is (= 1 (count staged)))))) + +(deftest test-unstage-file + (testing "unstages a staged file" + (spit (str *test-repo* "/file1.txt") "modified\n") + (sh "git" "add" "file1.txt") + (git/unstage-file "file1.txt") + (let [staged (git/staged-files)] + (is (empty? staged))))) + +(deftest test-stage-all + (testing "stages all changed files" + (spit (str *test-repo* "/file1.txt") "modified\n") + (spit (str *test-repo* "/newfile.txt") "new\n") + (git/stage-all) + (let [staged (git/staged-files)] + (is (= 2 (count staged)))))) + +;; === Commit Tests === + +(deftest test-commit + (testing "creates a commit with message" + (spit (str *test-repo* "/file1.txt") "modified\n") + (sh "git" "add" ".") + (git/commit "Test commit message") + (let [log (sh "git" "log" "--oneline" "-1")] + (is (str/includes? log "Test commit message"))))) + +(deftest test-recent-commits + (testing "returns recent commits" + (let [commits (git/recent-commits 5)] + (is (seq commits)) + (is (= "Initial commit" (:subject (first commits))))))) + +;; === Stash Tests === + +(deftest test-stash-all + (testing "stashes all changes" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/stash-all) + (let [stashes (git/stash-list)] + (is (= 1 (count stashes)))) + ;; Working tree should be clean + (let [unstaged (git/unstaged-files)] + (is (empty? unstaged))))) + +(deftest test-stash-pop + (testing "pops stash and removes it from list" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/stash-all) + (git/stash-pop) + (let [stashes (git/stash-list) + unstaged (git/unstaged-files)] + (is (empty? stashes)) + (is (= 1 (count unstaged)))))) + +(deftest test-stash-apply + (testing "applies stash but keeps it in list" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/stash-all) + (git/stash-apply) + (let [stashes (git/stash-list) + unstaged (git/unstaged-files)] + (is (= 1 (count stashes))) + (is (= 1 (count unstaged)))))) + +(deftest test-stash-drop + (testing "drops stash from list" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/stash-all) + (git/stash-drop) + (let [stashes (git/stash-list)] + (is (empty? stashes))))) + +;; === Reset Tests === + +(deftest test-discard-file + (testing "discards unstaged changes to a file" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/discard-file "file1.txt") + (let [content (slurp (str *test-repo* "/file1.txt"))] + (is (= "line1\n" content))))) + +(deftest test-discard-all-unstaged + (testing "discards all unstaged changes" + (spit (str *test-repo* "/file1.txt") "modified\n") + (git/discard-all-unstaged) + (let [unstaged (git/unstaged-files)] + (is (empty? unstaged))))) + +(deftest test-reset-staged + (testing "unstages all staged files" + (spit (str *test-repo* "/file1.txt") "modified\n") + (sh "git" "add" ".") + (git/reset-staged) + (let [staged (git/staged-files)] + (is (empty? staged))))) + +;; === Tag Tests === + +(deftest test-list-tags + (testing "returns empty list when no tags" + (let [tags (git/list-tags)] + (is (empty? tags)))) + + (testing "returns tags after creating one" + (sh "git" "tag" "v1.0.0") + (let [tags (git/list-tags)] + (is (some #(= "v1.0.0" %) tags))))) + +(deftest test-create-tag + (testing "creates a tag" + (git/create-tag "v2.0.0") + (let [tags (git/list-tags)] + (is (some #(= "v2.0.0" %) tags))))) + +(deftest test-delete-tag + (testing "deletes a tag" + (sh "git" "tag" "to-delete") + (git/delete-tag "to-delete") + (let [tags (git/list-tags)] + (is (not (some #(= "to-delete" %) tags)))))) + +;; === Reflog Tests === + +(deftest test-reflog + (testing "returns reflog entries" + (let [reflog (git/reflog 10)] + (is (seq reflog)) + (is (every? :sha reflog)) + (is (every? :ref reflog))))) + +;; === Cherry-pick and Revert Tests === + +(deftest test-cherry-pick-commit + (testing "cherry-picks a commit" + ;; Create a branch with a commit + (sh "git" "checkout" "-b" "feature") + (spit (str *test-repo* "/feature.txt") "feature content\n") + (sh "git" "add" ".") + (sh "git" "commit" "-m" "Feature commit") + (let [feature-sha (sh "git" "rev-parse" "--short" "HEAD")] + ;; Go back to main + (sh "git" "checkout" "main") + ;; Cherry-pick + (git/cherry-pick-commit feature-sha) + ;; Verify file exists + (is (.exists (java.io.File. (str *test-repo* "/feature.txt"))))))) + +(deftest test-revert-commit + (testing "reverts a commit" + ;; Make a change and commit + (spit (str *test-repo* "/file1.txt") "modified\n") + (sh "git" "add" ".") + (sh "git" "commit" "-m" "Change to revert") + (let [sha (sh "git" "rev-parse" "--short" "HEAD")] + ;; Revert it + (git/revert-commit sha) + ;; Verify content is back to original + (let [content (slurp (str *test-repo* "/file1.txt"))] + (is (= "line1\n" content)))))) + +;; === Merge Tests === + +(deftest test-merge-branch + (testing "merges a branch into current" + ;; Create feature branch with changes + (sh "git" "checkout" "-b" "to-merge") + (spit (str *test-repo* "/merged.txt") "merged content\n") + (sh "git" "add" ".") + (sh "git" "commit" "-m" "Merge commit") + ;; Go back to main + (sh "git" "checkout" "main") + ;; Merge + (git/merge-branch "to-merge") + ;; Verify file exists on main + (is (.exists (java.io.File. (str *test-repo* "/merged.txt")))))) + +;; Run tests when executed directly +(defn -main [& args] + (clojure.test/run-tests 'lazygitclj.git-test)) diff --git a/test/run-tests.clj b/test/run-tests.clj new file mode 100644 index 0000000..c3d9e0f --- /dev/null +++ b/test/run-tests.clj @@ -0,0 +1,22 @@ +#!/usr/bin/env bb +;; Run all unit tests for lazygitclj + +(require '[clojure.test :as t]) + +;; Add test path +(require '[babashka.classpath :refer [add-classpath]]) +(add-classpath "test") + +;; Load test namespaces +(require 'lazygitclj.core-test) + +(println "") +(println "Running lazygitclj unit tests...") +(println "================================") + +(let [summary (t/run-tests 'lazygitclj.core-test)] + (println "") + (println "================================") + (when (or (pos? (:fail summary)) + (pos? (:error summary))) + (System/exit 1)))