Git で別ブランチから特定のファイルのみチェックアウトする

Git で別ブランチから特定のファイルのみチェックアウトする方法を知ったので試しました。なお、 Git は 2.33.1.windows.1 で試しました。

今回は Ambergrease で。該当プロジェクトは mainブランチ と MySQL のバージョンを 8.0 から 5.7 に落とした mysql5.7ブランチ が存在するため、うってつけの条件でした。

別ブランチのファイルを参照

> git show main:workspace/entrypoint_web.sh

#!/bin/bash

# gen key & certificate
openssl req -new -newkey rsa:2048 -nodes -out /etc/ssl/private/server.csr -keyout /etc/ssl/private/server.key -subj "/C=/ST=/L=/O=/OU=/CN=*.lvh.me"
openssl x509 -days 365 -req -signkey /etc/ssl/private/server.key -in /etc/ssl/private/server.csr -out /etc/ssl/private/server.crt

# 略

mysql5.7ブランチ で mainブランチ の workspace/entrypoint_web.sh を参照。OKです。

別ブランチから特定のファイルをチェックアウト

試しに、 WP-CLI のインストールの条件分岐を mainブランチ には入れているが mysql5.7ブランチ には入れていない状態のリポジトリを作ります。

このリポジトリで mysql5.7ブランチ に移動し、次のコマンドを実行。

> git checkout main -- workspace/entrypoint_web.sh
> 

これで mainブランチ から WP-CLI のインストールの条件分岐の部分が入ったエントリポイントのシェルスクリプトが mysql5.7ブランチ にチェックアウトされ、上書き&ステージングまでされました。

mainブランチ から WP-CLI のインストールの条件分岐の部分が入ったエントリポイントのシェルスクリプトが mysql5.7ブランチ にチェックアウトされ、上書き&ステージングまでされた
mainブランチ から WP-CLI のインストールの条件分岐の部分が入ったエントリポイントのシェルスクリプトが mysql5.7ブランチ にチェックアウトされ、上書き&ステージングまでされた

今回のケースではWebサーバ側は共通なのでバッティングも気にせず、そのままコミットで大丈夫なケースです。こういう場合は便利ですね。

別ブランチから特定のファイルをチェックアウト (コンフリクト想定)

次に、DB側のエントリポイントで一ヶ所修正をします。

修正内容は該当リポジトリでは「 MySQL のログを削除せずにコンテナを再度ビルドすると、ログの最初の初期パスワードを拾ってしまうため、 root のパスワード置換処理でコケることを回避するために最後の結果を使用するように awk コマンドを修正」というもの。

先程とは逆に mysql5.7ブランチ で先に修正を施します。

-    DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk '{print $11}')
+    DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk 'END{print $11}')

awkEND を追加しています。

一方、 MySQL8.0 環境用の mainブランチ では該当箇所は次のようになっています。

    DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk '{print $13}')

ログの出力フォーマットが変わった結果、空白区切りで11番目ではなく13番目に初期パスワードが出現します。そのため、 awk の中身が {print $11} ではなく {print $13} 指定になっています。

この状態で、先程と同じようにチェックアウトのコマンドを実行。

> git checkout mysql5.7 -- workspace/entrypoint_db.sh

すると、次のようになりました。

-    DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk '{print $13}')
+    DB_INIT_PASSWORD=$(sudo grep 'temporary password' /var/log/mysql/mysql-error.log | sudo awk 'END{print $11}')

完全に mysql5.7ブランチ の内容で上書きされていますね。どうやら、そのままだと上書きしてしまうようです。

完全に mysql5.7ブランチ の内容で上書きされていますね。どうやら、そのままだと上書きしてしまう模様
完全に mysql5.7ブランチ の内容で上書きされていますね。どうやら、そのままだと上書きしてしまう模様

こういうケースでは注意するか、コンフリクトと同じような状態を起こすオプションがあったりするのでしょうか(未確認)。

とはいえ、先程の共通部分をチェックアウトできるだけでも便利なので、覚えておいて損はなさそうです。

参考

この記事を書いた人

アルム=バンド

フロントエンド・バックエンド・サーバエンジニア。LAMPやNodeからWP、Gulpを使ってejs,Scss,JSのコーディングまで一通り。たまにRasPiで遊んだり、趣味で開発したり。