Getting the top-level directory of the relevant git worktree
#!/usr/bin/env bash
# set up a dummy repo
set -euo pipefail
experiment_dir="$(mktemp -d --tmpdir test_repo.XXX)"
git clone --recurse-submodules git@github.com:SKalt/dummy_repo.git "$experiment_dir"
cd "$experiment_dir"
git pull --recurse-submodules=yes
git checkout -b brnch && git checkout - # set up a dummy branch
git worktree add wrktr brnch # add a wortree
cd wrktr && git submodule update --init --recursive # init the recursive submodules in the worktree
.
├── LICENSE
├── nested
│ └── file.txt
├── README.md
├── submod
│ ├── LICENSE
│ ├── nested
│ │ └── file.txt
│ ├── README.md
│ └── submod
│ ├── LICENSE
│ ├── nested
│ │ └── file.txt
│ └── README.md
└── wrktr
├── LICENSE
├── nested
│ └── file.txt
├── README.md
└── submod
├── LICENSE
├── nested
│ └── file.txt
├── README.md
└── submod
├── LICENSE
├── nested
│ └── file.txt
└── README.md
11 directories, 18 files
./.git
├── branches
├── config
├── description
├── HEAD
├── hooks/...
├── index
├── info/...
├── logs/...
├── modules
│ └── submod
│ ├── branches
│ ├── config
│ ├── description
│ ├── HEAD
│ ├── hooks/...
│ ├── index
│ ├── info/...
│ ├── logs/...
│ ├── modules
│ │ └── submod
│ │ ├── branches
│ │ ├── config # <- contains relative path in core.worktree
│ │ ├── description
│ │ ├── HEAD
│ │ ├── hooks/...
│ │ ├── index
│ │ ├── info/...
│ │ ├── logs/...
│ │ ├── objects/...
│ │ ├── packed-refs
│ │ └── refs/...
│ ├── objects/...
│ ├── packed-refs
│ └── refs/...
├── objects/...
├── packed-refs
├── refs
│ ├── heads
│ │ ├── brnch
│ │ └── main
│ ├── remotes
│ │ └── origin
│ │ └── HEAD
│ └── tags
└── worktrees
└── wrktr
├── commondir
├── gitdir
├── HEAD
├── index
├── logs
│ └── HEAD
├── modules
│ └── submod
│ ├── branches
│ ├── config
│ ├── description
│ ├── HEAD
│ ├── hooks/...
│ ├── index
│ ├── info/...
│ ├── logs/...
│ ├── modules
│ │ └── submod
│ │ ├── branches
│ │ ├── config
│ │ ├── description
│ │ ├── HEAD
│ │ ├── hooks/...
│ │ ├── index
│ │ ├── info/...
│ │ ├── logs/...
│ │ ├── objects/...
│ │ ├── packed-refs
│ │ └── refs/...
│ ├── objects/...
│ ├── packed-refs
│ └── refs/...
└── ORIG_HEAD
91 directories, 133 files
args=(
--git-common-dir
--git-dir
--is-inside-git-dir
--is-inside-work-tree
--show-toplevel
);
padding() {
local delimiter="$1" # must be 1ch
local message="$2"
local width="${3:-78}"
printf -- "${delimiter}%.0s" $(seq 0 $(($width - ${#message})))
}
header() {
message="$(printf "%s " "$1")"
echo
printf "%s" "$message"; padding "#" "$message"; echo
echo
}
indent() {
padding " " "$1" 22;
printf "%s = " "$1";
}
explore() {
local to_explore="$1"
{
cd "$to_explore"
header "$to_explore"
for arg in "${args[@]}"; do
indent "$arg";
git --no-pager rev-parse "$arg" 2>&1 || true;
done
indent "config#core.worktree"
git --no-pager config core.worktree || echo "<missing>"
indent "./config#core.worktree" 22
if [ -f ./config ]; then
git --no-pager config --file ${PWD}/config core.worktree || echo "<missing>"
else
echo
fi
indent "./gitdir"
if [ -f ./gitdir ]; then
cat ./gitdir;
else
echo
fi
} | sed 's/^/# /g' | sed "s#${PWD}#\${PWD}#g"
}
paths_to_explore=(
"${PWD}"
"${PWD}/nested"
"${PWD}/.git"
"${PWD}/.git/worktrees"
"${PWD}/.git/worktrees/wrktr"
"${PWD}/.git/worktrees/wrktr/modules/submod"
"${PWD}/wrktr"
"${PWD}/wrktr/submod"
"${PWD}/submod"
"${PWD}/.git/modules/submod"
)
for p in "${paths_to_explore[@]}"; do explore "$p"; done
#
# ${PWD} ############################################################
#
# --git-common-dir = .git
# --git-dir = .git
# --is-inside-git-dir = false
# --is-inside-work-tree = true
# --show-toplevel = ${PWD}
# config#core.worktree = <missing>
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/nested #####################################################
#
# --git-common-dir = ../.git
# --git-dir = ${PWD}/.git
# --is-inside-git-dir = false
# --is-inside-work-tree = true
# --show-toplevel = ${PWD}
# config#core.worktree = <missing>
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/.git #######################################################
#
# --git-common-dir = .
# --git-dir = .
# --is-inside-git-dir = true
# --is-inside-work-tree = false
# --show-toplevel = fatal: this operation must be run in a work tree
# config#core.worktree = <missing>
# ./config#core.worktree = <missing>
# ./gitdir =
#
# ${PWD}/.git/worktrees #############################################
#
# --git-common-dir = ${PWD}/.git
# --git-dir = ${PWD}/.git
# --is-inside-git-dir = true
# --is-inside-work-tree = false
# --show-toplevel = fatal: this operation must be run in a work tree
# config#core.worktree = <missing>
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/.git/worktrees/wrktr #######################################
#
# --git-common-dir = ${PWD}/.git
# --git-dir = .
# --is-inside-git-dir = true
# --is-inside-work-tree = false
# --show-toplevel = fatal: this operation must be run in a work tree
# config#core.worktree = <missing>
# ./config#core.worktree =
# ./gitdir = ${PWD}/wrktr/.git
#
# ${PWD}/.git/worktrees/wrktr/modules/submod ########################
#
# --git-common-dir = .
# --git-dir = .
# --is-inside-git-dir = false
# --is-inside-work-tree = false
# --show-toplevel = ${PWD}/wrktr/submod
# config#core.worktree = ../../../../../wrktr/submod
# ./config#core.worktree = ../../../../../wrktr/submod
# ./gitdir =
#
# ${PWD}/wrktr ######################################################
#
# --git-common-dir = ${PWD}/.git
# --git-dir = ${PWD}/.git/worktrees/wrktr
# --is-inside-git-dir = false
# --is-inside-work-tree = true
# --show-toplevel = ${PWD}/wrktr
# config#core.worktree = <missing>
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/wrktr/submod ###############################################
#
# --git-common-dir = ${PWD}/.git/worktrees/wrktr/modules/submod
# --git-dir = ${PWD}/.git/worktrees/wrktr/modules/submod
# --is-inside-git-dir = false
# --is-inside-work-tree = true
# --show-toplevel = ${PWD}/wrktr/submod
# config#core.worktree = ../../../../../wrktr/submod
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/submod #####################################################
#
# --git-common-dir = ${PWD}/.git/modules/submod
# --git-dir = ${PWD}/.git/modules/submod
# --is-inside-git-dir = false
# --is-inside-work-tree = true
# --show-toplevel = ${PWD}/submod
# config#core.worktree = ../../../submod
# ./config#core.worktree =
# ./gitdir =
#
# ${PWD}/.git/modules/submod ########################################
#
# --git-common-dir = .
# --git-dir = .
# --is-inside-git-dir = false
# --is-inside-work-tree = false
# --show-toplevel = ${PWD}/submod
# config#core.worktree = ../../../submod
# ./config#core.worktree = ../../../submod
# ./gitdir =
explore_tab() {
local to_explore="$1"
{
cd "$to_explore"
printf '|`%s`' "$to_explore"
for arg in "${args[@]}"; do
_result="$(git --no-pager rev-parse "$arg" 2>&1 || true)"
printf '|`%s`' "$_result"
done
# config#core.worktree
printf '|`%s`' "$(git --no-pager config core.worktree || echo "<missing>")"
# ./config#core.worktree
printf '|'
if [ -f ./config ]; then
printf '`%s`' "$(
git --no-pager config --file ${PWD}/config core.worktree || echo "<missing>"
)"
fi
# ./gitdir
printf "|"
if [ -f ./gitdir ]; then
printf '`%s`' "$(cat ./gitdir)";
fi
echo "|"
}
}
_headers=(
"pwd"
"${args[@]}"
"config#core.worktree"
./config#core.worktree
./gitdir
)
for i in "${_headers[@]}"; do printf '|`%s`' "$i"; done
echo "|"
for i in "${_headers[@]}"; do printf "|-"; done
echo "|"
for p in "${paths_to_explore[@]}"; do
explore_tab "$p" | sed "s#${PWD}#\${PWD}#g";
done
pwd | --git-common-dir | --git-dir | --is-inside-git-dir | --is-inside-work-tree | --show-toplevel | config#core.worktree | ./config#core.worktree | ./gitdir |
|---|
${PWD} | .git | .git | false | true | ${PWD} | <missing> | | |
${PWD}/nested | ../.git | ${PWD}/.git | false | true | ${PWD} | <missing> | | |
${PWD}/.git | . | . | true | false | fatal: this operation must be run in a work tree | <missing> | <missing> | |
${PWD}/.git/worktrees | ${PWD}/.git | ${PWD}/.git | true | false | fatal: this operation must be run in a work tree | <missing> | | |
${PWD}/.git/worktrees/wrktr | ${PWD}/.git | . | true | false | fatal: this operation must be run in a work tree | <missing> | | ${PWD}/wrktr/.git |
${PWD}/.git/worktrees/wrktr/modules/submod | . | . | false | false | ${PWD}/wrktr/submod | ../../../../../wrktr/submod | ../../../../../wrktr/submod | |
${PWD}/wrktr | ${PWD}/.git | ${PWD}/.git/worktrees/wrktr | false | true | ${PWD}/wrktr | <missing> | | |
${PWD}/wrktr/submod | ${PWD}/.git/worktrees/wrktr/modules/submod | ${PWD}/.git/worktrees/wrktr/modules/submod | false | true | ${PWD}/wrktr/submod | ../../../../../wrktr/submod | | |
${PWD}/submod | ${PWD}/.git/modules/submod | ${PWD}/.git/modules/submod | false | true | ${PWD}/submod | ../../../submod | | |
${PWD}/.git/modules/submod | . | . | false | false | ${PWD}/submod | ../../../submod | ../../../submod | |
pwd | --git-common-dir | --git-dir | --is-inside-git-dir | --is-inside-work-tree | --show-toplevel | config#core.worktree | ./config#core.worktree | ./gitdir |
|---|
${PWD}/.git | . | . | true | false | fatal: this operation must be run in a work tree | <missing> | <missing> | |
${PWD}/.git/worktrees | ${PWD}/.git | ${PWD}/.git | true | false | fatal: this operation must be run in a work tree | <missing> | | |
${PWD}/.git/worktrees/wrktr | ${PWD}/.git | . | true | false | fatal: this operation must be run in a work tree | <missing> | | ${PWD}/wrktr/.git |
${PWD}/.git/worktrees/wrktr/modules/submod | . | . | false | false | ${PWD}/wrktr/submod | ../../../../../wrktr/submod | ../../../../../wrktr/submod | |
${PWD}/.git/modules/submod | . | . | false | false | ${PWD}/submod | ../../../submod | ../../../submod | |