LoginSignup
8
0

More than 5 years have passed since last update.

gitで変更があったファイルを列挙する

Posted at

今作業しているブランチで変更・追加を行ったファイルを列挙したい。

具体的には、 lint チェックの対象を作業中のファイルだけに絞って省力化したい、というイレギュラーじみたケースのためにやってみました。

master と作業中ブランチとで差があるファイルを列挙

次のコマンドで masterHEAD (作業中ブランチ)とで差があるもののファイル名を列挙できます。

git -c core.quotepath=false diff master HEAD --name-only

-c core.quotepath=false を付けているのは、取得したファイル名を他コマンドのパラメータにする目的があるのでこの時点でエスケープとかやってほしくなかったからです。
masterHEAD はベースにするブランチ・対象にするブランチで読み替えましょう。

ただし、このコマンドでは master に対しての作業中ブランチのファイルだけでなく、作業中ブランチに対して差がある master のファイルも出てきてしまいます。

master ではなく master から作業中ブランチを生やしたベースコミットから差があるファイルを列挙

GitHub の Pull Request みたいにベースコミットからその作業中ブランチで変更したファイルだけを列挙したいです。
なのでベースコミットを見つけてくればよい。

git -c core.quotepath=false diff `git show-branch --merge-base master HEAD` HEAD --name-only

さっきのコマンドの mastergit show-branch --merge-base master HEAD に置き換えただけです。
読みづらいので、シェルスクリプトの中で使う場合は次のように一度変数に入れたほうがよいでしょう。

BASE_COMMIT=`git show-branch --merge-base origin/master HEAD`
git -c core.quotepath=false diff $BASE_COMMIT HEAD --name-only

列挙したファイル名を他コマンドのパラメータにする

こんな事し出した目的は、 Pull Request に含まれるファイルだけを対象に lint チェックかけたかったからでした。
そこで最終的に出来上がったのが次のようなシェルスクリプトです。

#!/bin/bash -eux

BASE_COMMIT=`git show-branch --merge-base origin/master HEAD`
files=()
while read file
do
    files+=("${file}")
done < <( git -c core.quotepath=false diff $BASE_COMMIT HEAD --name-only | grep -E '\.md"?$' )

if [ ${#files[@]} -gt 0 ]; then
    npm run lint "${files[@]}"
fi

本当はスクリプトの実行パスの正規化のために cd `dirname $0` とか他にもやってるんですが割愛してます。
今回チェックしたいのは Markdown のドキュメントだったので grep -E '\.md"?$' でファイルをさらに絞り込んでます。
ファイル名に空白が含まれたりして面倒くさかったんですが、参考記事などのおかげでエスケープとか深く考えずになんとかなりました。

そういうわけで、できあがったスクリプトを CI で動かしています。

参考

8
0
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
8
0