ふれっしゅのーと

ふれっしゅのーと

趣味に生きる30代エンジニアが心に移りゆくよしなし事をそこはかとなく書きつくるブログ

過去時点のコミットをでっちあげて10年分のGoogleマイマップの編集履歴をGitHubに移行するまでの軌跡

やったこと

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ファイルの差分比較を実施しました。

  1. Visual Studio Code の標準機能でKMLを差分比較
  2. 各差分箇所の<styleUrl>を書き換えて色を変える
  3. VSCode Map Preview プラグインでプレビュー表示

という流れで、作業前後の変更箇所を可視化できます。


KMLファイルの差分は地図上で見るとわかりやすい

おわりに

Googleマイマップの編集履歴GitHubでバージョン管理しました。

プロジェクト開始当初からバージョン管理していなくても、今回の方法を使えば「そろそろバージョン管理しようかな」と思ったタイミングでGitHubに移行できます。

「あの日は何をしたっけな〜」と頭を捻っていたら、サボり続けた夏休みの宿題の日記をあとから全部書いたときの記憶が蘇りました。大人になっても変わらないものですね。

参考サイト