LoginSignup
1
0

gitコミットにはタイムスタンプのほかタイムゾーンも記録されている

Posted at

gitのコミットにはタイムスタンプだけでなくコミットした環境のタイムゾーンも記録されている、という発見です。

gitコミットにはタイムスタンプだけが保存されており、タイムゾーンの表示は見ている人の環境に合わせて表示されているんだと思い込んでいました。しかしそうではなく、タイムゾーンもコミットごとにちゃんと保存されていました。なので、オープンソースのリポジトリのログを見ればいろんなタイムゾーンに開発者が散らばっている様子がわかります。

以下のの記事を読んで、タイムゾーンも保存されてるのか???って疑問から調べてしまったのが今回の記事のきっかけです。

確認した内容

ローカルにclone済みの適当なgitリポジトリを見ます。.git というディレクトリにGitログや過去のファイルがすべて保存されており、コミットの情報も含まれています。gitリポジトリの内容は .git がすべてです。

まず以下のファイルを見ます。

$ cat .git/refs/heads/main

最新のmainブランチのコミットのハッシュ値が書いてあります。40文字のSHA-1ハッシュ値です。このファイルがなくても .git/refs/heads/ の中の別名のファイルでもよいです。

ハッシュ値が例えば ca218c30e4ed29eb778f45c75faa2043708b143e だった場合、以下のファイルの存在を確認します。ハッシュ値の最初の2文字をディレクトリ名にして、残り38文字をファイル名にします。

$ ls .git/objects/ca/218c30e4ed29eb778f45c75faa2043708b143e

git gcを実行した直後だったり、 git clone したばかりの場合は、このファイルがない場合があります。かわりに .git/object/pack/ の中に圧縮されています。この中を見るのは面倒なので、その場合は別のリポジトリを見るなり、もしくはダミーで適当なコミットをしてみて、再チャレンジしてください。

.git/objects/ca/218c30e4ed29eb778f45c75faa2043708b143e はzlibで圧縮されています。Rubyのワンライナーであれば次のようにして展開できます。

$ cat .git/objects/ca/218c30e4ed29eb778f45c75faa2043708b143e | ruby -e "require 'zlib'; puts Zlib::Inflate.inflate(STDIN.read)"

Perlのワンライナーであれば次の通りです。

$ cat .git/objects/ca/218c30e4ed29eb778f45c75faa2043708b143e | perl -e 'use Compress::Raw::Zlib; undef $/;new Compress::Raw::Zlib::Inflate()->inflate(<>,$o);print $o'

Pythonのワンライナーであれば次の通りです。

$ cat .git/objects/ca/218c30e4ed29eb778f45c75faa2043708b143e | python -c "import zlib,sys;print(zlib.decompress(sys.stdin.buffer.read()).decode('utf8'))"

どの言語を使っても次のように表示されます。

commit 274tree c15e322196a5f6a9cd34ff42709848e649e156c6
parent 491c797feb18eff93d25fe19cb2a83bb399ec9d8
author suzuki-navi <...> 1689242567 +0900
committer suzuki-navi <...> 1689242567 +0900

dummy commit

これはダミーのコミット

コミットの情報がテキストで表示されます。 .git に所定のフォーマットのテキスト形式でコミット情報が保存されているのです。

最初の commit 274 は説明省略しますがコミット情報を .git/objects に保存するためのヘッダみたいなもので、そのあとの tree ... から後ろがコミット情報の本体です。 ... と書いた個所は本当はメールアドレスが載っています。

この中にタイムゾーンが +0900 というふうにテキストで記載されていることがわかります。ヨーロッパやアメリカなどタイムゾーンの異なる環境からこのリポジトリをcloneしてもこのコミットに関しては +0900 と表示されるはずです。へぇー。

補足 その1

今回の記事では .git/objects の中を直接見ましたが、以下のように git cat-file コマンドでも見ることができます。 git コマンドが出力をいい具合に整形しているという疑念を払拭するために、生データを直接見ることにしました。

$ git cat-file -p ca218c30e4ed29eb778f45c75faa2043708b143e
tree c15e322196a5f6a9cd34ff42709848e649e156c6
parent 491c797feb18eff93d25fe19cb2a83bb399ec9d8
author suzuki-navi <...> 1689242567 +0900
committer suzuki-navi <...> 1689242567 +0900

dummy commit

これはダミーのコミット

補足 その2

今回の記事の内容は、以下のドキュメントにだいたい書いてあります。コミット情報にある tree とか parent とかもだいたい説明されています。

以上。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0