matobaの学んだこと

とあるPythonエンジニアのブログ。ソフトウェア開発、執筆活動、ライフログ。

gitで特定の行がそうなっている理由を調べる

gitで特定の行がそうなっている理由を調べることがあります。

そういう時に使う git blame を紹介します。

調べたい行の行番号を確認する

今回は、djangoリポジトリを使います。

事前にgit cloneして起きます。

そのあと、調べたい行を見つけます。

今回は、以下の class Model(metaclass=ModelBase) が定義されたコミットを調べます。

github.com

django.db.models.Modelが定義されたコミットです。

行番号は、382です。

git blameでコミットを特定する

調べたいファイルと行番号を指定してgit blameします。

$ git blame -L 382,384 django/db/models/base.py
2b281cc35ed (Claude Paroz    2017-01-07 12:11:46 +0100 382) class Model(metaclass=ModelBase):
f69cf70ed81 (Adrian Holovaty 2006-05-02 01:31:56 +0000 383)
f69cf70ed81 (Adrian Holovaty 2006-05-02 01:31:56 +0000 384)     def __init__(self, *args, **kwargs):

-L が行を指定するオプションです。 今回は、そのオプションに、382行目から384行目を指定してます。

なお、指定しないと指定したファイルの全ての行が対象になります。

結果を見てわかるのは、Modelのクラスを定義したコミットは、「 2b281cc35ed 」だということです。

あと、initは2006年なのに、クラスの定義は2017年に変更されてます。

指定コミットの変更を調べる

指定コミットの変更を調べるために以下のコマンドを実行します。

$ git show 2b281cc35ed

結果は以下のようになります。長いので省略してますが、該当のコミットで変更された差分がわかります。ちなみにModelクラスが最後に変更されたコミットでは、 sixを外したコミットのようです。sixはPython2とPython3の互換性を保つためのライブラリです。今回調べているのは、djangoのmasterブランチです。先日、djangoのmasterで、Python2をサポートの対象外になったので、納得感があります。

$ git show 2b281cc35ed
commit 2b281cc35ed9d997614ca3c416928d7fabfef1ad
Author: Claude Paroz <claude@2xlibre.net>
Date:   Sat Jan 7 12:11:46 2017 +0100

    Refs #23919 -- Removed most of remaining six usage

    Thanks Tim Graham for the review.

diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index eaa9916056..2d4bbbb933 100644
--- a/django/contrib/admin/options.py
+++ b/django/contrib/admin/options.py
@@ -36,7 +36,6 @@ from django.http import HttpResponseRedirect
 from django.http.response import HttpResponseBase
 from django.template.response import SimpleTemplateResponse, TemplateResponse
 from django.urls import reverse
-from django.utils import six
 from django.utils.decorators import method_decorator
 from django.utils.encoding import force_text
 from django.utils.html import format_html
@@ -92,7 +91,7 @@ FORMFIELD_FOR_DBFIELD_DEFAULTS = {
 csrf_protect_m = method_decorator(csrf_protect)


-class BaseModelAdmin(six.with_metaclass(forms.MediaDefiningClass)):
+class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
...

終わり

たまには技術的な記事を書こうと思って、僕がよく使うgitのコマンドを紹介して見ました。

既存のライブラリやアプリケーションを修正する際、よくわからない行があると、それがいつ、なんの目的でそうなっているのかを調べると思います。そう言う時にgit blameは便利です。

git blameで見つかったコミットの時期を考えて、その時期の時代背景を考えると、色んなことがわかる。かマシれないです。

あと、自分のコミットは将来的にgit blameされると思って、きちんと意味のある単位にしておきましょう。