AR ホームベーカリー

AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

Git が扱う改行の話

not equal Github.

自分の理解のために書いたので、困っている人は最後の「参考」ブロックに貼ってあるリンク順に読んだほうがわかりやすいと思います (小声)。

改行コード

世界には 3 種類の代表的な改行コードが存在する。

  • CR
    • キャリッジリターン、古の Macintosh 環境
  • LF
  • CR+LF
    • キャリッジリターン+ラインフィード、Windows

だいたい、というかこれだけ覚えておけば早々困らないけど、他には NEL など別の改行コードも存在する。

なんなら自作アプリケーションなら \kaigyo とかしたら改行コードとして見なす、みたいにしても良いわけだ。 これも広義の意味では改行コードたりえる。

Unicodeでは、CR (U+000D) とLF (U+000A) に加えて、「次の行」 (next line) を示すNEL (U+0085)、行区切り文字 (line separator) を示すLS (U+2028)、段落区切り文字 (paragraph separator) を示すPS (U+2029) が提供される。

ja.wikipedia.org

個人的には調べて初めて「えー HTTP って CR+LF なの!?」というのを知ったし、単純に名称として CR・LF を覚えていたのを、以下のように「あーなるほど、頭出しなのか要は」と納得したのだった。 意外と面白い。

すなわち、プリンタヘッドを新しい行の先頭に移動するという「改行」の動作を、現在行の先頭に移動するCR(キャリッジリターン→横移動)の動作と、新しい行に移動するLF(ラインフィード→縦移動)という2つの動作に分割し、それぞれ独立して制御するよう設計されていた。

上記 wikipdia 記事の歴史項より

Git が扱う改行コード

話が大幅にそれたけどここからが本題。

Git が扱う改行コードは、基本的に git コマンドを実行する環境に依存している (core.eol: native つまりデフォルト動作)。 すなわち Windows なら CR+LF だし Unix/Linux なら LF というように。

なにが問題になるか

実行する環境に依存する、ということは WindowsmacOS 環境で開発している人とか、 Windows で開発して本番は Linux、などという異なる OS で動作させる時に「改行の動作が揃わない (認識されない! もしくは CR, LF で分解されて改行が意図した形にならない! 行末に ^M のように BOM が付与される!)」 となる。

どう解決するか

core.autocrlf という設定で git が扱う (リモートに push したり、ローカルに pull してきたり) タイミングで、管理対象の改行コードをよしなにしてくれるオプションがある。 以下のように使う。

git config --global core.autocrlf (true|input|false)

autocrlf

前述の通り、改行コードを自動変換してくれるオプション。 人によって様々な意見があるけど、これを有効にして解決する……というわけではない。

以下の参考元がわかりやすいが、雑に記載すると Windows 環境だと以下のような変換が走る。

futureys.tokyo

autocrlf: true

  • リモートに push
    • CR+LF → LF
  • ローカルに pull
    • LF -> CR+LF

注意するべき点として、 CR+LF で git に登録されたファイルを pull してきたとき LF へ変換されない。以下のような動きですね。

  • ローカルに pull
    • CR+LF -> CR+LF

autocrlf: input

  • リモートに push
    • なにもしない
  • ローカルに pull
    • LF -> CR+LF

autocrlf: false

なにもしない

基本的に LF 方向へ変換される

というのが git の改行コード変換の基本動作。 また、上記の通り「CR+LF で git に登録されたファイルを pull してきたとき LF へ変換されない」という動作があり、このようなパターンは基本救えない。 (これは明示的に CR+LF で git に登録されてくる、という例外前提っぽい)

ということがわかると自然と解決策が 作業環境も LF に揃える のがよさそうだ、となる。

設定

強制的に揃えるなら以下のようになる。

Windows

CLI から 設定する場合は以下。

git config --global core.autocrlf false
git config --global core.eol lf

直接 .gitconfig などを編集する場合は以下。

[core]

        ...

        # ここから
        autocrlf = false
        eol = lf
Unix/Linux

何もしなくて大丈夫。 あえて設定で表現すると以下のような状態。

git config --global core.autocrlf false
git config --global core.eol native

push/pull するとき改行コードを触らず、かつ改行コードは一貫して OS に依存した LF のみ扱う (CR+LF が紛れ込んでいても残置する) となる。

問題

たとえばこれプロジェクト的に「Windows 向けアプリ作っててビルドもなんもかんも CR+LF の世界なんだけど!」という場合はどうすればいいのか、となる。

