2026/06/21(日)Mastodon v4.6.0をv.4.5.4にロールバックしたログ
UIが余りにも好みではなかったので戻した時のログ。
結論から言うと簡単に戻せた。
確認環境
- バイナリから起動しているMastodon
- Mastodon本番環境をGitで管理している
手順
- DBのロールバックを行う。34世代前に戻すと4.5.4になる
RAILS_ENV=production bundle exec rails db:rollback STEP=34 - 4.5.4時点まで
git revertする - Mastodonのアップグレードと同じ方法でコマンドを叩いてゆく
sudo su - mastodon # Rubyのアップデート用 cd ~/.rbenv/plugins/ruby-build git pull cd ~/live RUBY_CONFIGURE_OPTS=--with-jemalloc rbenv install # install bundle install yarn install # DBがアカンことがあるので叩いておく RAILS_ENV=production bundle exec rails db:migrate # いつものリビルド RAILS_ENV=production bundle exec rails assets:clobber RAILS_ENV=production bundle exec rails assets:precompile exit # 再起動 sudo systemctl restart mastodon-web mastodon-sidekiq mastodon-streaming - 動いてれば終わり
あとがき
切り戻した動機
4.5系から4.6系でUIが大幅に変わること自体は知っていたが、UIの変更が余りにも多く、個人で元に戻せるレベルではなかったため切り戻しすることにした。
app/javascriptやpackage.json, yarn.lock, config/viteを戻してもバックエンドと結びついてるやつがいるようで上手くいかなかった。
以下、v4.6.0で気に入らなかった部分の一例。端的に言うと目が痛いし、ダサい。
フォロー・フォロワー一覧にある「フォローされています」が余りにもデカく、ダサすぎる。
また二枚目にある便利メニューが消えた。私はこの便利ボタンを頻繁に使用しているため非常に困った。このボタンそのものは簡単に復活させられた。
日本語翻訳がまた消えた。翻訳が消えるのはMastodonにはよくあることだが毎回翻訳キーを調べて書き換えるのが嫌になった。ここ以外にも未翻訳部分はある。
ユーザーハンドルのポップアップが変わった。前の方が良かった。説明が薄いし、Copy handleのボタンも直感的でないと思う。あと翻訳してほしい。
左に寄りすぎたタブと、直感的でなく操作に手数がかかるフィルタUI。返信を表示は今までタブとしてあったのに、4.6.0では「投稿とブースト」プルダウンをクリックし、トグルボタンを切り替えないといけない。これはとても直感的でないと思うし、そこまでして操作したくない。
自己紹介編集画面が縦長になりすぎた。自己紹介の編集画面が空白まみれになり縦長になりスクロールが必要になったうえ、更に個別の項目に編集ボタンがあり、編集しづらい。なんで初期状態で編集可能にしないのか…。
自己紹介の補足情報が一行に複数入って気持ち悪い。
自己紹介で絵文字が出ない、要素が変に改行されたりトリムされている。
ハッシュタグのコントラスト比が高く目が痛い。
スクロールバーが太くなった。スタイリッシュさが消えた。
テキスト入力欄にフォーカスが入ると枠が出るようになった。光りすぎてて目が痛い。
未読チェックが左側に出るようになった。右側に出てくれた方が押しやすい。スクショ貼るのが面倒なので以降スクショなし。
タイムラインのメニュー展開ボタンが左側に出るようになった、右側にry。
非ログインユーザーの表示が標準ではライトテーマになっており、見た目を調整するには両方のテーマを直すか、ライトテーマを消し去るしかなく、UIの保守コストが増大した。(厳密にはブラウザのテーマによって変わる)
UIが嫌なのにバージョンを上げた理由
実はこうなることは事前にある程度知っていたのだが、Wrapstodonが使いたかったからバージョンを上げたところがある。
しかし全く容認できないUIだったため切り戻すことにした。
どうにかして元に戻そうとした夢の跡
4.5系のUIを部分的に復活させた #4で、vibe codingを利用して直そうとしたものの、破綻が酷く、結局半分くらい自分で書いたが、結局変更箇所が多すぎてどうにもならなかった。
あとがきのあとがき
取り敢えずDBを壊さず、ロールバックもせず綺麗に戻せてよかった。
2026/06/19(金)異なるGitリポジトリの履歴を連結する方法
投稿日:
あるリポジトリのファイルだけを抜いてきて新たにgit管理していたが、元々のリポジトリの履歴と繋げたくなったのでやった内容。
リベースやマージを経ないためコンフリクト解消が不要でお手軽。とにかく履歴さえくっつけばいい場合に向く。
確認環境
MSYS2上のGitで確認している
| Env | Ver |
|---|---|
| OS | Windows 11 Pro |
| Gitの動作環境 | msys2-x86_64-20260322 |
| Git | 2.53.0 |
前提
- 元となったリポジトリをA、リポジトリAの履歴を捨てて新しく作ったリポジトリをBとする
- どちらにもmainブランチしかないものとする
手順
- 事故が起きると面倒なため、まず作業用フォルダを作る
- リポジトリAをgit cloneする
- 最新のコミットハッシュを取得する
git rev-parse HEAD - この状態でリポジトリBをリモートリポジトリに追加する
git remote add new リポジトリB - リポジトリBを別ブランチにチェックアウトする
- チェックアウトしたブランチで最古のコミットハッシュを取得する。過去に連結歴のあるリポジトリでやると複数出るので注意
git rev-list --max-parents=0 HEAD - メインブランチに戻る
- 元となったリポジトリAに、新しいリポジトリBを繋ぎこむ。
この時、リポジトリB側のコミットハッシュはすべて変更され、署名も消えるgit replace --graft リポジトリBの最古のコミットハッシュ リポジトリAの最新コミットハッシュ
一括でやるコマンド
上に書いたことをコマンドに落としただけのもの。動作確認はしていない。
mkdir temp
cd temp
git clone /path/to/old/.git
BASE_END=$(git rev-parse HEAD)
git remote add dest /path/to/new/.git
git fetch new
git checkout -b new dest/main
NEW_START=$(git rev-list --max-parents=0 HEAD)
git switch -
git replace --graft $NEW_START $BASE_END
あとがき
リベースもマージもgit mvも何もせず、異なるリポジトリを無理やり繋げたのにも拘らず、ファイル名の変更が繋がってるのが凄いと思った。
恐らくAとBで同じパスのファイルがあれば、それは同じものとして繋げてくれていると思うのだが、これは便利だ。
これによってリポジトリを分離する前の履歴が見れるようになり、過去の経緯が追えるようになったので助かった。
あとMSYS2のGitは非常にパフォーマンスが悪く重いので、こういう作業で使うと非常に遅かった。
2026/06/19(金)さくらのレンタルサーバーにCachetを設置したログ
ステータス管理画面のCachetをさくらのレンタルサーバーに設置したときのログ。
開発版の3.xを利用しているが、軽く叩いた感じはとりあえず使える気がする。
確認環境
確認時点でのさくらのレンタルサーバーではSQLiteでの動作は出来なかった。これはPHP拡張がJSONをサポートしていないからと思われる。
| Env | Ver |
|---|---|
| Cachet 3.x | 2b0fc68988309647bdc0ba8e0b40862a3b8ddef4 |
| cachethq/core | 87be2387c06264c672dad94c87d00408bf34536d |
| PHP | 8.3.31 |
| MySQL | 8.0 |
Cachetには正確なバージョン番号がなさそうなのでコミットハッシュを書いている。最新のハッシュのコードが入っていることを確認済。
またCachet 3.xの中身は事実上からっぽで、vendor/配下にあるcachethq/coreが本体なので、そちらのバージョンも併記している。
手順
以下のコマンドはすべてzshで実行しているため、さくら標準のcshでは動かない箇所があるかもしれない。
composerがなかったのでcomposerを入れた。ここから先は
~/bin/にPATHが通っていることを前提で進めるphp -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" php -r "if (hash_file('sha384', 'composer-setup.php') === 'c8b085408188070d5f52bcfe4ecfbee5f727afa458b2573b8eaaf77b3419b0bf2768dc67c86944da1544f06fa544fd47') { echo 'Installer verified'.PHP_EOL; } else { echo 'Installer corrupt'.PHP_EOL; unlink('composer-setup.php'); exit(1); }" php composer-setup.php php -r "unlink('composer-setup.php');" mkdir ~/bin mv composer.phar ~/bin/composerCacheの取得と設置
git clone -b 3.x https://github.com/cachethq/cachet.git cd cachet composer install --no-dev -o # composerでエラーが出てupdateしろといわれたためupdate、これでインストールまでしてくれる composer update # 本体のアップデート composer update cachethq/core # 環境変数の編集 cp .env.example .env.envの編集
デフォルトでAPP_DEBUGがtrueなのでfalseにした方が良い。まだ開発版のためかTIMEZONEを設定してもトップ画面には反映されない。管理画面の一部では反映される。APP_DEBUG=false APP_TIMEZONE="Asia/Tokyo" APP_URL=https://status.example.com DB_CONNECTION=mysql DB_HOST=DBホスト DB_PORT=3306 DB_DATABASE=データベース名 DB_USERNAME=データベース名 DB_PASSWORD=パスワードCachetのセットアップ
php artisan key:generate php artisan vendor:publish --tag=cachet php artisan migrate # envを閲覧不能にする cat <<'EOF' | tee .htaccess <Files .env> deny from all </Files> EOF # 403になることを確認 curl https://status.example.com/.env php artisan cachet:make:user- crontの設定。ステータスページ表示する機能しかないのにやる意味があるのかは謎。
* * * * * php /home/<username>/www/path/to/artisan schedule:run >> /dev/null 2>&1 - さくらのコンパネからドメインを開き、Web公開フォルダーを
path/to/cachet/publicにする。
備考
Cachet v3.x is currently in development and not yet released. The following instructions are intended for development purposes only and are subject to change.
現時点では上記のようにあり、開発版なのでバグはあると思われる。
トラブルシューティング
Illuminate\Database\QueryExceptionが出る
SQLiteを使っていて次のようなエラーが出る場合、MySQLに変えると直る。恐らくさくらのレンサバに入ってるSQLite拡張がjson_eachをサポートしてないのが原因。
!Illuminate\Database\QueryException
Internal Server Error
SQLSTATE[HY000]: General error: 1 no such table: json_each (Connection: sqlite, SQL: select *
from "webhook_subscriptions" where ("send_all_events" = 1 or exists (select 1 from
json_each("selected_events") where "json_each"."value" is component_updated)))
Expand vendor frames
app/Http/Middleware/TrustProxies.php :32
あとがき
ステータスページを作る以上の機能が中区、外形監視はしてくれなかった
外形監視をして、その結果をステータスに表示してくれるツールだと思っていたら、ステータスの設定を行う機能と、それを表示する機能しかなかった。
つまり手動でメンテナンス中とか出したり、外形監視からAPIを蹴って何か表示するのには使えるが、このツールにはそれ以上の機能はないようだ。
これはダッシュボードを作る画面とAPIを提供してくれるツールということだ。
親切だったユーザー作成ウィザード
install.phpにアクセスして設定を書き換えるみたいな、一瞬ではあるものの脆弱な瞬間がないのは便利だと思った。
簡単なものなら自作できそう
Cachetは画面操作によってステータスを変えたり、履歴を出したりできるが、curlを投げて落ちてたら画面に表示くらいならパパっと作れそうだなと思った。
とはいえ、画面のリッチさや、APIからも操作できることなどを考えると、そんなのを作るのも大変なので、Cachetのようなツールを使った方が楽なのは間違いない。
ほぼ自分しか使ってないサーバーのためにこんなリッチなものが必要なのか…?
まぁあった方が豪華だし…みたいな…。
保守やオペのコストの方が高いので結局使わずじまいになる可能性も無きにしも非ずではある。
2026/06/18(木)Forgejoをv11からv15に上げる
Forgejo v11のエディタがスマホから扱いづらいのでv15に上げて扱いやすくするのが目的。
この作業で解決する問題
Forgejo v11ではAndroid Edgeでエディタ上をロングタップするとJSでカスタマイズされたメニューが出てしまい、全選択や全選択→切り取りみたいなコンボができない問題があった。
Forgejo v15に上げることで、ブラウザ標準のコンテキストメニューが表示されるようになった。但し全選択→切り取りは上手くいかず、ファイル先頭を選択しそこから末尾までドラッグした上で切り取る必要があった。とはいえ、ほとんど全く操作できなかったところから操作できるようになっただけでも十分だ。
個人的にスマホでコードを触る場合、ほとんどは小規模な編集なので、いったんはこれでも事足りる。
参考までに、この変更はForgejo v14で行われていた。
前提条件
- DBはSQLite
- Forgejo 11.0.15+gitea-1.22.0から15.0.3へのアップグレード
手順
基本的にはアップグレードガイドを読みながらやる。
# v15の取得
wget https://codeberg.org/forgejo/forgejo/releases/download/v15.0.3/forgejo-15.0.3-linux-amd64
# バックアップの作成
sudo -u git /usr/local/bin/forgejo \
--config /etc/forgejo/app.ini \
dump --file /home/git/forgejo.zip
# ジョブキューを吐き出す
sudo -u git /usr/local/bin/forgejo \
--config /etc/forgejo/app.ini \
manager flush-queues
# サービスを止める
sudo systemctl stop forgejo.service
# バイナリを上書き
sudo cp forgejo-11.0.15-linux-amd64 /usr/local/bin/forgejo
sudo chmod 755 /usr/local/bin/forgejo
# サービスを再開
sudo systemctl start forgejo
あとがき
特に何事もなく移行でき、バックアップファイルも使うことがなかったので良かった。
UI全体としてもブラッシュアップされ、いい感じになっていると思った。
昨日の今日でv11がv15を上げた感じだが、そもそもなんでv11を入れたんだっけ…?と思ったが、多分リリースページの真ん中にv11がいて、v15は画面の上の方にあったので、前回のインストール作業時に見えていなかったのだと思う。
前回の記事でForgejoのIssueを立てるための検証をしたときに最新がv16だったので、やけにバージョンがすっ飛んでるな、WinampやPHP方式か?と思ったら、単に私が見落としていただけだったか…という感じだ。
あと全然関係ないのだが、Forgejoのコントリビューターはオタクっぽい人が多いなと思ったのと、Forgejo同様にFOSSを使っていてCodebergでも採用されているAnubisの開発者もなかなかのオタクに見えるので、この二つのFOSSに何かの縁を感じたりもした。
2026/06/18(木)第五話 今日もサイトの改築をしたが、結果は控えめ
投稿日:
今日のサイト改築の話 第四話の続き。Forgejoを設置して公開するまでをやったログと長いあとがきは4.5話の可能性もある。
Pタグの行頭字下げをやめた
上の表はやめる前と、やめた後の見た目の比較。
adiaryを導入して少ししてから今まで長らく行頭の字下げが必要な気がしていたのだが、サイトのスタイリングをしていく中で空白が出すぎることや、他のマージンやパディングとの兼ね合いの調整、Pの中に画像を入れる、入れないによる差などが気になり始め、行頭字下げを廃止することにした。
これに伴いこのブログの行頭字下げも解除されている。
Web文書ではスタイリングの観点からインデントがない方が良いと判断したため。
廃止しても良いと思った理由としては行頭開けは原稿用紙や新聞、書籍など行間が詰まった媒体で段落の頭を判別しやすくするために配置されているものと考えたところによる。
Webは紙媒体と違い、余白を自由にとることができるから段落は空行で示すことができる。このことから行頭開けをするのは過剰ではないかと思い、廃止を決定した。
勿論、行頭字下げがあることで、より段落が判別しやすくなるとかもあると思うのだが、スタイリングをするときに行頭の空白が増えすぎること、画像などを巻き込むとややこしくなること、引用時のスタイルが破綻すること、CSS同士の相互干渉により考慮すべきことが増えることから、行頭インデントを廃止することとした。
あとがき
本日の活動が減った理由の一つとしては、ForgejoのOGPで日本語が文字化けすることに対して、Issueを立てることに力を入れていたことがある。
調べたところForgejoではGo言語組み込みフォントであるGo RegularをOGPの生成に使っており、このフォントはWGL4フォントファミリしかサポートしていないらしい。WGL4というのはWindows Glyph List 4のことで、端的に言うとWindowsに搭載されている欧文向けのフォントグリフの代表的なものらしい。
つまりForgejoでは欧文の代表的な文字しか表示できないというわけだ。というわけで日本語や繁体字・簡体字・ハングルなどのアジア文字をサポートすればアジア人が助かるというIssueを立てたが、一年以上前から議論されていたようで、即クローズされた。フォント問題が複雑で難しいらしい。わかる。私も名刺のフォント選定で死ぬほど悩んだもん。
と、まぁこんなのはほとんど言い訳で、次にやることが決まっていないというのが大きい。サイトの全体レイアウトの調整をしようにも指針を決めてないし、監視などの強化についてもドラフト状態のままである。なので、次すべきはタスク整理と、ロードマップ作りになってくるだろう。
あとはいい加減溜まってるブログネタを書かないと腐るので書くべきである。
というわけでサイト改築日記シリーズはいったん打ち切りになると思う。
一応今でも速攻で成果を出せるものとしてCachetの構築があるにはあるのだが、ちょっと勢いのまま走ってきた部分もあるので、一度立ち止まりたい気がしている。いや、そう言いつつ明日にはCachet置きましたとか書いてそうだが、それはそれでまぁ…。
そういえばGitHubからForgejoに移行した関係でページフッタにあるExtendsへのリポジトリリンクを変更したのと、Gistにあった資材をForgejoに移動してきたりもした。ついでに文字数カウンタを作って以来、長らく放置していたリガチャやサロゲートペアに対応する処理のテストコードを書ききった[1]。偉いと思う。
テストコードがあると、テストコードから、ああこれは正しい挙動なんだなというのが読み取れるので便利である。例えば👨👩👧👨👩👧👨👩👧👨👩👧あ゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙゙が゙゙゙゙ざ゙゙を4文字としてテストしているコードがあるが、このことからこの文字列が4文字になることが実装者の仕様として決まっていることが分かる。
Windowsでは先ほどの文字列はキャレットが四回移動するため、Windows的にも四文字の扱いだ。こういうのは決めの問題だが、テストコードがあることで、決めが分かるという話である。
- 但し実際のページのコードは大幅に簡略化しており、コードとしてみると別物なので、このテストコードが実際に機能しているとは言えない。このリポジトリのコードは元々別の目的で作ったもので、それを流用して例のツールを作ったという感じだ。 ↩



























