Stop at top level .git in project.sh

This commit is contained in:
2026-06-29 15:46:36 +01:00
parent 95e9fcfbcb
commit 7bb0131ad4

View File

@@ -6,7 +6,7 @@ projects_dir=$HOME/Projects
# Print the sorted, de-duplicated list of selectable projects.
list_projects() {
local projects=() dir relative line
local projects=() dir relative git_dirs kept_roots=() root kept
# All depth-2 directories without @ are included unconditionally
for dir in "$projects_dir"/*/*/; do
@@ -16,22 +16,30 @@ list_projects() {
[[ "$relative" != *@* ]] && projects+=("$relative")
done
# For @ directories, only include those with .git
# For @ directories, only show the top-most directory that holds a .git
# entry. Sorting makes every parent precede its descendants, so once a root
# is kept we drop anything nested beneath it — typically a git submodule —
# while separate clones and worktrees, each in their own directory, survive.
if command -v fd &>/dev/null; then
while IFS= read -r line; do
projects+=("$line")
done < <(fd -H '^\.git$' "$projects_dir" |
grep '@' |
sed -E -e "s|^$projects_dir/||" -e 's|/\.git/?$||')
git_dirs=$(fd -H '^\.git$' "$projects_dir" || true)
else
while IFS= read -r line; do
projects+=("$line")
done < <(find "$projects_dir" \( -name 'node_modules' -o -name '.git' \) \
-prune -name '.git' -print |
grep '@' |
sed -E -e "s|^$projects_dir/||" -e 's|/\.git/?$||')
git_dirs=$(find "$projects_dir" \( -name 'node_modules' -o -name '.git' \) \
-prune -name '.git' -print || true)
fi
while IFS= read -r root; do
for kept in "${kept_roots[@]}"; do
if [[ "$root" == "$kept/"* ]]; then
continue 2
fi
done
kept_roots+=("$root")
projects+=("$root")
done < <(printf '%s\n' "$git_dirs" |
grep '@' |
sed -E -e "s|^$projects_dir/||" -e 's|/\.git/?$||' |
sort -u)
printf '%s\n' "${projects[@]}" | sort -u
}