これは git の説明ページの core.eol に以下のように書いてある。

Setting this variable to "true" is the same as setting the text attribute to "auto" on all files and core.eol to "crlf".

この変数を「true」に設定することは、すべてのファイルのテキスト属性を「auto」に設定し、core.eol を「crlf」に設定することと同じです。

git-scm.com

つまり以下のようにすればよさそう (もし CR+LF なプロジェクトも同時に管理しているなら、対象のワーキングディレクトリに移動して git config --local で実行すればよさそう)。

git config --global core.autocrlf true
git config --global core.eol crlf

.gitconfig に書くなら以下。

[core]

        ...

        # ここから
        autocrlf = true
        # Windows なら native でも
        eol = crlf

なぜ突然こんな話を

インフラメンテナンス担当している Rails 案件で「動かない〜」という相談が相次いでいて、流石におかしいと思ったので「development で動かしてみるか!」と様子見でコンテナ立ち上げようとしたら rescue in _decrypt が出て、確認したら developmeny.yml.enc に謎の改行が紛れ込んでいて「そりゃ動かねえよ!」となったので調べていた。

どのエディタで開いても改行コードは LF で検出される。 のでさすがに、「自分の環境が悪いのか?」となり

  • core.autocrlf = false
  • main ブランチを ZIP でダウンロード

いずれも全く同じく改行が見える。 しかし Github UI 上だと、逆に単一行として改行が見えない……ので、なんだこれは、CR+LF がバラされているのか? git が悪さしているのか? となって調べていた。

オチとしては、コード側メンテナーの人がなんかのアドオンだかエクステンションで、「CTRL+S すると必ず改行を挿入する」という動作を入れており、バックポートを持ってきた時に development.yml.enc が conflict して、手動で解消したら意図せず改行が挿入されてしまった、ということだった。

たしかに diff とかで前後を比較すると以下のように No newline at end of file が検出されないので、単純に改行が悪い、という当初の見立て通りだった。

--- a/config/credentials/development.yml.enc
+++ b/config/credentials/development.yml.enc
@@ -1 +1 @@
- ... 
\ No newline at end of file
+ ...
lines 1-14/14 (END)

...

--- a/config/credentials/development.yml.enc
+++ b/config/credentials/development.yml.enc
@@ -1 +1 @@
- ... 
\ No newline at end of file
+ ...
\ No newline at end of file

おまけ:デフォルト値

core.eol は以下のように native、つまり実行環境に依存すると明言されている。

The default value is native.

git-scm.com

しかし、 core.autocrlf はデフォルト値がない。

git-scm.com

StackOverflow で以下のように答えている外人兄貴がいた。

stackoverflow.com

