きり丸の技術日記

技術検証したり、資格等をここに残していきます。

Gitにchmodした結果を含めない、そして復帰させた時の手順(core.fileMode)

WSLで開発中にroot権限で作成されたファイルがあり、IntelliJ IDEAで更新できなかったファイルがありました。そのためディレクトリごとchownchmodを行ったのですが、Gitに変更箇所があると検知されてしまい、気づかずにコミットしてしまいました。

今回の記事では、chmodを行っても検知されないようにする設定方法と誤ってコミットしてしまったときの復帰手順の操作を記載します。復帰手順に関しては、もっといいやり方がありそうですので、もし同じ事象にハマったら教えてください。

環境

  • Git
    • 2.34.1
  • IntelliJ IDEA
    • 2024.1 EAP

設定方法

次のコマンドを実行すれば、chmodしても結果がコミットされなくなります。

git config --global core.fileMode false

復帰方法

  1. 一時ブランチを切る
  2. 目的のブランチを戻したいコミットまで戻す

IntelliJ IDEAのGit(Alt + 9)で操作しました。目的のコミットを選択しながら右クリックでReset Current Branch to Hereを選択してください。次に出現するウィンドウはHARDを選択してください。

  1. 一時ブランチで目的のコミットから目的のファイルだけget From Revisionで戻す

終わりに

普段なら戻したいファイルをRevert Selected Changesで選択していましたが、chmodの変更は戻せませんでした。復帰方法をまとめてくれる記事は今までなかったと思うので、これを機に同じ失敗した人に役立てばいいと思います。

なお、Chat GPTからは目的の答えは聞き出せませんでした。

類似記事

RailsのRSpecテストを並列化して30分から12分に短縮した(parallel_testsと性能アップ)

CI上のRailsのRSpecテストが30分もかかっていてストレスフルだったので、テストを並列化する等で30分かかっていた時間を12分まで削減しました。

そのときのメモ。

環境

  • AWS CodeBuild
  • Ruby
    • 2.7.2
  • Rails
    • 6.0.3.6
  • Parallel_tests
    • 4.4.0
  • MySQL
    • 8

前提

docker composeでテストは閉じている。そのため、RDS等のアクセスは発生していない。

対応

parallel_testsライブラリを入れる

並列化ライブラリのparallel_testsを導入します。

group :development, :test do
  gem 'parallel_tests'
end

テストのDB名を修正する

並列化したプロセスごとに独立したスキーマを割り当てないとデッドロックが頻発するのでプロセスごとにスキーマを作成します。

parallel_testsライブラリが実行しているプロセスごとに環境変数TEST_ENV_NUMBERを用意してくれるので、suffixに環境変数を指定します。

test:
  database: sample<%= ENV.fetch('TEST_ENV_NUMBER', '') %>
  # sample
  # sample2
  # sample3
  # といった具合に、プロセス数に応じたスキーマ名が振り当てられます。
  # 1は割り振られないので、どうしても1と割り振りたい場合は自作rakeが必要です

テスト実行時のRakeを自作する

私の環境の場合docker composeを使用して閉じた環境でテストしていることもあり、商用環境テーブルは不要でした。そのため、parallel_testsのライブラリをそのまま使用するとマイグレーションチェックが走ってエラーが発生してしまったため、その過程を飛ばしています。

また、自作Rakeがdevelop testgroupに依存しているのもあり、商用でエラーになってしまうので、LoadErrorをスキップするようにしています。

# frozen_string_literal: true

# NOTE: テスト時にしか使用しないものなので、商用ビルドするとインポートエラーが発生してしまう
begin
  require 'parallel_tests/tasks'
rescue LoadError
  puts 'Unable to load parallel_tests/tasks, skipping'
end

namespace :my_parallel do
  # NOTE: 必要な個所のみ抜き出す
  # https://github.com/grosser/parallel_tests/blob/8129c4c6feb6db7f94de144b995ea2a42aae0af5/lib/parallel_tests/tasks.rb#L258C1-L266C8
  task :spec, [:count, :pattern, :options, :pass_through] do |_t, args|
    # 商用環境テーブルのマイグレーションはチェックしない
    # ParallelTests::Tasks.check_for_pending_migrations
    ParallelTests::Tasks.load_lib
    command = ParallelTests::Tasks.build_run_command("spec", args)

    abort unless system(*command) # allow to chain tasks e.g. rake parallel:spec parallel:features
  end
