
最終更新日: 2025年02月12日(水)
- 1. ご挨拶
- 2. 「スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう!」シリーズ
- 3. 「しくじり編」でやらかしたこと
- 4. 挽回のためにやったこと
- 5. 「しくじり編」の教訓3つ
- 6. 「スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう!」シリーズの最後に
- 7. バックナンバー
1. ご挨拶
こんにちは。
前回の「【本編】スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう! Vol.3 -自動化ワークフロー実装編-」までの本編完結後の箸休め的な番外編、「スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう!」シリーズの最終回を投稿します、@hayat01sh1da です。
ソフトウェアエンジニアとして、以下のサービスの進路・学事向け機能(e.g. アンケート配信機能、進路希望調査配信機能、面談ダッシュボード)を開発・運用・保守しています(for SCHOOL ブランドは先生の管理画面である「先生アプリ」の開発に従事)。

今回は、前回記事の次回予告 で頭出しをした、吹っ飛ばしてしまった GitHub Wiki の Revisions 復旧と前方互換性の確保のお話をしたいと思います。
今回はスクリプト言語やワークフローではなく、Git の概念のお話が中心になります。
2. 「スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう!」シリーズ
全4部作の構成でお届けしています!
blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp
3. 「しくじり編」でやらかしたこと
3-1. GitHub Wiki の Revisions の仕組みについて
GitHub Wiki には本体リポジトリにおけるファイルの History に相当するページの Revisions という編集履歴の概念が存在します。
GitHub Wiki も本体リポジトリ同様に Git でバージョン管理がされています。
「【本編】スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう! Vol.1 -泥臭い手作業編-」で Ownership ごとに Wiki を手作業で整理した話をしました。
私は手元の VSCode で Wiki を編集する派だったので、そのタイミングでファイル探索のしやすさを追求して Ownership 単位のディレクトリに Wiki を振り分けるという作業を行い、それを自動化するスクリプトまで実装しました。
その結果起きたことは... そう、振り分けられた Wiki の Revisions が消えてしまったのです。
泣く泣く 振り分けスクリプトはお釈迦となりました。
ファイルパスの移動は、Git の概念上「ファイルの削除 + 新規作成」として扱われます。
ファイルが削除された時点でそれまでの編集履歴は消し飛び、新規作成された時点からその後の履歴が記録されるので、パスを移動する以前の編集履歴は機構上閲覧出来なくなります。
実験してみましょう。
まず現在のディレクトリ構造はこのようになっています。
$ tree . ├── Home.md ├── Ownerチーム・要or不要が不明なページ.md ├── Owner記名ありページ.md ├── Owner記名なしページ1.md ├── Owner記名なしページ2.md ├── Ownerチームが不明だが必要なページ.md ├── _Sidebar.md
「Owner記名ありページ.md」に対して以下の差分を作ります。

当然ですが Git のログに記録が残ります。
$ git log
commit 6a4184ee0ad823ba31686d61d19b37b9ebe75dee (HEAD -> master, origin/master, origin/HEAD)
Author: Hayato Ishida <bin.lhkty.gtthj.o.zs+github@gmail.com>
Date: Wed Jan 29 18:22:29 2025 +0900
Updated Owner記名ありページ (markdown)
「Owner記名ありページ.md」を「「Owner記名ありページ群」というディレクトリに移動させてみましょう。
% mkdir Owner記名ありページ群/ % mv Owner記名ありページ.md Owner記名ありページ群/
移動後のディレクト構造は以下の通りです。
. ├── Home.md ├── Ownerチーム・要or不要が不明なページ.md ├── Owner記名なしページ1.md ├── Owner記名なしページ2.md ├── Owner記名ありページ群 │ └── Owner記名ありページ.md ├── Ownerチームが不明だが必要なページ.md ├── _Sidebar.md
ここで Git Status を見てみましょう。
$ git status
On branch master
Your branch is up to date with 'origin/master'.
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: "Owner\350\250\230\345\220\215\343\201\202\343\202\212\343\203\232\343\203\274\343\202\270.md"
Untracked files:
(use "git add <file>..." to include in what will be committed)
"Owner\350\250\230\345\220\215\343\201\202\343\202\212\343\203\232\343\203\274\343\202\270\347\276\244/"
ファイルの削除 + 新規作成として記録されているのが分かります。
この差分を GitHub Wiki にプッシュすると、Revisions はどうなるでしょうか?
# 差分を確認した上でワンライナーで処理しています $ git add -A && git commit -m 'Move Owner記名ありページ.md to Owner記名ありページ群/' && git push origin master

