mirror of
https://github.com/wfxr/forgit.git
synced 2026-09-10 07:16:23 -04:00
feat: resolve a relative FORGIT_WORKTREE_ADD_DIR per repository
A relative FORGIT_WORKTREE_ADD_DIR is resolved against the root of the main worktree on every invocation, so a single setting such as `.worktrees` is valid in every repository. Absolute paths keep their meaning. The variable previously only took a full path, so users resolved the repository root in their shell startup files, which runs git outside a repository on every new shell and freezes the path for the whole session.
This commit is contained in:
parent
d7d53288f9
commit
4f884bd9bd
|
|
@ -381,7 +381,7 @@ export FORGIT_LOG_FZF_OPTS='
|
|||
| `FORGIT_FULLSCREEN_CONTEXT` | lines of diff context in full-screen mode | 10 |
|
||||
| `FORGIT_DIR_VIEW` | command used to preview directories | `tree` if available, otherwise `find` |
|
||||
| `FORGIT_CLEAN_LIST_FILES_OPTS` | arguments passed to `git ls-files` together with `--others` to determine which files are shown when invoking `forgit clean` | |
|
||||
| `FORGIT_WORKTREE_ADD_DIR` | directory where new worktrees are created | `<repo-root>/.wt` |
|
||||
| `FORGIT_WORKTREE_ADD_DIR` | directory where new worktrees are created (a relative path is resolved against the main worktree root) | `.wt` |
|
||||
| `FORGIT_CHECKOUT_BRANCH_AUTO_CREATE_BRANCH` | prevents forgit from auto creating a new branch with `gcb <BRANCH_NAME>` when `<BRANCH_NAME>` does not exist when set to `false` | |
|
||||
| `FORGIT_SWITCH_AUTO_CREATE_BRANCH` | prevents forgit from auto creating a new branch with `gsw <BRANCH_NAME>` when `<BRANCH_NAME>` does not exist when set to `false` | |
|
||||
|
||||
|
|
|
|||
|
|
@ -1583,6 +1583,20 @@ _forgit_main_worktree_root() {
|
|||
git worktree list --porcelain | sed -n 's/^worktree //p;q'
|
||||
}
|
||||
|
||||
# Get the directory in which new worktrees are created
|
||||
# A relative FORGIT_WORKTREE_ADD_DIR is resolved against the root of the main
|
||||
# worktree, so that a single setting is valid in every repository. Anchoring it
|
||||
# to the main worktree rather than the current one also keeps adding a worktree
|
||||
# from a linked worktree from nesting the directory any deeper.
|
||||
_forgit_worktree_add_dir() {
|
||||
local dir="${FORGIT_WORKTREE_ADD_DIR:-.wt}"
|
||||
if [[ $dir == /* ]]; then
|
||||
echo "$dir"
|
||||
else
|
||||
echo "$(_forgit_main_worktree_root)/$dir"
|
||||
fi
|
||||
}
|
||||
|
||||
# Parse git worktree list --porcelain output and format it for display
|
||||
# Output format: [XY] /path/to/worktree (branch) 3 hours ago
|
||||
# X: '*' = current worktree, ' ' = other
|
||||
|
|
@ -1740,8 +1754,8 @@ _forgit_worktree_delete() {
|
|||
_forgit_worktree_add() {
|
||||
_forgit_inside_git_repo || return 1
|
||||
|
||||
# Default to main worktree root, not current worktree's root
|
||||
local wt_dir="${FORGIT_WORKTREE_ADD_DIR:-$(_forgit_main_worktree_root)/.wt}"
|
||||
local wt_dir
|
||||
wt_dir=$(_forgit_worktree_add_dir)
|
||||
|
||||
# Two or more arguments: pass through to git directly
|
||||
if [[ $# -ge 2 ]]; then
|
||||
|
|
|
|||
49
tests/worktree.test.sh
Normal file
49
tests/worktree.test.sh
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
function set_up_before_script() {
|
||||
source bin/git-forgit
|
||||
|
||||
# Ignore global git config files
|
||||
export GIT_CONFIG_SYSTEM=/dev/null
|
||||
export GIT_CONFIG_GLOBAL=/dev/null
|
||||
|
||||
unset FORGIT_WORKTREE_ADD_DIR
|
||||
|
||||
# Create a temporary git repository for testing
|
||||
MAIN_WORKTREE_ROOT="$(bashunit::temp_dir)/main"
|
||||
git init -q "$MAIN_WORKTREE_ROOT"
|
||||
cd "$MAIN_WORKTREE_ROOT" || return 1
|
||||
git config user.email "test@example.com"
|
||||
git config user.name "Test User"
|
||||
echo "initial" >README.md
|
||||
git add README.md
|
||||
git commit -q -m "Initial commit"
|
||||
}
|
||||
|
||||
function test_worktree_add_dir_defaults_to_dot_wt_in_main_worktree_root() {
|
||||
assert_same "$MAIN_WORKTREE_ROOT/.wt" "$(_forgit_worktree_add_dir)"
|
||||
}
|
||||
|
||||
function test_worktree_add_dir_resolves_a_relative_path_against_main_worktree_root() {
|
||||
assert_same "$MAIN_WORKTREE_ROOT/.worktrees" \
|
||||
"$(FORGIT_WORKTREE_ADD_DIR=.worktrees _forgit_worktree_add_dir)"
|
||||
}
|
||||
|
||||
function test_worktree_add_dir_resolves_a_nested_relative_path() {
|
||||
assert_same "$MAIN_WORKTREE_ROOT/build/wt" \
|
||||
"$(FORGIT_WORKTREE_ADD_DIR=build/wt _forgit_worktree_add_dir)"
|
||||
}
|
||||
|
||||
function test_worktree_add_dir_uses_an_absolute_path_as_is() {
|
||||
assert_same "/somewhere/else" \
|
||||
"$(FORGIT_WORKTREE_ADD_DIR=/somewhere/else _forgit_worktree_add_dir)"
|
||||
}
|
||||
|
||||
function test_worktree_add_dir_resolves_a_relative_path_from_a_linked_worktree() {
|
||||
local linked_worktree="$MAIN_WORKTREE_ROOT/.worktrees/linked"
|
||||
git worktree add -q -b linked "$linked_worktree" >/dev/null 2>&1
|
||||
cd "$linked_worktree" || return 1
|
||||
|
||||
assert_same "$MAIN_WORKTREE_ROOT/.worktrees" \
|
||||
"$(FORGIT_WORKTREE_ADD_DIR=.worktrees _forgit_worktree_add_dir)"
|
||||
}
|
||||
Loading…
Reference in a new issue