🐕

一日一処: 初心者にGitを教える時の個人的な正攻法

2024/02/18に公開

Gitを教える

4月の入社を控えて、それぞれのプロジェクトには、新しいメンバーが増えると思う。特に学生が多く、最近の学校では、Gitを教えているところも少なくない。それでも、まだGitに触れたことがない初心者がいることは確かだ。
そのため、私が行っているGitの教えかたを記載する。

Gitとは

Gitは、ソースコードを管理する仕組みだ。特に、複数の開発を同時並行で行い、その差分を記録したり、他の人が作ったソースコードを分離した状態で確認したり、最終的に一つのプログラムに合体させることができ、その変更履歴も確認することができるものだ。説明は、そこまで難しくないが、完璧に使いこなすのには、時間がかかる。そのため、初心者に対して、最低限のスキルを身に着けさせる。

教えるコマンド

初心者に教えるコマンド、以下のみだ。これ以外のことを教えたり、できるようにするためには、半年か、本人が慣れてきてからにする。

  • git clone
  • git checkout
  • git checkout -b
  • git status
  • git add
  • git commit
  • git push

git clone

リポジトリからのソースコードの取得。まずは、これをしないと始まらない。
以下のように、リポジトリのアドレスを用いて、既存のリポジトリをローカルにクローンさせる。リポジトリは、

git clone [リポジトリのアドレス]
# 例
git clone git@github.com:getExampleOrg/example.git

他にもオプションがあるが、まずはこれだけしか教えない。

git checkout

ブランチを切り替えるための仕組みとして教える。その他に、ファイルを取得したりと様々な使い方があるが、オプションを活用して、ミスに繋がるのは困る。

git checkout [ブランチ名]
# 例
git checkout main

ブランチ一覧を見るために、git branchコマンドが存在するが、これは、教えない。gitを扱う場合、殆どは、GithubやGitbucketなどのWebサービスを用いてるだろう。そのため、ブランチ名は、常に、Webページから参照させる。なぜならば、初回のクローン後には、main(master)リポジトリしか存在せず、git branch -aでリモートブランチも合わせて表示させた場合、想定していない名称(remotes/testbranch)でcheckoutしてしまい、おかしな状態になる人が多かったからだ。

git checkout -b

ブランチの切り出し。ブランチを作成する場合、常にmain(master)ブランチから行わせる。

git checkout main
git branch # ここでmainブランチ選択中だと確認させる
git checkout -b [新規ブランチ名]

初心者はどこか構わず、今の状況で、新しいブランチを作成する。こうなると、マージしなかったブランチから切り出されて、よくわからない、またはマージすべきではないコードを含んでしまうこともあるからだ。ブランチを作る場合は、このコマンドの過程を厳守させる。

git status

このコマンドも確実に必須にさせる。ブランチに含むべきファイルの確認は、リモートにシュッシュしていないかどうかの状態を確認させることが大切だ。

git status

更新してないファイルが登場した場合は、一報を行うように教育すべきで、その結果によっては、gitignoreを更新する。ただし、gitignoreの更新は、初心者には絶対にさせない。

git add

ステータス確認の後、コミットの前に行う。これ自体は、難しいコマンドではないが、慣れた人がよくする、以下のコマンドは、絶対に教えない。

# 教えないコマンド(すべてをステージさせる)
git add .
# 教えるコマンド(ファイル名はgit statusのファイルパスをコピー)
git add [ファイルパス]

ドットですべてをステージさせる方法を知ってしまうと、必ずgit statusは行わなくなる。その代わりに、git addでは、ファイルパスを知る必要があると教育すれば、自ずとgit statusを行うようになるため、癖になる。

git commit

ブランチに更新履歴を残すため、コミットを行う。これは、git addでファイルをステージしないとできないが、一連の作業として、status→add→commitと教え込めば、特に問題ないだろう。

git status
git add [ファイルパス]
git commit -m "AをBにするため、CをDのように変更"

この時、コミットメッセージを記述させる。「更新」など、当たり前の内容ではなく、「AをBにするため、CをDのように変更」という具合で、具体的に記述させる。理由は、もちろん簡単で、後から振り返ったり、全体の履歴を見たときに、どのコミットで変更したのかを理解するためだ。そのため、複数のファイルを更新した場合、一度にコミットするのではなく、関連する一連の処理に合わせて、複数のコミットに分けるように指示する。たとえば、「更新内容を明確に記述できる、最低限の関連する更新ファイルのみ個別にそれぞれコミットするように」といった具合だ。

git push

最後にgit pushだ。これは、私が10年ほど指導していて、初心者のミスが最も多かったコマンドだ。コミットを必ず一つ以上行って、プッシュさせる。そうでなければ、更新しなかったブランチがリモート上に溢れかえってしまうため、コミットを行わない限り、絶対git pushは実行させない。

git push

ただ、このコマンドのみでは、ローカルでクローンしたブランチは、プッシュできない。この記事を読むのは指導者側だと想定しているため、当たり前に感じるだろう。
ただ、ローカルにしかないブランチ(仮にmybranchだった場合)をプッシュする際に、このコマンドを実行すると、以下の表示が現れる。

fatal: The current branch test has no upstream branch.
To push the current branch and set the remote as upstream, use

    git push --set-upstream origin mybranch

To have this happen automatically for branches without a tracking
upstream, see 'push.autoSetupRemote' in 'git help config'.

この内容を読ませることを忘れてはならない。ローカルにて、リモートの送り先(プッシュ先)のブランチが登録されてない旨で表示されるエラー内容だ。
ただ、ここには、以下のコマンドが表示される。

git push --set-upstream origin mybranch

ローカルで新規作成したブランチをプッシュする際、このエラーを必ず表示させて、文中にある、上記のコマンドをコピーし実行させる。これは、何が何でも絶対だ。
これまでの初心者で起きていた問題は、オプション忘れ、リモートエイリアスの間違い、ブランチ名の誤植など様々だ。何を言いたいかというと、ローカルで作ったブランチが、わけもわからない状態で、リモートと同期されてしまうということが非常に多かった。
そのため、私の指導では、git pushをする際、いかなる場合においても、オプションなど記述せずに実行し、表示されたコマンドをコピーして実行することだ。

終わりに

ここまで紹介したgitコマンドは、多くの人にとって当たり前の内容だろう。そして、これを読んでいる指導者側にとって見れば、稚拙で、更に便利なコマンドも知っていることだろう。ただ、初心者は違う。初めて触る人間にとってみれば、どれも複雑怪奇だ。そのなかで、様々なコマンドを教えると、大きな問題を生んでしまう。状況が悪ければ、mainブランチに直接コミットしていたり、中身が消えたりと、CI/CDなどを設定している場合では、最悪な状態に陥ることも考えられる。
これらのコマンドだけで、数ヶ月はまともに業務ができるはずなので、まずは最小限にミニマムに、余計なコマンドは書かせない、覚えさせない、というところから、新メンバーには教育してほしい。

Discussion