find searching in parent directories instead of subdirectories
git rev-parse --show-toplevel
will print out the top level directory of the current repository, if you are in one.
Other related options:
# `pwd` is inside a git-controlled repository
git rev-parse --is-inside-work-tree
# `pwd` is inside the .git directory
git rev-parse --is-inside-git-dir
# path to the .git directory (may be relative or absolute)
git rev-parse --git-dir
# inverses of each other:
# `pwd` relative to root of repository
git rev-parse --show-prefix
# root of repository relative to `pwd`
git rev-parse --show-cdup
A generalized version of Gilles' answer, first parameter used to find match:
find-up () {
path=$(pwd)
while [[ "$path" != "" && ! -e "$path/$1" ]]; do
path=${path%/*}
done
echo "$path"
}
Keeps the use of sym-links.
An even more general version that allows using find
options:
#!/bin/bash
set -e
path="$1"
shift 1
while [[ $path != / ]];
do
find "$path" -maxdepth 1 -mindepth 1 "$@"
# Note: if you want to ignore symlinks, use "$(realpath -s "$path"/..)"
path="$(readlink -f "$path"/..)"
done
For example (assuming the script is saved as find_up.sh
)
find_up.sh some_dir -iname "foo*bar" -execdir pwd \;
...will print the names of all of some_dir
's ancestors (including itself) up to /
in which a file with the pattern is found.
When using readlink -f
the above script will follow symlinks on the way up, as noted in the comments. You can use realpath -s
instead, if you want to follow paths up by name ("/foo/bar" will go up to "foo" even if "bar" is a symlink) - however that requires installing realpath
which isn't installed by default on most platforms.