# Githubでファイルの変更リストを自動作成してみた

> GitHubの異なるタグ間で変更されたファイルの管理と、自動化の手法について説明しています。手作業からコマンドを使用した自動化への移行により、効率的にファイル名の一覧作成や変更ファイルのフォルダー作成が可能になります。

- 公開日: 2024-11-08
- 更新日: 2024-11-08
- 著者: しんじょう
- タグ: Git
- URL: https://tech.anycloud.co.jp/articles/git-diff

---

私はこれまでの業務で、Githubの異なるタグ間で変更されたファイルの管理を行う際、以下の2つの作業を手作業で行っていました。

-   変更されたファイル名の一覧を作成
-   Github上のFiles Changedを確認しながら、変更ファイルをまとめたフォルダーの作成

これらの作業を手作業で行っていたため、先日フォルダー作成時にミスが生じてしまい、同じ失敗を繰り返さないために、作業の自動化を検討しました。

以前から、自動化を考えてはいたものの、精度検証にかける時間がなかなか取れず、手作業を続けていました。

しかし、同じミスを防ぐために、この機会に精度検証の時間を取って、自動化の妥当性を検討してみます！

## Githubから変更したファイル名の一覧を作成

Github上で、あるタグのバージョンから別のタグのバージョンの間で、変更が加わったファイル名の一覧をテキストベースで取得したい場合は以下のコマンドを実行します。

```bash
git diff --name-only --diff-filter=AMRD "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)" > ~/Desktop/test/test.txt
```

これで、あるタグから別のタグの間で変更があったファイル名のみをテキストの配列で取得することができます。

### それぞれのコマンドを説明

-   `git diff`
    
    →gitでの差分を見ることができます。今回は、タグのバージョンを指定しているため、タグ同士の差分を確認しています。
    
-   `--name-only`
    
    →ファイル名だけを表示することができます。今回はファイル名だけを表示するため、ファイルの変更内容までは表示していません。
    
    ※ ファイルの変更内容を出力するには、`--name-only` を削除します。
    
-   `--diff-filter=AMRD`
    
    →`--diff-filter` は特定の変更タイプに絞って結果を表示するものです。
    
    `A` ：新規に追加されたファイルを表示
    
    `M` ：内容が変更されたファイルを表示
    
    `R` ：名前が変更（リネーム）されたファイルを表示
    
    `D` ：削除されたファイルを表示
    
-   `"比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)"`
    
    →比較したいタグのバージョンを指定しています。指定されたバージョンを比較します。
    
-   `> ~/Desktop/test/test.txt`
    
    →`>` はコマンドの出力をファイルに書き込むリダイレクト演算子です。今回は、PCのデスクトップのtest/test.txtに出力を書き出しています。
    

### それぞれの変更タイプでリストを作成してみた

前述したコマンドでは、一つのファイルにまとめてリスト化されてしまうので、それぞれ変更のタイプ別にリストを作成するために、以下のコマンドを実行しました。

```bash
git diff --name-only --diff-filter=A "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)" > ~/Desktop/test/test_a.txt
git diff --name-only --diff-filter=M "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)" > ~/Desktop/test/test_m.txt
git diff --name-only --diff-filter=R "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)" > ~/Desktop/test/test_r.txt
git diff --name-only --diff-filter=D "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)" > ~/Desktop/test/test_d.txt
```

すると、変更があったファイル数が100ファイルほどだったのですが、一瞬でファイルが作成されます！

<figure><img src="./image-001.webp" alt="コマンドで作成したファイル一覧" width="1296" height="1118"></figure>

これまで手動で苦労しながら作成していたので、感動です！

もっと早く出会いたかった…

作成されたファイルのリストと自分が手動で作成したリストを見比べてみると、完全に一致しておりました！

これで次からは、このコマンドをフル活用していこうと思います！

### ファイル名を変更して、内容も変更したファイルはどこに分類される？

こちらの結論としては、`--diff-filter=R` のファイルに格納されていました。

また、変更前のファイルは削除前のリストにもありませんでした(これはちょっと意外でした…)。

つまり、ファイルの差分において、リネームは変更よりも優先され変更前のファイルはどの変更タイプにも分類されないということです。

## Githubから変更したファイルをまとめたフォルダーを作成

続いて、Github上で、あるタグのバージョンから別のタグのバージョンの間で、変更が加わったファイルをそのままのフォルダー構造で取得したい場合は以下のコマンドを実行します。

```bash
git archive --format=tar.gz --prefix=diff/ "比較したいタグ2(例：v1.0.1)" `git diff --name-only --diff-filter=AMRD "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)"` -o ~/Desktop/test/diff.tar.gz
```

### それぞれのコマンドを説明

-   `git archive`
    
    →Gitリポジトリの特定のバージョンやコミットの内容を圧縮ファイルとして書き出すことができます。
    
-   `--format=tar.gz`
    
    →出力フォーマットを指定しています。`tar.gz`という形式で圧縮したアーカイブファイルが生成されます。
    
-   `--prefix=diff/`
    
    →`--prefix` は、アーカイブファイル内のファイルに共通の先頭パスを付け加えるためのものです。これによって、全てのファイルが`diff/`フォルダの配下に出力されます。
    
-   `"比較したいタグ2(例：v1.0.1)”`
    
    →圧縮する基準となるバージョン（タグ）を指定します。`比較したいタグ2(例：v1.0.1)` の内容がアーカイブ対象です。
    
-   `git diff --name-only --diff-filter=AMRD "比較したいタグ1(例：v1.0.0)" "比較したいタグ2(例：v1.0.1)"`
    
    →コマンドの中でさらに別のコマンド（ で囲まれた部分）が実行され、出力がそのまま`git archive`に渡される仕組みです。
    
    →`git diff --name-only --diff-filter=AMRD "タグ1" "タグ2”` は、タグ1とタグ2の間で何かしらの変更があったファイルのリストを生成します。この出力が`git archive`に渡されることで、変更があったファイルのみが圧縮対象になります。
    
-   `-o ~/Desktop/test/diff.tar.gz`

→`-o`オプションは出力先のファイルを指定します。今回は、PCのデスクトップのtest/diff.tar.gzに圧縮ファイルが作成されます。

### 作成されたフォルダーを確認

前述したコマンドでフォルダーを作成しました。

<figure><img src="./image-002.webp" alt="作成されたフォルダー" width="1294" height="1128"></figure>

作成されたフォルダーを見ると、GIthub上のフォルダー構造でファイルが仕分けされていました。

実際に自分が作成したフォルダー構造と比較しても完全に一致しておりました！

これで、次からこの作業がかなり短縮できます！

## 結論

上記より、これからはコマンドで自動化していこうと思います！

ファイル名の一覧を作成する際は、`--diff-filter=AMRD` のコマンドでは`R` が優先される(変更前のファイルは出力されない、ファイル内容を変更していてもRにのみヒットする)ことを念頭において、実行していきます。
