GitHub のプルリクエストを美しく書くための小技集

この記事は [YUMEMI Advent Calendar 2022](https://qiita.com/advent-calendar/2022/yumemi) 4 日目の記事です。

ゆめみでは、 GitHub + プルリクエスト駆動での開発が基本となっており、日々大量のプルリクエストが飛び交っています。
当然コードレビューの工数も比例して掛かってくるため、プルリクエストの書き方を工夫してレビュワーの負荷軽減に努めています。

そこで、今回はプルリクエストをより美しく書くために、個人的によく利用している小技についてまとめてみました。

:::note
それぞれの表示・動作については以下での確認となっています。

- 2022 年 12 月 4 日時点
- macOS + Google Chrome
:::

## メディア表示系

### 画像を小さく表示

ドラッグ & ドロップすることで、画像をプルリクエストに貼り付けることができますが、そのままだと Markdown 記法となってしまうため、原寸大で表示されてしまいます。

```md:アップロード後の&#x20;Markdown&#x20;形式
![ファイル名](https://user-images.githubusercontent.com/アップロード先URL.png)
```

画像を特定サイズで表示したい場合は、アップロード先の画像 URL を `src` 属性として利用して `img` タグに変換してしまいます。

```md:img&#x20;タグに変換してのサイズ指定
<img width="640" alt="ファイル名" src="https://user-images.githubusercontent.com/アップロード先URL.png">
<img width="320" alt="ファイル名" src="https://user-images.githubusercontent.com/アップロード先URL.png">
```

|対象|スクリーンショット|
|:-:|:-:|
|Markdown 記法|![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/5a3fe7f0-3b39-27a5-6504-b245175b093e.png)|
|`width="640"`|![after640.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/6204e80f-2ff5-440d-5a88-14e1cf22e3cd.png)|
|`width="320"`|![after320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/fbca12e9-4701-06b5-0de8-fae604a35555.png)|

### 動画をテーブル組み

以前は対応していなかったのですが、2021年頃から動画に関してもドラッグ & ドロップでアップロード + プレイヤーの表示に GitHub 側が対応してくれています.[^1]

[^1]: https://github.blog/2021-05-13-video-uploads-available-github/

実際に試してみると、 Markdown 記法ではなく単純なアップロード先 URL という形で展開されます。

```md:アップロード後の表示
https://user-images.githubusercontent.com/アップロード先URL.mp4
```

単純な URL 形式のため、修正前後の表示を行うためにテーブル組みを行った場合では動画プレイヤーがインライン展開されずに困ったことになります。

これを回避するために、アップロード先の動画 URL を `src` 属性として利用して `video` タグに変換。
これで、動画のテーブル組みが実現できます。

```md:動画のテーブル組み
|Before|After|
|:-:|:-:|
|<video src="https://user-images.githubusercontent.com/アップロード先URLその1.mp4">|<video src="https://user-images.githubusercontent.com/アップロード先URLその2.mp4">|
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/503f8045-cd43-c450-9e14-01ece259cb5d.png)

動画プレイヤーの上部に表示されるタイトル部分については、アップロード時の動画ファイル名が利用されるため、こだわる場合はアップロード前にファイル名を変更してください。

## 引用系

### コードのインライン参照

レビュワーに関連するコード部分を示したいといった場合に、以下のようにインライン展開した状態でコードを示すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/6f034eda-237d-19bd-6953-cf0cf38618c8.png)

対応手順としては、以下の通りです。

1. 対象のコードを GitHub 上で確認
1. 行を選択して、 `Copy permalink` で該当行へのリンクをクリップボード上に取得
    - ブランチ名やタグ名に依存するものではなく、コミットハッシュに依存した形式の URL となります
1. クリップボードからペースト
1. 複数行指定する場合はリンクのアンカー部分を `L${開始行数}-L${終了行数}` に変更

<img width="480" alt="Copy permalink の操作" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/29e22565-e9e4-2cda-3448-5ef997b81cad.png">

```md:複数行の指定例
https://github.com/hugehoge/Snappable/blob/806de8123c87fdd818f1b8998a56417a1a510007/Example/CarouselExample/CarouselExample/Components/CarouselView.swift#L12-L25
```

### プルリクエスト や Issue のインライン展開

GitHub ではプルリクエストや Issue の番号に沿った `#39` のような表記を自動的にリンクに展開してくれます。

![GitHub でのリンク展開](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/ba806bc1-9e84-9929-b7cb-e6afb2e8f5ba.png)

これだけでも十分なのですが、 Markdown のリスト形式で表現してあげると、該当項目のタイトル等をインライン展開してくれます。

```md:リスト表記によるインライン展開
- #39
- [ ] #39
    - チェックボックスとも合わせられる
```

![リスト表記によるインライン展開のレンダリング結果確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/d60e6088-b727-0a30-bc01-937f623a277d.png)


## 修飾系

### カラーコード表示

```md:カラーコード表示
`#ABCDEF`
```

のように、 HEX 値をインラインコード扱いすることで、対応するカラーが横に追加表示されます。

![カラーコード表示のレンダリング結果確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/0f46da29-0502-409f-f900-c7fb3d44a64a.png)

### diff をハイライト表示

Markdown のコードブロックを利用する際に言語を指定して、シンタックスハイライトを効かせることができるのは有名ですが、この言語として `diff` を指定することができます。

このため、`git diff` の結果をプルリクエストの説明欄やコメントに記載したいとなった場合に `diff` なコードブロックを利用することで、いい感じに表示してくれます。

```md:diff&#x20;をハイライト表示
​```diff
diff --git a/fizzbuzz.swift b/fizzbuzz.swift
index 64dff72..a982e50 100644
--- a/fizzbuzz.swift
+++ b/fizzbuzz.swift
@@ -1,12 +1,12 @@
 import Foundation
 
 let result: [String]  = (1...100).map { i in
-  if i % 3 == 0 {
+  if i % 15 == 0 {
+    return "FizzBuzz"
+  } else if i % 3 == 0 {
     return "Fizz"
   } else if i % 5 == 0 {
     return "Buzz"
-  } else if i % 15 == 0 {
-    return "FizzBuzz"
   } else {
     return String(i)
   }

​```
```

![diff 表示のレンダリング結果確認](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/e1540933-ad10-cef3-4684-b7fd5e003bd6.png)


### 冗長な記述を折りたたみ

どうしても必要だけど冗長になってしまう記述ブロック等があると、プルリクエストの説明欄がどうしても縦に長くなってしまいます。

全体ではコンパクトにまとめてレビュー時の可読性を担保しつつ、冗長な記述を追加したいとなった場合には `<details>` タグと `<summary>` タグを利用してアコーディオン展開可能にするといったことが可能です。

特にスクリーンショット画像の数が多い場合や上述の diff を載せるとなった場合に効果的です。

```md:折りたたみ表示
<details>
<summary>修正前後の動作</summary>

|Before|After|
|:-:|:-:|
|<video src="https://user-images.githubusercontent.com/アップロード先URLその1.mp4">|<video src="https://user-images.githubusercontent.com/アップロード先URLその2.mp4">|

</details>

<details>
<summary>diff 全文</summary>

​```diff
diff --git a/fizzbuzz.swift b/fizzbuzz.swift
index 64dff72..a982e50 100644
--- a/fizzbuzz.swift
+++ b/fizzbuzz.swift
@@ -1,12 +1,12 @@
 import Foundation
 
 let result: [String]  = (1...100).map { i in
-  if i % 3 == 0 {
+  if i % 15 == 0 {
+    return "FizzBuzz"
+  } else if i % 3 == 0 {
     return "Fizz"
   } else if i % 5 == 0 {
     return "Buzz"
-  } else if i % 15 == 0 {
-    return "FizzBuzz"
   } else {
     return String(i)
   }

​```

</details>

あのイーハトーヴォのすきとおった風、夏でも底に冷たさをもつ青いそら、うつくしい森で飾られたモリーオ市、郊外のぎらぎらひかる草の波。

```

|状態|スクリーンショット|
|:-:|:-:|
|格納|![格納状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/66e21f1d-046b-b524-901f-2f80c47e7de8.png)|
|展開|![展開状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/178830/22704d6a-d7d5-12c4-4e6a-681059b67860.png)|