皆さんはGitを問題なく使えているでしょうか?
時おり社内で「リポジトリが何だかおかしくなってるんです~」と相談を受けることがあります。 コミットログが思ってたのと違う状態になっていて、さらに元に戻そうとアレコレやって状況悪化。 最終的に、どうにもならなくなっちゃったって感じです。
たいていは単純にGitの操作ミスによるものです。でもGitについて正確に理解していれば、ちょっとした間違いはすぐに元に戻せるはず。 裏返せば、Gitの仕組みや概念を正確に理解できておらず、「なんとなく」Gitを使っている人が多いのでしょう。 Gitのコミットやブランチについて明確なイメージを頭の中に描けていないように思います。
ところがこの春、新型コロナの影響で、弊社も「基本的にはテレワーク」と指示が出まして不安が的中。既にちらほら問題が発生してます。
ということで「Gitが不安、難しい」と思っている人たちのために、最初にキチンと理解しておいて欲しいことや、基本的な使い方を書いておきます。 ちなみに、Gitを難なく使っている人にとっては当たり前のことしか書いていません。
- masterブランチで作業しないで
- いろんな変更を詰め込まないで
- masterブランチをpushしないで
- 他人のワーキングブランチにコミットしない
- rebaseしないでmergeして
- プルリクのマージを急かさないで
- 勝手に安易にリファクタリングしないで
masterブランチで作業しないで
いちいち「この作業はブランチを切って行えばよいですか?」って聞いてくる人がいますが、これ当たり前なんですよね。 なにか作業するにはワーキングブランチを作成して、そのブランチで行ってください。
ワーキングブランチのベースをどこにするかは、採用しているフローに依存します。 弊社では GitHub Flow でやりましょうとなっているのでベースは必ず master です。 この点についてはチーム内で取り決めがあるはずですし、なければ取り決めておくべきですね。
GitHub Flowでは、作業内容を具体的に表す名前をワーキングブランチに付けるべきだとなっています。 そして早い段階で(コードを変更していなくても)リモートにpushしておきます。 これによって、チーム内に「自分が何をしようとしているかを知らせる」ためです。
いろんな変更を詰め込まないで
たくさんのコードを変更して、一発巨大なコミットをぶちかますのはやめてください。 また、ひとつのワーキングブランチで、色んな種類のコミットを積み重ねるのもやめてほしい。ワーキングブランチの変更内容は首尾一貫している必要があります。
その時の作業に無関係な部分で「あら、ここのインデントおかしいやん」とたまたま発見しても、そのまま流れで修正しないでほしいのです。 これをやると、後のmergeやrebaseでCONFLICTが発生しやすくなって、割ととんでもない手間がかかります。 本筋から外れた問題を見つけたときは、忘れないようにIssueを書いて、本来の作業に戻りましょう。
これらを正しく行うには、キチンと作業の計画を立て、短期のゴールを見定めて、それに集中する必要がありますよ。
masterブランチをpushしないで
複数人のチームで開発しているとき、masterブランチを前に進めるのはプルリクだけに限定したい。 緊急のBugFixなどでは、この限りではありませんが、少しでも時間的に余裕があるならプルリク投げてマージしたい。
主な理由はレビューできないからですが、チーム内に「masterが前に進む」ということを周知できるのも理由のひとつ。
同じ場所で作業している場合に、声を掛け合ってワーキングブランチをローカルでmasterにマージして、pushするケースは確かにあります。プロジェクトの初期段階では特に。 でも、リモートワークでメンバーがバラバラな状況で、さらにGitの操作に慣れていない人がいる場合などでは、正統にプルリクを投げてレビューしてからマージするのが筋というものです。
複数のコミットが連なったブランチを直接(プルリクを投げないで)レビューする時、レビュアーはレビュー対象のブランチを手元にチェックアウトしてHEADとベースブランチの差分を確認する必要があります。 GitHubなどのサービスでは複数コミットの差分をまとめて確認しにくいので。
他人のワーキングブランチにコミットしない
他の人のワーキングブランチをチェックアウトするのは構いません。コードを確認したりするだけですから。 でも、そのブランチに変更を加えてコミットした上で、push しないで欲しいのですよ。
これって論外だと思うのですが、おそらくワーキングブランチとは何であるかを理解できていないのでしょうね。
ワーキングブランチは、それを作った人の責任においてコーディング作業が進んでいるものであって、途中から無言で他の人が別の変更を加えちゃうと、その時点で枝分かれしてしまいますよね。 ブランチのオーナーは最終的に複数のコミットをまとめようとしているかもしれませんし。 とにかくワーキングブランチは途中段階の中途半端な状態なので、本人から移譲されたのでない限り、勝手に変更を加えるようなものではありません。
他の人のワーキングブランチが自分にとって必要であるならば、きりの良いところでプルリクを投げてもらってmasterへマージしてもらうように依頼するべきです。 そして、そのプルリクがマージされたあとに、自分のワーキングブランチへマージするべきです。いずれにせよ無言でしれっとやるのはご法度です。
ワーキングブランチを早い段階でリモートにpushしておくのは「私はこういう作業をしていますよ」ということをチーム内に表明するためです。
今まで未遂も含めて何度か経験しています。 一度はそのブランチがmasterにマージされていて驚きました。 怖いよ初心者w。まあその後問題が出なかったので良かったけれど。
rebaseしないでmergeして
ワーキングブランチで作業中に、リモートのmasterが前に進んでいることがあります。 このとき自分の作業が終わってプルリク投げる時などに、新しいmasterにrebaseする(ワーキングブランチのベースブランチを新しいmasterに切り替える)のはやめて欲しいのです。
じゃあどうするか。その時点でコンフリクトが発生する可能性があったり、新しいmasterに加えられた変更が自分の作業に必要であったりするなら、新しいmasterをワーキングブランチへmergeすれば良いのです。 逆に、明らかにコンフリクトが発生しない場合や、自分の作業に無関係な変更であるなら、何もしなくても構いません。
コンフリクトが発生するかどうかの判断は、少し難しいかもしれません。 なので同じファイルを変更しているかどうかで判断すれば良いと思います。 同じファイルを変更しているなら良いタイミングで新しいmasterをワーキングブランチにmergeする。 そうでないなら何もしなくてOKです。
rebaseをやめて欲しい理由のひとつは「際限がない」からです。 複数人で開発している場合、作業中にどんどんリモートのmasterは進んでいくと思います。 その時に、いちいちrebaseするのは手間ですし、コンフリクトが発生しそうなときだけrebaseするという対応も、状況によってベースブランチが変わるなんて、おかしな話です。
ちなみにmasterとの間でコンフリクトが発生したら、その解消時に尊重されるべきなのはmasterブランチのコードです。 masterブランチに取り込まれた時点で、それは「みんなが認めた正統なコード」ですからね。
プルリクのマージを急かさないで
プルリク投げてマージを急かす人がいますけど、あれも困ります。
あとの作業にそのブランチがマージされる必要があると懇願されたことがあるのですが、それってプルリク投げるタイミングでないかもしれません。 切りの良いところで、一旦プルリクを投げておきたいのであれば、その後も同じブランチで作業すればよいのです。 そのブランチでの作業はまだ終わっていないということですから。
勝手に安易にリファクタリングしないで
全体の構成を変更したり、命名規則を修正したりするリファクタリングに類することは広範囲に影響を及ぼしますから安易にこっそりやるべきではありません。 チーム内に注意を促してタイミングを見計らう必要があります。
また個々のコミットの変更内容を、極力あとでリファクタリングする必要がないように気をつけるのも必要です。