今回の目的
Gitを使わずに2つのディレクトリの差分ファイル一覧を取得したい。
なぜやるのか
もちろん大抵のGitが導入されているプロジェクトであればgit diff --name-only
でファイル名一覧の差分を取得することが出来ると思います。
ただ、例えば
本番サーバーではセキュリティ面を考えて、git pullは使わずにscpを利用している。
といことでした。そのため、gitを使わずにファイル一覧の差分を取得する必要があったわけです。
diffコマンドを試してみる
gitがダメなら次に考えられるのがdiffコマンドです。
div、div_proという2つのディレクトリがあるとします。
divとdiv_proを単純にdiffコマンドでファイル一覧を取得すると以下のようになります。
$ diff -qr ./div ./div_pro/
Only in ./div: .DS_Store
Files ./div/css/style.css and ./div_pro/css/style.css differ
Only in ./div/images: .DS_Store
Only in ./div/images: uber.png
Files ./div/index.html and ./div_pro/index.html differ
Files ./div/js/sample.js and ./div_pro/js/sample.js differ
diff Option
-q : 差分のあったファイル名を表示する(ファイル名のみではない)
-r : 2つのディレクトリを再帰的にたどって、すべてのファイルを比較する
Onlyから始まる → 新規ファイル
Filesから始まる → 修正(差分)があったファイル
見た通り差分がすぐわかると思います。
ただ、今回の欲しい情報はgit diff --name-only
のようなファイル名一覧のみです。
なので、上記のコマンドを元に欲しい情報へ整形させます。
それを実現させるためのscriptを書きました。
結論
# $1 $2はinput値です。ここではディレクトリ名を入れます。
output=$(diff -qr $1 $2)
array=()
while read -r line; do
string=$(echo "$line" | awk '{print $1}');
if [ $(echo $string | grep -e 'Only') ]; then
path=$(echo "$line" | awk '{print $3}' | sed -e "s/\:/\//");
fileName=$(echo "$line" | awk '{print $4}');
# .DS_SToreはMacのみなので、必要がなければ削除してください
if [ $fileName != '.DS_Store' ]; then
echo ${path/$1/$2}$fileName;
array+=(${path/$1/$2}$fileName);
fi
else
echo $(echo "$line" | awk '{print $4}');
array+=($(echo "$line" | awk '{print $4}'));
fi
done <<< "$output"
#####Command
$ sh script.sh ./div ./div_pro
./div_pro/css/style.css
./div_pro//images/uber.png
./div_pro/index.html
./div_pro/js/sample.js
これで差分のあったファイルに何か処理をさせるといったことも出来るようになりました。
※間違いの指摘やもっと他にいい方法があればぜひ教えてほしいです!!