このようにそれまで存在していた Revisions は消えてしまいました。
このような破壊的変更を、私は300個以上の Wiki ページに対して行ってしまったのです。
何て初歩的で間抜けな失敗なのでしょうか 💧
Wiki の Markdown ファイルのパスが変わるタイミングは、手元の (git) mv コマンド意外にもあります。
ページタイトルは Markdown ファイル名と同期しているため、GUI 上で編集するとパスが変わり、同じく Revisions が吹き飛んでしまいます。

差分を確認するため、手元に最新状態を取り込んで Reset をかけてみましょう。
$ git reset --soft HEAD^
$ git restore --staged .
$ git status
On branch master
Your branch is behind 'origin/master' by 1 commit, and can be fast-forwarded.
(use "git pull" to update your local branch)
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
deleted: "Owner\350\250\230\345\220\215\343\201\202\343\202\212\343\203\232\343\203\274\343\202\270\347\276\244/Owner\350\250\230\345\220\215\343\201\202\343\202\212\343\203\232\343\203\274\343\202\270.md"
Untracked files:
(use "git add <file>..." to include in what will be committed)
"Owner\350\250\230\345\220\215\343\201\202\343\202\212\343\203\232\343\203\274\343\202\270\343\201\240\343\202\210\343\203\274\343\202\223.md"
ファイルの削除 + 新規作成として記録されているのが分かります。
3-2. ジレンマ over ジレンマ
「うわー、やっちまった!これでは Ownership や要・不要の判断をしようにも、編集履歴が閲覧出来ないからにっちもさっちもいかない。どうしよう... 😨」と気落ちする私をよそに、GitHub Wiki はどんどん更新されていきます。
その結果、以下のようながんじがらめの状態に陥りました。
- 続々と新規作成された Wiki はルート階層に配置されるので、ディレクトリに振り分けられた Wiki とそうでない Wiki が混在した一貫性のない状態になってしまいました。
- 変更に強く一貫性のある状態にするためにディレクトリ構造をフラットに戻したかったのですが、パスの移動が発生するため再度 Revisions が吹き飛んでしまうのでおいそれとは出来ませんでした。
- ディレクトリ構造整理スクリプトの実行だけ無効化した状態で GitHub Actions を動かせば破壊的な変更は発生しないが、変更に弱く一貫性のない状態の 1 の状態は受け入れ難かったので、どうにか 2 の状態に戻したいという願望が風化せず強く残りました。
多忙のため、この状態が2-3ヶ月ほど続いてしまいましたが、その放置している間に問題は解決することはもちろんありません。
冷静に戦略を立てて解決するしかありませんでした。
4. 挽回のためにやったこと
結論から言うと、恐れていたほど手強いものではなく、ものの1日で解決出来ました。
私が立てた戦略は以下の5つの手順を踏むことでした。
4-1. Issue に書き残した作業記録の日付を手がかりにコミット日時を特定した
普段 Working Out Loud を出来るだけ意識して作業ログを残していたことが幸いし、作業記録が Issue 上ですぐに見つかりました。
記録って大事!

