- 投稿日:2021-08-06T18:52:15+09:00
【Git】commitの粒度
この記事で書きたいこと 「commitの粒度ってどうすればいいの?」という質問に対して考えたことを書こうと思います。以前は「意味ある単位でコミットしよう」などとしか言えなかったのですが、Gitを何年か使ってきた中で、なんとなく、こういう時はこういう単位だと嬉しいなと言語化できる部分が増えてきました。私の経験からの記事になります。一人の意見として参考になればと思います。 どんな人向けの記事なのか 「Gitは普段使うのに困らない。commitは意味のある単位で細かくしてね、とは言われるけど、具体的にどんな単位?」と思っている方向けの記事になります。Gitのコマンドの説明などは行いません。 どんな単位が良いのか 「この単位が良い!」というよりは、いくつか検討するポイントがある、といった感じです。具体的には以下のポイントです。 エラーがなく動く単位でコミットする コミットする時点で実際に動かしてみたときにエラーが発生しない、というのは一つのチェックポイントになると思います。 エラーが起きないと何がいいのか 主に障害対応でコミットを1つずつ遡って検証する際に、動かないコミットがあるとそこで検証がストップしてしまいます。そのエラーが「中途半端な状態でコミットしたがゆえに起こっているエラー」とわかれば良いのですが、わからないことが多いと思います(そのコミットを行った本人であればいいかもしれませんが、本人であっても忘れていることも当然あります)。実際には、それがなんのエラーなのか調べることになり、本来の検証を進めることができなくなってしまいます。 静的解析、単体テストも含められるとより良い 静的解析の修正結果や単体テストの修正も、コード修正のコミットに含められると良いと思います。これも上記と同じような理由になります。そのコミットに戻してそこから作業したい、といった場合、静的解析でエラーが発生する、単体テストが動かない、となってしまうと、そのコミットのコードはOKであってもそのコミットに戻す+αの作業が発生します。 また、特に単体テストの改修がコミットに含まれていれば、その修正に対するテストが行われていること、どのような観点でのテストが行われているのかがレビュアーにも伝わりやすくなると思います。 エラーが起きなければコミットが大きくなっても良いのか ここが難しいところだと思いますし、チームや人によっても違うと思います。このあたりがよく言われる「意味のある単位でコミットしよう」ということだと思います。 例えば以下の3つに変更を加えるタスクがあるとします(なんとなく雰囲気で捉えていただけると嬉しいです・・・)。 UI UIから呼び出す関数 その関数が使っているサービス この場合、私だったら、 UI + UIから呼び出す関数 + これらにまつわる単体テスト + 静的解析で1コミット、その関数が使っているサービス + 単体テスト + 静的解析で1コミット、の2コミットに分けます。単体テストの単位がこんな感じになりそうだな、というのと、サービスはUIに依存せずに独立したものになるはずなのでコミットとしても分けています。 後で見たときになんでこの変更を入れたのかがわかる単位 「なんでこんなコードなんだっけ?」というときに、 git blame してコミットIDを調べ、 git show <commit-id> でそのコミット全体を見てみる、といったことをする場合が私はあります。そのときに適切なコミットメッセージ(Bug fixとか指摘対応とかではなく)が入っており、そのメッセージにあっている変更であれば、作業が捗ります。ここについては「具体的にこういう単位」とまだまだ言語化できていないのですが、自分がコミットIDからコミットを探すような行動をとることがあった場合に考えてみると、後の自分のコミットに役立つかもしれません。 renameやファイル移動などの機械的な変更は別コミットにする 例えば先ほどの、UI〜サービスまで手を入れる場合に、サービスの関数名をより良いものに変更しようという場合があると思います。もしくはファイル名を変えたり、ファイルの階層を移動するといったことがあるかもしれません。このような場合は、実際のサービスの修正とは別に、renameやファイル移動の変更単体で(静的解析や単体テスト込みで)コミットします。 renameやファイル移動でコミットを分けると何が嬉しいのか レビューがしやすくなります。レビューをする場合に、コミットごとに変更内容を見ていくことでレビューがしやすくなります。そのときに、renameやファイル移動のコミットがわかれていると、本来レビューしたいロジックの変更などに着目しやすくなります。renameやファイル移動に関する修正点って意外とありますよね。その修正点を別にしておけるのはとてもメリットがあると思います。 また、renameやファイル移動を万が一ミスしてしまっている場合、コンパイル言語であればコンパイルの時点でエラーが出るでしょうし、そうでなくても実際に動かせばエラーになると思います。そのため、どんな名前に変更したのか、については興味があっても、renameの漏れやimport文の修正はさらっと確認するレベルで良いと私は思っています。この点からも、コミットを別にする利点はあると思います。 レビューの指摘対応は指摘ごとにコミット レビューで指摘を受けて修正する場合、指摘ごとにコミットをするようにするとよいと思います。そうすることで、指摘に対してどのように対応したのかをレビュアーが確認しやすくなります。そして、指摘の意図を理解して、どういう意図で変更したのかをコミットメッセージに入れると良いと思います(コミットメッセージに「レビュー指摘対応」とだけ入れてしまうと、後でコミットを見直すときに何が目的でこの変更を入れたのかがわからなくなってしまいます)。 とはいえ、完全に指摘ごとにコミットを分けてしまうと、指摘コメント=コミットの数が増えるということで細かくなりすぎる場合もあります。指摘の理由が同じであれば対応箇所が違う行やファイルであっても同じコミットにしてしまって良いと思います。 タスクに関係がない修正は別コミットにする、もしくは別プルリクにする ボーイスカウトは素晴らしい タスクを行なっている中で、タスクには全然関係ない改善点を見つけることもよくあると思います。typoとか。コメントと実装の内容があっていないとか。気づいたときに直していくという行動はとても素晴らしいと思います。そして、コミットも別にしておくとさらに良いと思います。 やはりレビューがしやすい これもrenameを別コミットにするのと同じ理由です。レビューする人からはレビューしやすくなります。また、万が一修正したコミットが間違っていた場合(そしてこのコミットにtypoの修正も含んでいた場合)、そのコミットをrevertするかもしれません。そうすると、間違っていた内容と一緒に「間違っていない修正(ここではtypo)」まで失われてしまいます。 コミットを分けてさらに別プルリクにするのもあり 今やっているタスクとは別のプルリクにするのもありだと思います。私であれば、typoはタスクのプルリクに含めてしまうことが多いです。コメントの間違えなどは、単純なミスのようなもの(その引数は存在していないとか、返り値の型が違うとか、typoとか)はタスクのプルリクに含めてしまいますが、「これは・・・なんか違う?」というようなちょっと検討が必要な場合(その関数の読み込みをしたいときなど)や、なぜこのコメントが間違っているのかを詳しく説明しなければならない場合(この場合はそもそもコメント変更だけで済まない場合もあると思いますが)は、一旦置いといて別プルリクにすることもあります。また(タスクに関係がない)renameやロジックの変更などは完全に別プルリクにしています。 タスクに関係がないものはどんな小さい変更であっても別プルリクにしましょう、というチームもあると思います。この辺はチームにとってやりやすい方法が変わってくると思います。 コマンド実行による変更は1つのコミットにする チームやプロジェクトによっては、よくある変更を簡単に行えるようスクリプト化しているといった場合や、コマンドを実行することによってコードに修正が入る、といったこともあると思います。そういう場合はそのコマンド(やスクリプト)を実行した結果を1つのコミットにして、コミットメッセージには実行したコマンド(やスクリプト)を入れておくと良いと思います。同じチームのメンバーであれば「ああ、あれね」といった感じで伝わりやすいはずです。 コミットメッセージに困るようであれば単位を見直すべきかもしれない 以前、私はこれがよくありました。小さい単位でコミットしようとしすぎて、コミットにメッセージをつけられない現象です。コミットメッセージにはなぜ(Why)を書くと良いと言われています(ここでは説明を省きます)。思いつかない場合は、もしかするとコミットしようとしている粒度が小さすぎて意味をなしていないのかもしれません。もう少し実装を進めてみる、もしくは一度コミットしておいて後で見直してみると良いかもしれません。 以上5つのポイントについて説明しました。 コミットしてはいけない、ということではない コミットの粒度などについて考え始めると、なかなかコミットができなくなる、といったことが起こるかもしれません。ですが、それでコミット漏れがあったり、pushできないまま翌日休むことになり誰にも作業を引き継げなかった、などが起こると本末転倒です。コミットの粒度を考えられるというのは、作業の段取りができていたり、作業の見通しが立っている、ということが前提にあるとも思っているので、明日すぐできるのかというと難しい部分があると思います。 慣れてくれば意識せずとも粒度を考えてコミットできるようになると思います。コミットは後で修正することも可能ですし(この後説明します)、最初から完璧に行わなければ開発が進まないといったものでもありません。ちょっとずつ意識しながらよりよくしていく精神で、緩くいくと良いと思います。 便利なコマンド このようにコミットの粒度について考え始めると、一度したコミットを修正したい場合が出てくると思います。そんなときに便利なコマンドです。ここではコマンドの紹介に留め、使い方については省略させていただきます。 rebase git rebase -i <commit-id> HEADから commit-id までのコミットをまとめたり消したり順番を変えたりコミットメッセージの編集をしたり、などできます。「今日はも業務終了だからできたところまでpushしたい」といって作業途中でコミットした場合や、静的解析忘れていた!という場合など、後から修正することができます。とても便利です。 rebase は既存のコミットを修正してしまいます。revert コマンドでコミットを消す場合は「コミットを消した」という記録がコミットとして残りますが、 rebase はそのような記録が残らずコミット自体を書き換えてしまいます。そのため、他のメンバーと共有しているリモートブランチの内容を勝手に rebase で書き換えたり、開発の最新が詰まっているブランチやましてやmasterやmainに対しての rebase はNGです。チームの運用方法によると思いますのでご注意ください。 最後に 最後になりますが、コミットの粒度やコミットメッセージなど、凝りすぎるとミスります。お気をつけください。 また、記事の中でも何度か書いておりますが、これが正解、というわけではありません。開発スタイルやチームのメンバーによって、何がチームにとってプラスになるのかは変わってきます。 一つの案として、悩んでいる方の参考になれば幸いです。
- 投稿日:2021-08-06T17:38:29+09:00
GPG 鍵のメールアドレスを更新する
GCP鍵のメールアドレスを更新する記事があまり(目立った)文献がなかったので備忘録で書きますわよ! GitHubなどのメールアドレスを変えると GitHubのメールアドレスを変更するとgcpで登録したメールアドレスと一致せず、Unverified(未署名) になってしまいます。 GitHubのメインのメールアドレスを更新したらgcp鍵も更新しましょう。 gcp鍵のメールアドレス更新 基本的にWindows(Command PROMPT)で行います。 MacやLinuxなどでやる場合は個人で解釈を 1. ターミナルを開く ターミナルを開きましょう。 Win+R で開くファイル名を指定して実行 に cmd といれて起動しましょう。 2. GPGキーIDをコピー ターミナルで次のコマンドでGPGキーIDリストを出しましょう。 $ gpg --list-secret-keys --keyid-format=long C:/Users/piki0/AppData/Roaming/gnupg/pubring.kbx ------------------------------------------------ sec ~~~/GPGキーID 2021-06-27 [SC] GPGキーID をコピーする 3. ユーザー情報の編集 $ gpg --edit-key GPGキーID $ gpg> adduid 4. 指示に従って本名、メールアドレス、あればコメントを入力 よろしければ o で確認をしたあと、パスフレーズを入力します。 5. 保存する $ gpg> save 6. gpgキーを出力 Ctrl + Q で $ gpg> から抜けます。 gpg --armor --export GPGキーID で GPG キーを出力します。このキーをコピーしましょう。 7. GitHubアカウントへ追加 Settings > SSH and GPG keys > New GPG key Key の欄に貼り付けて Add GPG key をクリックで完了。
- 投稿日:2021-08-06T16:39:09+09:00
Gitを活用した共同開発の方法
Gitとは 共同開発を可能にするターミナル上で利用するツール 共同開発のステップ コードを変更する 共有する準備をする 共有する Gitの利用 git init:Gitを利用するために、ターミナルにて最初に実行する
- 投稿日:2021-08-06T16:39:09+09:00
初級:Gitを活用した共同開発の方法
Gitとは 共同開発を可能にするターミナル上で利用するツール 共同開発のステップ コードを変更する 共有する準備をする(コミットと呼ばれる作業) 共有する(リモート / リモートリポジトリと呼ばれる共有ファイル置き場にて共有) 共同開発のステップはこの4コマンドのサイクル add→commit→push→pull→ addに戻る。※以降、繰り返し。 add = 自分が作成したコードを選択し commit = メッセージをつけて記録し push = 共有リポジトリにアップロードする pull = 共有リポジトリからファイルをダウンロードする Gitに関するターミナルコマンド Gitを利用するために、ターミナルにて最初に実行する git init 共有するためにGitに追加する git add git add index.html 選択したファイルをメッセージをつけて記録する git commit -m "メッセージ" git commit -m "index.htmlを作成しました" 共有で作業するリモートリポジトリに登録する git remote add リモートリポジトリ名 URL git remote add origin https://example.com/mysite.git リモートリポジトリにファイルをアップロードする(プッシュする) git push origin master リモートリポジトリのファイルをダウンロードする git pull origin master
- 投稿日:2021-08-06T12:13:12+09:00
.DS_Storeファイルとは?
.DS_Storeファイルってなに?? 全てのフォルダにMacで自動生成されるようになっており、フォルダやファイルに関するmeta情報が格納されている。(フォルダ内のアイコンの位置や表示設定など) .DS_Storeは隠しファイルであるため、通常の使い方であれば表示されることがありませんが、隠しファイルを表示している設定している場合がある。 どう隠すか。 .gitignoreに記述してgitの管理から外す。 .gitignoreとは。 Git の管理に含めないファイルを指定するためのファイル。 -1 .gitignoreの作成 $ touch .gitignore -2 .gitignoreの記述 .gitignoreの記述 -3 キャッシュの削除 $ git rm -r --cached . -4 push $ git add . $ git commit -m "create .gitignore" $ git push origin master 参考記事
- 投稿日:2021-08-06T09:18:23+09:00
【Gitエラー解決】warning: LF will be replaced by CRLF
事象 Git/githubで個人開発を進めていたところ『warning: LF will be replaced by CRLF』というエラーが発生してgit add コマンドが動かなくなってしまった。 warning: LF will be replaced by CRLF in log/error_2018-11-04.log. The file will have its original line endings in your working directory 原因 改行コードがLFからCRLFに置き換えられようとしている模様。 対応方法 以下のコマンドを実行で無効にできました。 git config --global core.autoCRLF false そもそも改行ってなんだ 改行ってbrタグとかじゃないんですか????LF/CRLF????というような、 という状態だったので調べてみました。 HTMLファイル(css/JavaScript/image)はパソコンやモバイルのブラウザのレンダリングエンジンによって解釈され表示されるようです。 単純に『HTMLファイル内で改行があったから』改行するのではありません。 つまりブラウザ側でレンダリングされる時に『ここで改行した状態で画面上に表示してね』と表すのがbrタグの役割のようです。 じゃぁLFやCRLFって何なんなのか・・??? 上記で説明した『HTMLファイル内で改行があったから』という部分を示すものが改行コードになります 。 分かりやすい例で言うと、エディタ等で改行をボタンを押すと以下のような記号『↩︎』表示がされる場合を思い浮かべると良いかもしれません。 これが改行↩︎ コンピュータに改行があると伝えます↩︎ コンピューターに改行を知らせる このように文字列の改行するところには、改行コードという見えない特殊文字が入っています。 その一方で残念なお知らせがありました。 コンピュータの世界で改行コードが統一されていればよいのですが、あいにく、統一されていないのです。 以下はwikipedia先生より。 ASCII文字コードに基づくシステムでは、CR(復帰、0x0D)、LF(改行、0x0A)、またはCR+LFで表している。 LF: UNIXやUnix系のシステム。Linux、AIX、Xenix、macOS、BeOS、Amiga、RISC OSなど。 CR+LF: CP/M、MP/M、MS-DOS、OS/2、Microsoft Windows。 CR: コモドールによるシステム、Apple IIファミリ、Mac OS(バージョン9まで)、OS-9。 改行コードには種類があります。 そのため、対応している改行コードでないと正しくコンピュータに読み込ませることができないのです。 今回のケースでいうとLFという改行コードが自動的にCRLFに置き換えられてしまったことが原因のようです。 まとめ 今回のように調べれば簡単に出てくるエラーでも一歩踏み込んで『このエラーはどういう意味なのか』『解決コマンドによってどう変わるのか』『そもそもどういう仕組みなのか』というところまで勉強していくことで少しづつ理解できる範囲が広がっていくのだなと実感しました。 引き続き頑張ります。