end

CIを修正する(buildspec-ci.yml)

AWS CodeBuildを使用しているので、次のようなymlを用意しました。

phases:
  pre_build:
    commands:
      # MySQL 8 だと_utf8mb4 というsuffixがついてしまうので、それを削除する
      - sed -i 's#_utf8mb4\\\\'\''_\\\\'\''#'\''_'\''#g' db/schema.rb
      # スキーマの削除・作成・db/schema.rbの反映
      - docker-compose run --rm api rails parallel:drop parallel:create parallel:load_schema
  build:
    commands:
      # 自作rakeでのテスト実行
      - docker-compose run --rm api rails my_parallel:spec

プロセス数は指定したイメージのCPU数に依存するので、もし指定したCPU数よりも少ないプロセスで動かしたい場合は環境変数で指定してください。ローカルPCで挙動確認すると、20並列で動いてしまって期待の速度が出なかったので制御していました。

env:
  variables:
    PARALLEL_TEST_PROCESSORS: 4

結果

もともと、30分の内訳としては次のとおりでした。

  • 起動準備
    • 2分
  • PRE_BUILD
    • 5分弱
  • BUILD
    • 23分

テストを並列化した結果、25分になり、内訳は次のとおりでした。

  • 起動準備
    • 2分
  • PRE_BUILD
    • 5分弱
  • BUILD
    • 18分

ここまではコンピューティングが3GBメモリ2vCPUでしたが、7GBメモリ4vCPUに変更した結果。16分になり、内訳は次のとおりでした。

  • 起動準備
    • 2分
  • PRE_BUILD
    • 5分強
  • BUILD
    • 9分

最後に15GBメモリ8vCPUまで性能を上げて、12分になり、内訳は次のとおりでした。

  • 起動準備
    • 1分40秒
  • PRE_BUILD
    • 5分強
  • BUILD
    • 5分弱

AWSが用意するコンピューティングとのバランスを考えたときに、並列化によるこれ以上のメリットはないと考えてここで終了しています。

ソースコード

なし

終わりに

イメージ作成したり、DBを用意したりするPRE_BUILDが測定前に想像していなかったほど重く、ここを改善しないとこれ以上の高速化は見込めませんでした。

ビルドをDocker Build Cloudに任せたり、DBを作ったイメージごとsaveして流用する等々の考えもありましたが…。複雑になる上、高速化に貢献するか微妙なラインだったので、検証はしていません。

EC2だけでなく、Lambdaをうまく組み合わせたら早いとかそういう話があればぜひ聞きたいです。

参考情報

https://www.publickey1.jp/blog/24/docker40docker_build_cloudappleaws_graviton.html

WSLのIPを調べる

同一ネットワークに所属していればローカルで起動したサーバをiPhone等の他端末からアクセスできるのは知っています。Windowsの場合ipconfigで表示されたIPを指定すればアクセスできることも知っています。WSLの場合、別のIPを保持していることが原因だと分かったので、そのIPを知るためのメモ。

環境

  • Ubuntu
    • 22.04.2 LTS
  • GNU/Linux 5.15.133.1-microsoft-standard-WSL2 x86_64

前提条件

  • なし

コマンド

次のコマンドで得られたIPを指定すればアクセスできます。

ip addr show eth0 | grep inet | awk '{ print $2; }' | sed 's/\/.*$//'

説明

特にありません。

ソースコード

なし

終わりに

1つの端末では1つのIPしか振られないと思っていたので少々ハマりました。WSL自体は独立したLinux環境ですし、そう考えたらWindowsとWSLでは違うIPを持つのは普通なんですけどね。

これでIPを固定する必要がある環境だったり、proxyサーバを必要とする環境だとどうなるんでしょうね。しばらくはそういう企業に戻る気はないので、もし戻ることがあればそういう点も検証したいです。


20240331 追記 WSLで起動したサーバに他端末からアクセスしたい という副題を付けていましたが、これでは情報が足りないのでタイトルから外しています。