4-2. 日付を手掛かりにロールバックする先のコミットハッシュを特定した
以下のコマンドを実行し、日付・コミットメッセージ・コミットハッシュ・コミッターをテキストファイルに出力しました。
$ git log --date=short --pretty=format:"%cd %s %h (@%cn) " >> history.txt
以下のようなログを取得し、Issue の作業記録と同日に件の破壊的変更を行なっていたことがいみじくも特定出来ました。
記録って大事!(2回目)
(省略: 実際は300件くらいありました) 2024-10-04 Remove deleted pages from Wiki list on Home and Sidebar 612b8781 (@hayat01sh1da) 2024-10-04 Destroyed ページ名 (markdown) b7f583bc (@Hayato Ishida) 2024-10-04 Destroyed ページ名 (markdown) a3e9eadd (@Hayato Ishida) 2024-10-04 Destroyed ページ名 (markdown) ec6ccfad (@Hayato Ishida) 2024-10-04 Replace invalud symbols as links with full-width charactors 95759503 (@hayat01sh1da) 2024-10-04 Categorise Wikis to directories by onwership unit 00fdffb9 (@hayat01sh1da) 👈🏻 これ! 2024-10-04 Organise Wiki list by ownership unit on Sidebar da38ffe4 (@hayat01sh1da) 2024-10-04 Organise Wiki list by ownership unit on Home 903aa544 (@hayat01sh1da) (省略)
4-3. トピックブランチを切ってロールバックと Cherry-Pick を行った
先の Git Log から破壊的変更を行なったコミットが取得できました。
当該コミットを含めてロールバックをしたいので、取得対象のコミットハッシュはもう1つ前の da38ffe4 です。
まずは既存の GitHub Wiki に影響を与えないように、作業用のトピックブランチを切ります。
$ git checkout -b hayat01sh1da/issue-83591/github-wiki-organisers-wiki/restore-revisions
次に、対象のコミットまでロールバックを行います。
$ git reset --hard da38ffe4
これで GitHub Wiki はディレクトリ構造がフラットな時代までタイムリープしました(おかえり)。
あとはひたすら Wiki の新規作成・更新・削除のコミットを1つひとつ300コミット分 Cherry-Pick していくだけです。
$ git cherry-pick 95759503 $ git cherry-pick ec6ccfad $ git cherry-pick a3e9eadd $ git cherry-pick b7f583bc $ git cherry-pick 612b8781 (省略)
コミットハッシュ 95759503 は件の破壊的変更の次のコミットのため、ディレクトリ構造がめちゃくちゃコンフリクトしました。
通常であれば解消してからコミットしますが、あえてコンフリクトごとコミットすることで、フラットなディレクトリ構造を強制的に取り込むことが出来ました。
ある時点で全 Wiki に Owner: @OWNER_TEAM を記入するコミットを積んだので、その差分がコンフリクトを起こしましたが、それ以外は本当にすんなり Cherry-Pick が出来ました。
予想では全300件分の Cherry-Pick でコンフリクトが起こると予想していただけに、これは嬉しい誤算でした。
4-4. GitHub Wiki へトピックブランチの作業内容を反映した
トピックブランチでディレクトリ構造のフラット化と Cherry-Pick が完了したので、master に反映させます。
万が一の場合がありますので、バックアップブランチ master-backup を切っておきました。
$ git checkout master $ git checkout -b master-backup
また、作業中に Wiki を新規作成・更新・削除されてコミットが積まれると整合性が取れない可能性があるため、関係者各位に「メンテナスのため、GitHub Wiki を合図を出すまで使用しないで下さい」という旨の周知をしました。
さて、準備が整ったので Rebase の時間です。
以下のコマンドを叩いて Rebase を試みましたが、言うまでもなくコンフリクトが大量に出ました。
$ git checkout master $ git rebase hayat01sh1da/issue-83591/github-wiki-organisers-wiki/restore-revisions
コンフリクトは先の作業でうんざりしていましたし、取り込むべき正の差分を理解していましたので、トピックブランチをマージする方式を取りました。
$ git checkout master $ git reset --hard da38ffe4 $ git merge hayat01sh1da/issue-83591/github-wiki-organisers-wiki/restore-revisions $ git push origin master
これでトピックブランチの作業内容が既存の GitHub Wiki に反映されました。
4-5. GitHub Wiki の Revisions を確認した
いくつか歴史がありそうなページをサンプリングして Revisions を確認しました。
以下はそのうちの1つですが、Wiki の新規作成時の履歴が復旧していることが確認出来ました。

関係者各位に作業完了と GitHub Wiki 使用の解禁の旨を連絡し、復旧と前方互換性の確保達成です 🎉
5. 「しくじり編」の教訓3つ
本体リポジトリと違い、GUI 上でディレクトリ構造やコミット履歴、ブランチを確認出来ないので忘れがちですが、GitHub Wiki も Git のエコシステムとライフサイクルの中で生きています。
そのことを忘れて犯した初歩的な大失敗をもとに得た教訓は以下の3つです。
- ファイルパスの移動は削除 + 新規作成である!
- GitHub Wiki は Markdown ファイルをディレクトリに移すべからず。ファイルパスが変わって Revisions が消えてしまいます ⚠️
- GitHub Wiki は容易にページタイトルを変えるべからず。同じくファイルパスが変わって Revisions が消えてしまいます ⚠️
- GitHub Wiki をメンテナンスする者はすべからく Git の機構を理解して保守すべし!
6. 「スクリプト言語と GitHub Actions で GitHub Wiki に秩序をもたらそう!」シリーズの最後に
今回トピックとして取り上げた題材は、エンジニアなら一度は扱ったことがある GitHub Wiki という身近なツールでした。
卑近だからこそ長所や短所に関する共感を得られ、負の解消のアプローチを自分事と捉えて頂き易いのではないかと思い、記事にさせて頂きました。
私自身も世の優秀なエンジニアの皆様のアウトプットの恩恵でこうしてお仕事が出来ていることに感謝しています。
今後もその恩返しとして、少しでも皆様のお役に立てる学びや教訓、技術的な Tips を得たら今後も記事にしていこうと思いますので、よろしくお願いします 🙇🏻♂️
7. バックナンバー
blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp blog.studysapuri.jp