サブディレクトリの代わりに親ディレクトリでクエリを検索する

サブディレクトリの代わりに親ディレクトリでクエリを検索する

ファイルツリーの深いところに入れ子になっていて、そのファイルを含む親ディレクトリを探したいと思います。

たとえば、私はネストされたGITリポジトリセットにあり、現在存在.gitするファイルを制御するディレクトリを探したいと思います。同じことがあってほしい

find -searchup -iname ".git"

答え1

git rev-parse --show-toplevel

現在リポジトリにある場合は、現在リポジトリの最上位ディレクトリが印刷されます。

その他の関連オプション:

# `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

答え2

一致を見つけるために使用される最初のパラメータを使用するGilesの回答の一般的なバージョン。

find-up () {
  path=$(pwd)
  while [[ "$path" != "" && ! -e "$path/$1" ]]; do
    path=${path%/*}
  done
  echo "$path"
}

シンボリックリンクの使用を維持します。

答え3

オプションの使用を許可するより一般的なバージョンfind

#!/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

たとえば(スクリプトがとして保存されていると仮定find_up.sh

find_up.sh some_dir -iname "foo*bar" -execdir pwd \;

...パターンがあるファイルが見つかるsome_dirまで印刷されるすべての祖先(自分を含む)の名前。/

上記のスクリプトを使用するときは、コメントreadlink -fに記載されているようにシンボリックリンクに従います。realpath -s名前でパスを追跡したい場合(「bar」がシンボリックリンクであっても「/foo/bar」は「foo」になります)、逆のアプローチを使用できます。ただし、これを行うには、インストールされていないrealpathほとんどのパスをインストールする必要があります。基本的にプラットフォーム。

答え4

不可能だとわかりました。私はシェルループよりも単純なことを考えることはできません。 (テストされていない、そうでないと仮定/.git

git_root=$(pwd -P 2>/dev/null || command pwd)
while [ ! -e "$git_root/.git" ]; do
  git_root=${git_root%/*}
  if [ "$git_root" = "" ]; then break; fi
done

Gitリポジトリの特定のケースでは、Gitにタスクを実行させることができます。

git_root=$(GIT_EDITOR=echo git config -e)
git_root=${git_root%/*}

関連情報