1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Gitリポジトリのルートの絶対パス動的取得は git rev-parse --show-toplevel が便利

Posted at

この記事は、なんか作ろうの会 Advent Calendar 2024 の3日目の記事として書かれました。

結論

Git管理しているリポジトリで、リポジトリのルートの絶対パスを環境に依らず取得するには、以下のコマンドが便利です。

git rev-parse --show-toplevel

はじめに

Git管理しているリポジトリに何らかのスクリプトを配置したとき、リポジトリのルートの絶対パスが欲しくなることがよくありませんか? 私はよくあります。
たとえば、スクリプト内で別のディレクトリやファイルを処理するとき、リポジトリのルートの絶対パスがあればそこを起点にリポジトリ内のパスを容易に構築できて可読性もよいです。

  • スクリプトを実行するディレクトリによらない
  • スクリプトが存在するディレクトリによらない

このような条件を満たすパスの取得方法が望まれます。

ケーススタディ

前提

以下のようなディレクトリ構造があります。

$ pwd
/tmp/20241203-advent

$ tree
.
├── deep
│   └── path
│       └── script.sh
├── input
│   └── sample.txt
└── output
    └── result.txt

5 directories, 3 files

このとき、deep/path/script.sh を使って input/sample.txt の内容を output/result.txt に追記することを考えます。

また、script.sh は後々べつのディレクトリに動かす可能性があります。

案1. 相対パスを使う

deep/path/script.sh
#!/bin/bash
cat ../../input/sample.txt >> ../../output/result.txt

上記のコマンドは、deep/path にcdしていて、 ./script.sh などと実行されることが前提です。
スクリプトの実行位置によってエラーになるので、あまり良い手とは言えないでしょう。

案2. dirnamerealpath を使う

deep/path/script.sh
#!/bin/bash
cat "$(dirname $(dirname $(dirname $0)))/input/sample.txt" >> "$(dirname $(dirname $(dirname $0)))/output/result.txt"

Gitリポジトリのルートまで dirname でさかのぼる案です。どのディレクトリにいる状態でスクリプトを実行するか、には結果が左右されなくなりましたが、今度はスクリプトが存在する位置によってエラーになる可能性が出てきてしまいます。
たとえば deep/path/script.shdeep/path/hoge/script.sh に移動したら、このスクリプトは成立しなくなります。

案3. git rev-parse --show-toplevel を使う

deep/path/script.sh
#!/bin/bash
cat "$(git rev-parse --show-toplevel)/input/sample.txt" >> "$(git rev-parse --show-toplevel)/output/result.txt"

満を持して、gitコマンドを使うパターンです。このパターンであれば、リポジトリのルートであればどこで実行しても結果が変わりません。$(git rev-parse --show-toplevel) がリポジトリのルートの絶対パスで展開されます。スクリプトをリポジトリ内の別のディレクトリに移動しても、返されるパスは変わらないので保守性が高いです。
また、gitのtoplevelを表示しようとしている、というのはコマンドについての知識が無くても何となく雰囲気から読み取ることができ、可読性も高いです。

制約として実行位置および実行されるスクリプトがともにリポジトリのルート以下の階層である、という前提は置かれます。しかし、むしろgitリポジトリ外で実行したりgitリポジトリ外のディレクトリにアクセスしたりする方が特殊かと思われますので、問題になることは少ないでしょう。

おわりに

Gitリポジトリのルートの絶対パスは意外と欲しくなることが多いのではないかと個人的には思っています。少なくとも自分は表題のコマンドをそらんじられるようになるくらいには欲しいと思う機会がありました。

ちょっとしたテクニック的なことではありますが、どなたかのお役に立てばとても嬉しく思います。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?