Keep `forgit add` on the porcelain `git status --porcelain -zs` path so
filenames containing backslashes continue to work, while restoring the
behaviors that regressed when we moved away from Git's cwd-relative output.
This change makes the status picker emit a display label and a hidden
absolute-path payload separately. That lets the UI keep showing intuitive
cwd-relative paths, while preview, edit, and add actions operate on the real
path instead of reparsing the rendered status line. As a result, untracked
files, subdirectory workflows, and special filenames now share one consistent
path flow.
It also restores the old-Git fallback for plain `?? path` output before status
filtering, raises the required fzf version for `--accept-nth`, and adds
regression coverage for backslashes, spaces, tabs, subdirectory entries,
sibling directories, and logical symlink paths.
We explored a few alternatives before landing here. Keeping a single
human-readable line and reparsing it downstream remained too fragile for
quoted paths and backslashes. Shell-only display-path rewriting worked for
some cases but stayed brittle across logical vs physical paths and still
failed in macOS CI. A per-path `realpath` approach would have been easier to
read, but GNU-style relative-path support is not portable across the
platforms we test and would add one external process per file in a hot path.
The final tradeoff keeps the pipeline batch-oriented and portable by doing
the path normalization once in a single helper step, even though that is less
lightweight than the earlier shell-only versions. That complexity is
justified here because it fixes the old-Git untracked regression, preserves
correct preview/add behavior from subdirectories, and avoids reintroducing
long-standing filename parsing bugs.
Git escapes backslashes with `git status` even when
`core.quotepath=false` is set. Use `--porcelain -z` with `git status` as
a more robust approach to fix this.
Fixes#467
When users configure a TUI/interactive diff pager (e.g., diffnav, tig)
via `git config pager.diff`, fzf preview panes show blank output because
TUI pagers require a TTY that fzf previews don't provide.
Add FORGIT_PREVIEW_PAGER env var that overrides the diff pager only in
fzf preview context. Preview detection relies on a FORGIT_IN_PREVIEW
marker set by a new `_forgit_preview` wrapper, so the override applies
only to preview commands and leaves fullscreen behavior unchanged.
Fixes#491
Add `gwa` command for interactively creating git worktrees with
fzf-powered branch selection.
Usage:
- `gwa`: select a branch to create a worktree for
- `gwa <new-branch>`: create a new branch from a selected base branch
- 2+ args: fall back to `git worktree add` directly
New worktrees are created under `$FORGIT_WORKTREE_ADD_DIR` (defaults to
`<repo-root>/.wt/`) and the shell automatically cd's into the result.
- Extract dim formatting into _forgit_print_dim() to replace hardcoded
ANSI sequences in _forgit_branch_list()
- Add empty state check and alt-l lock toggle reload for worktree delete
- Fix worktree path completion to handle paths with spaces using -z flag
- Add worktree command completion for bash and zsh
Add worktree browser (gwt) and worktree delete selector (gwd) with:
- Interactive worktree list with lock status, branch info, and age
- Preview showing working tree status and recent commits
- Ctrl-Y to copy worktree path, Alt-L to toggle lock/unlock
- Shell integration for zsh (with cd) and fish (with cd)
- Tab completions for zsh, bash, and fish
- Documentation in README with keybindings and options
Co-Authored-By: Sufien Tout <sufientout@gmail.com>
- Add _forgit_strip_ansi for removing ANSI escape codes
- Add _forgit_branch_list to list branches with current branch first
- Add _forgit_extract_branch_name to parse branch names from git output
- Update checkout_branch, switch_branch, branch_delete, cherry_pick_from_branch,
and branch_preview to use the new helpers
- Fix _forgit_inside_work_tree to suppress stderr
Show informative messages when there is nothing to checkout:
- checkout_file: "Nothing to checkout." when no modified files
- checkout_tag: "Nothing to checkout: there are no tags."
This is a breaking change: flag arguments provided to forgit clean are
now passed to git ls-files instead of git clean -n. This change is
necessary because git clean does not have a -z option that would prevent
it from escaping file names containing backslashes. However, git ls-files
is way more flexible than git clean, so all use cases covered by git
clean (and more) should still be possible.
Pass the value of git config status.showUntrackedFiles to the git status
command we run in _forgit_add, defaulting to 'all' when unset.
Additionally correctly handle directories in _forgit_add_preview for the
case when status.showUntracked is explicitly set to 'normal'.
git status includes untracked files by default, so passing the flag
explicitly is not necessary. This allows overriding forgits behavior
by setting showUntrackedFiles = no in the .gitconfig.
Instead of using `git stash show` in the `enter` binding of the
`stash_show` command, use `forgit show`. This allows forgit to show the
stash in the same interactive way it shows other commits (e.g. on
`forgit log`), with the same context and formatting options.
If non-option arguments are passed to `git forgit rebase`, pass them
through directly to `git rebase`, without launching the interactive
selector, just like we do for other forgit commands.
Along with this, remove possibility to pass files to rebase, as there is
no need for that. I assume this was a copy-paste error when the
rebase function was introduced in the first place.
Introducing `show` as a new subcommand of `forgit`, an interactive
version of `git show`. The configured default alias is `gso`.
Alt-T can be used to toggle between showing the diff and the commit
message in the fzf preview window.
The new command in used instead of `forgit diff` when pressing enter
in `forgit log`. This fixes the display of diffs for merge commits.
**Note**: we have a requirement for the `fzf` version now. The minimum
required `fzf` version is 0.49.0. If the installed version is lower,
forgit will exit with an error message.
Fixes#416.
The key binding for editing a file in diff and add was not working
properly on recent versions of fzf. As its documentation suggests, we
should replace `execute-silent` with `execute` since we need to switch
to a new screen and handle both input and output.
> fzf switches to the alternate screen when executing a command.
> However, if the command is expected to complete quickly, and you are
> not interested in its output, you might want to use execute-silent
> instead, which silently executes the command without the switching.
Git escapes special characters in it's output when core.quotePath is
true or unset. Git always expects unquoted file paths as input. This
leads to issues when we consume output from git and use it to build
input for other git commands. This commit ensures we always feed unqoted
paths to git commands.
The _forgit_list_files function is introduced to handle usage of git
ls-files with the -z flag, which ensures unquoted paths.
It replaces the direct calls to git ls-files in _forgit_reset_head,
_forgit_stash_push and _forgit_checkout_file.
In _git_reset_head the -z option is added to the git diff command to
ensure unqoted paths.
Since git clean does not support the -z flag, we disable core.quotePath
by passing a configuration parameter in _forgit_clean. The same is done for
_forgit_add.
When trying to open a file from gd in $EDITOR (alt + e) the wrong file
was being opened when the command wasn't executed from the repository's
root directory.