やったこと
Before:手動履歴管理
Googleマイマップから出力したKMLファイルをひたすらフォルダに溜めていました。ファイル名に日付を書く伝統的な履歴管理スタイルです。
エンジニアの端くれですがプライベートではこのざま
After:GitHubでのバージョン管理
GitHubでのバージョン管理に移行して、作業記録(コミットメッセージ)も付けました。
ドヤァ
過去時点のコミットをでっちあげる特殊な操作を行っているので、本記事では特にそのあたりの時間偽装テクニックを紹介しようと思います。
GitHubに移行するまでの軌跡
混沌
Googleマイマップを使って趣味で小字地図を作っているのですが、あいにくGoogleマイマップにはバックアップ機能がありません。そこでとりあえずファイルをエクスポートしてフォルダに保存していました。
冒頭で「ファイル名に日付を書く伝統的な履歴管理スタイル」だったと書きましたが、実は本当の最初はこんな感じでした……
ごみ箱ですか?いいえ、バックアップです。
つらい。
ファイル形式がバラバラ。.csv.kmz
とかいうのもあって最悪です。これをあれやこれやして全部.kml
に揃えました。
.kmz
から.kml
への変換
KMZファイルはKMLファイルのZIP圧縮なので、拡張子を.zip
に変更すると普通に展開でき、KMLファイルを取り出せます。
.csv
から.kml
への変換
小字地図作成の黎明期に Google Fusion Tables(現在は廃止)経由でダウンロードしたファイルがCSV形式になってました。
構造化データから非構造化データへの変換は流石に人力では無理なので、Pythonで適当なスクリプトを組んでマッピングしました。
過去時点のコミットをでっちあげる
バックアップファイルの形式を揃え終わったので、いよいよgitでコミットしていきます。
git環境構築やGitHubリポジトリ作成については本記事では触れませんので、そのあたりの解説は「GitHub 最初」とかでググってください。Macでのgit環境構築については過去記事でも軽く触れてます。
(以下、リポジトリ作成済みの状態とします)
一番古いバックアップファイルをローカルリポジトリに配置して、ファイル名をkusatsu-city-koaza-map.kml
にリネームします。
そして普通にgit add
します。
git add kusatsu-city-koaza-map.kml
次が重要です。過去時点でコミットしたことにするために、git commit
に--date
オプションを付けて日時指定でコミットします。
git commit --date="Feb 25 01:08:00 2012 +0900"
これでgit log
を確認すると
% git log commit ee276ac... (HEAD -> master) Author: fffw2 Date: Sat Feb 25 01:08:00 2012 +0900 野村・上笠・平井の一部の小字を追加
…と、コミット時に指定した日時が「Date」に表示されていて「うまくいった」と安心してしまうのですが、これは巧妙なトラップです!!
このままGitHubにプッシュしても残念ながら指定した日時では表示されません。
実はgitのコミットには2種類の日時が存在しています。
- AuthorDate:
git commit --date
で指定できるのはこっちgit log
で表示されるのはこっち
- CommitDate:
- GitHubで使われるのはこっち
git log --pretty=fuller
で CommitDate を見てみましょう。
% git log --pretty=fuller commit ee276ac... (HEAD -> master) Author: fffw2 AuthorDate: Sat Feb 25 01:08:00 2012 +0900 Commit: fffw2 CommitDate: Mon Oct 10 18:30:20 2022 +0900 野村・上笠・平井の一部の小字を追加
AuthorDateは10年前の日付(git commit --date
で指定した日付)ですが、CommitDateは現在の日付になってしまってます。GitHubで使われるのはCommitDateのほうなのでこちらも改変しなくてはいけません。
2種類の日付の齟齬を解消するには
git rebase HEAD~ --committer-date-is-author-date
を実行すればOKです。(ここのオプションはcommit-dateではなくcommitter-dateです)
% git log --pretty=fuller commit ee276ac... (HEAD -> master) Author: fffw2 AuthorDate: Sat Feb 25 01:08:00 2012 +0900 Commit: fffw2 CommitDate: Sat Feb 25 01:08:00 2012 +0900 野村・上笠・平井の一部の小字を追加
CommitDate=AuthorDate に書き換わりました。
あとは通常通り git push origin master
でリモートにプッシュすれば、GitHubに10年前のコミットが出現します。
他の日付のバックアップファイルについても同様の作業を繰り返しましょう。最終的にこんな感じになります。
ちゃんと過去に草も生えます。
(追記 / 2022-11-30)
GitHubのコミット履歴ではCommitDateが使われますが、プロフィールページに表示される草にはAuthorDateのほうが使われているようです。ややこしいですね。(参考) How GitHub uses the Git author date and commit date - GitHub Docs
On your profile page, the author date is used to calculate when a commit was made. Whereas, in a repository, the commit date is used to calculate when a commit was made in the repository.
歴史改変コマンドまとめ
% git add kusatsu-city-koaza-map.kml % git commit --date="Feb 25 01:08:00 2012 +0900" % git rebase HEAD~ --committer-date-is-author-date % git log --pretty=fuller % git push origin master
git log
は確認用コマンドなので慣れたら省略しても大丈夫です。
KMLファイルの差分の可視化
過去時点のコミットメッセージを書くためには当時の作業内容を思い出さなくてはなりません。当時の進捗報告ツイートの発掘の他、KMLファイルの差分比較を実施しました。
- Visual Studio Code の標準機能でKMLを差分比較
- 各差分箇所の
<styleUrl>
を書き換えて色を変える - VSCode Map Preview プラグインでプレビュー表示
という流れで、作業前後の変更箇所を可視化できます。
KMLファイルの差分は地図上で見るとわかりやすい
おわりに
Googleマイマップの編集履歴をGitHubでバージョン管理しました。
プロジェクト開始当初からバージョン管理していなくても、今回の方法を使えば「そろそろバージョン管理しようかな」と思ったタイミングでGitHubに移行できます。
「あの日は何をしたっけな〜」と頭を捻っていたら、サボり続けた夏休みの宿題の日記をあとから全部書いたときの記憶が蘇りました。大人になっても変わらないものですね。