Checking the git source code, core.autocrlf is set to false by default. (And has been since the property's original introduction on Feb 13, 2007, though it has since been converted from a static value to a constant.)

The Windows installer does require you to pick a value for this property which is explicitly set in the git system config.

git ソース コードを確認すると、core.autocrlf はデフォルトで false に設定されています。 (このプロパティは 2007 年 2 月 13 日に最初に導入されて以来、静的な値から定数に変換されました。)

Windows インストーラーでは、git システム構成で明示的に設定されるこのプロパティの値を選択する必要があります。

そんなことある?! と思ってリンク先見たらちょっと古かったので現代は以下。

github.com

確かに定数じゃん……!? で、これがセットされていない時は参照先がないので false となる。

なので git をインストールする時、関連するソフトウェアやインストーラーで core.autocrlf の定義なり .gitconfig を配置して占有的に参照先を設定する、などをなんらかしているはず。

は〜、なるほど。

参考

qiita.com

ogawa.s18.xrea.com

docs.github.com

VScode の solargraph

github.com

治った! と思っても次回起動すると壊れていて無限にダメを感じるので、ちょっと腰を据えて見よう、という気持ちになっている。

ゴール

開いたプロジェクト (ディレクトリ) の Gemfile/Gemfile.lock に依存せず、rbenv なりシステムワイドなりで採用されている solargraph が自動的に読み込まれる。

調べていて出てきている注意点

VScode の terminal 環境はユーザシェルを読み込まない? という話を効いた気もするけど、以下記事を読むと -l でユーザーシェルとして処理している気がする。

qiita.com

けど実際、自分の環境で terminal タブを表示すると powerline とかあのあたりの表示が壊れるのでなんかあるんだろうな。

いまんとこやったこと

Solargraph: Command Path/Users/donbulinux/.anyenv/envs/rbenv/shims/solargraph と rbenv/shims を指定して、使っている環境 (rbenv local している先のバージョン) の gem に solargraph を追加した。

という感じ

なかなかうまくいかないので冒頭に戻る、という感じ。 ここまでやったことを書いておくので、11 末締め切りが終わればちょっと余裕あるので調べたい。

コンテナ全部とめたい

複数の fork プロジェクトを触っている

と、だいたい compose ファイルも共通しているので「特定のポートがバッティングしまくる」みたいな事になりがち。 なので、雑に全部のコンテナを停止したい時がある。

以下のようにすれば良いようだ。

docker stop $(docker ps -a -q)

参考

zenn.dev

仮想化とかコンテナのたとえを個人的に現代的に消化しようとしてうんちでた

うんちしてたら考えがまとまってきたので。

物のたとえ

最近「IT分野をなにかにたとえるのは無理では? 概念だろうとなんだろうと◯◯は◯◯、でいいのでは」という気になっており、例えるのは説明側のエゴというかよほど好適な例でないと学習の阻害になる (喋る側と聞く側で知識の差があるので、ギャップを埋めるために一方的にアウトプットしている) と感じている。

これはいわゆる同業種間での感じで、もちろん他業種や toC でお話する時に、相手の知識や立場にたった物のたとえが悪いということではない。

サーバー=家、という例えのお話です

よく挙げられるたとえとして、「サーバーは家 (部屋) !」みたいなのがあるけど、ここを雑に表現してしまうと、続くコンテナ環境とか説明しづらいよな、と思ったので個人的に整理をしていた。

まずサーバー=家、が成り立つのはコンテナという概念が発生する以前で、それこそ仮想サーバーなんかが流行った後は、「一戸建てと賃貸!」みたいな方便も生まれたけど、そういう整理を兼ねている。 で、個人的には以下のような関係かなあ、と整理した。

例え 現実の単位
国家 運営会社
国土 データセンター
(借地権) 土地 ラック
一戸建て (ラックマウント≒物理占有) サーバー
賃貸マンション 仮想サーバー
部屋 コンテナ
ソーシャルマンション サーバレスコンテナ環境

AWS (東京リージョン) を例にすると以下のようになる。

例え 現実の単位
国家 AWS
国土 リージョン (ap-northeast-1)
(借地権) 土地 アベイラビリティーゾーン (apne1-az1,2,3,4)
一戸建て EC2 (ハードウェア占有インタンス)
賃貸マンション EC2, LightSail
部屋 ECS on EC2
ソーシャルマンション ECS on Fargate

あまり適切ではなかった

書いてて思ったのは、サーバー=部屋概念ありきで広げていくとあまり好適ではないな、という感じでした。

たとえの中に土地 (借地権) の話入れているのは、たとえが必要な層には直感的に伝わりづらい気がする。 AWS という前提がもう賃貸じゃん、ってなるんで。 その中にハードウェア占有インスタンス、みたいな更に困る話があるのがアレ。 まあ今回はしめしめと記載させてもらいましたが。

これ、うんちしてる時に「コンテナが部屋なのはいいけど、じゃあ Fargate とか基盤部分構築しないヤツを部屋、と呼んでいいのか……? ううーん」というのを悩んだ結果「そうだ共用部は運営会社メンテナンスで部屋だけ占有するソーシャルマンションがあるじゃん!(ブッチブリリリ!」となったので、脱糞の爽やかさで脳が焼かれた可能性はある。

日本人の家事情わかりてテスト

とはいえ、Sales なんかの分野の人が、ドメイン外の知識しか持っていない相手に対して「オンプレミス、自社所有は一軒家でここに借地権なんかの話と自分の持ち家メンテナンスの積立、マンションだと修繕費積立がありますし、賃貸マンションだったら借地権は考えなくてまあ大丈夫で、修繕積立なんかも家賃に入ってるか、共益費として設定されていますよね」みたいな、日本人は家を買うために仕事している、みたいなトコもあるので、ある程度の年齢のそういう層への説明としては刺さりやすいのかもしれない。

ある程度の年齢のそういう層、というのが、「決裁権を持っている人間」となるので暗黙的に壮年が対象だし、仮に若年層だとしても決裁権持ってるならある程度住環境へのコスト感は理解できる人のはずだよな、という期待があるので、やはりこれはある種、高等教育の勝利の部分あるよな、と個人的には思います。

自分向けの整理はそんな感じ! もっと良い例えがあったら教えて欲しい、ほならな!

おまけ

ap-northeast-1a とかの AWS 側からの正式なマップ名ってなんだっけ……APAZ? なんかちがうな、となって調べていて、以下のクラスメソッドの記事が出てきたんだけど、一瞬「あれウチのマッピングと違う気がする?!」となって、本文読んでて混乱してしまった。

dev.classmethod.jp

マッピングはランダムであり以下の図のようにAWSアカウントごとにAZのコードとAZ IDのマッピングは異なる場合があるため、注意が必要です。

文中にこのように書いてある。

んだけど、以下のような書き出しなので、いわゆる主語がデカイというヤツを暗黙的に食らってしまいそうになる。

アベイラビリティゾーン「apne1-az3」とは? アベイラビリティゾーン「apne1-az3」は、最近発行されたアカウントでは利用できない古いアベイラビリティゾーン(以下AZ)です。

全体的に「マッピングは決め打ち」と誤読しそうになるので、クラスメソッドくんでもこういう書き方になる時があるんだな、気をつけよう、という気持ちになるのだった。

AWSゥ!

まずおまんがまともな文章書きよればこげんこつならんとよ! 「リファレンスは英語です!」と言っていても、その英ドキュメントもロクでもねえので、本当……という感じ。

2024/10/30

文章の書き方

www.bunka.go.jp

はえ~、となりながら途中まで読んでいた。

お仕事での提出グレード

よくわかんなくて、社内の高学歴兄貴に「赤ペン先生してください、オネシャス!!」って毎回様子を見てお願いしていたので、こういうのは助かる。

まあ X で回ってきたので偶然見て喜んでたら、日付が令和4年とか書いてあって衝撃でしたね。

iMac

突然 M4 iMac が生えてましたね。

www.itmedia.co.jp

8 CPU/ 8 GPU/ 16GB RAM/ 256GiB SSD/ 24 インチ (4.5k) ディスプレイ/ 付属品含め USB-C 統一/ 吊るし最安 199,800 円。 外に持ち出さない前提なら、MacBookPro と外付けディスプレイ買うよりよさそう。

Mac mini

突然 M4 Mac mini が生えてきましたね。

www.itmedia.co.jp

10 CPU/ 10 GPU/ 16GB RAM/ 256GiB SSD/ 吊るし最安 94,800 円。 Retina など高解像度ディスプレイにこだわらないのであれば、これと HDMI 接続の外付けディプレイ 3 万円くらいで買っちゃうのが開発環境的には一番安くてお手軽そう。

740g とのことなので、USB-C のモバイルディスプレイ 13 インチ程度だと 500g ないはずだし、MacBookPro 持つよりは合計重量的に軽い可能性まであるのがすごいなあ。 電源の確保必須だけど。

M4Pro モデルも用意されてて、こいつが背面 USB-C 端子だけ Thunderbolt5 実装で 120Gbps 使えるので「はえ~、ケーブル発熱もすごそう」という感じ。

Thudenrbolt5

pc.watch.impress.co.jp

全然知らなかったんですが、1 レーン 40Gbps を 4 レーン束ねて全二重通信 80Gbps を実現しとるんすね。

送信1 送信2 受信1 受信2
40Gbps 40Gbps 40Gbps 40Gbps

でこれ経路を変更することで、通信速度が非対称になる代わりに送信側が 120Gbps になるということか?

送信1 送信2 送信3 受信1
40Gbps 40Gbps 40Gbps 40Gbps

データの作りや流れが違うとはいえ、 TCP/IP が 1Gbps をいまだに卒業できないのを見ていると、シリアルパラレルケーブルから USB 以降の進化がすげーな、と思うわけ。 (RS-232C でプリンタ接続をしていた Windows98 のおじさんとしては)

120Gbps の転送速度

ja.wikipedia.org

送信 (片方向) 120Gbps っていうと、だいたい PCI-Express3 x16 もしくは PCI-Express4 x8 程度か。 はーめちゃ早い。

しかし、 PCI-Express はこの速度を双方向で保持しているので、実際比較するなら 80Gbps の方でやるべき。 そうなると Gen3 x8 と Gen4 x4 あたりですが。 それだと帯域たりないので、それぞれ x10, x6 相当かなとも思うわけ。

雑に解釈しているけど、いうて GeForce RTX 30, 40 世代は PCI-Express3 x16 とか PCI-Express4 x8 でも数パーセントしか性能劣化が起きない、みたいな話もあるので、外付け GPU が更に有効になりそうですねえという風情ある。 GPU 自体より外付け GPU ボックスの方が高い、みたいな風情になりつつあるけど。

通信速度

こういうホストターゲット型の通信がどんどん高速化するのに対して、雑な分類でいうと TCP/IP は全然市販部分で高速化しねーな、という気持ちがある。

www.softech.co.jp

とはいえ USB がホストターゲット型で、ある意味クローズな環境で完結するのに対して、 TCP/IP は遠距離を結ぶネットワークなので、全体、特に ISP などが底上げされないと高速化は難しいというのもわかるつもりではある。 あるけどさあ、という感じ。

「RJ-45 に Cat7 は存在しない! 10G はまやかしだふじこふじこ」つってる X のエンジニアおっさんが事実言ってるんだとしても、「欺瞞!」って感じるわけよ。 欺瞞ではないんだけど。

実際のところ、10 人が 10Gbps の回線を利用できるというシナリオより、 100 人が 1Gbps の回線を利用できる、というシナリオの方が最低限クリアすべきというように変化している時代だしなあ。 その上で更に高速通信をさせろ、という要求なんだけど、まあ難しいよねというのもわかる。

光速は遅い

こうなってくると「光速は遅い」という話が学術的ではなくて、現実の話になってくる。 いやまあ光ファイバーは現実的には光通信であって光通信ではない、というやつだけど。 素材がね (ファイバーの折れる音)。

qiita.com

AWS snowmobile だ! もうおなくなりになったけど!

www.publickey1.jp

これもファンキーに見えて、計画的にやれるなら転送時間や転送量を考慮するとローコストだよなあ、という感じ。 トラックで持ち出した以降の区間だけ同期できるようにレプリケーション用のリードクラスタ準備しといてあとはぶん回せばいいので。

太古の昔に Togetter かなんかで「HDD 満載したバックかついで新幹線に乗って東京大阪間を移動した」みたいな人見た記憶あるので、データ転送時の損失が物理か電子的か、どの程度の欠損率か、というのを考慮すると物理転送が最強、というのはしばらくはそう!

Heroku では Redis7 ではなく Valkey7 を使う

掲題のとおりです

image の指定を redis から image: "valkey/valkey:7.2" などにします。

engineerjutsu.com

upgrade コマンドなどあるようですが、今んところ公式に Docker ファイル更新内容から含めたアップグレードガイド、みたいなのないっぽくて、 heroku CLI から redis:upgrade 投げろ、みたいなのしか見当たらない。

Valkey

Redis のライセンスが変更になったので fork されたやつ。

OpenSearch といい、あのあたりマネタイズが難しいしクラウドベンダーがタダ乗りするのが許せねえ! という気持ちは十分に理解できるけど、

「ライセンスが違う? これは我々がこんにち表すところの OSS です!」

と言わざるを得ないから、各社ベンダーも

「じゃあ fork してライセンスに抵触しないように使うね」

となるのでウム、という感じですね。

Google ドキュメントで Markdown を有効にして文字数カウントを表示する

Markdown 有効化

ツール > 設定 > Markdown を有効にする

チェックを入れると有効になる

VScode などプレーンじゃないテキストエディタから丸ごとコピペなどすると、変なスタイルが付与されてカラーシンタックスとかめちゃくちゃになる。 ので、既存情報を手動で移行する際は、一度メモ帳など ascii 情報しか扱えないエディタを経由すると良い。

文字数カウント

CTRL+SHIFT+c

チェックを入れると編集画面上に表示できる

標準だと左下あたりに出るはず

常にカウントを表示するのは無理っぽく、文字数など詳細はクリックしている間だけ表示される。 しゃーなし。

概ね

Markdown ソースの保持 にこだわりがない (かつ Google に検疫されていい) なら Google ドキュメントでもよさそうです。 見出しに応じてアウトラインが増えるのは便利ですしね。

逆にクローズドな作業であったり、移植性などを鑑みて Markdown ソース (書式含めて) が保持されてないと困る、という人は VScode なりでがんばりましょう。