新人指導に役立つ！？初めてのGit学習と、躓くポイントのケーススタディ

この記事は、[NTTコムウェアAdvent Calendar 2021](https://qiita.com/advent-calendar/2021/nttcomware) 10日目の記事です。

##はじめに
NTTコムウェアの杉本です。
文系学部出身の駆け出しSEとして、iOSアプリ開発のプロジェクトに参画しています。

本記事では、配属後初めに**Git学習で実際に躓いた箇所を、ケーススタディとして書き留め**ました。

Gitに関する記事は世の中に数多ありますが、
本記事は純粋にGitのコマンドのみを解説した記事ではなく、関連したコマンド操作を含め、
**「新人が躓きやすいポイントを知る」**
という点に特化した内容になっています。



##本記事の想定読者
・**非情報系の新人を育成**する立場にある方
・**新人研修**の内容を企画している方
・**非情報系の新人**


##GUIかCUIか問題
バージョン管理システムにGitを採用する際、GUIで直感的に操作するか、はたまたCUIでコマンドを使いこなすのか、判断が分かれるところだと思います。
プロジェクトによって考え方はまちまちですが、特に新人研修で教える場合、
**CUIを強くオススメします。**

##新人研修におけるCUIのメリット
私がCUIでのGit学習を薦める理由は全部で３つあります。

**1．CUI→GUIで覚えるのは楽だが、逆は辛い**
**2．コマンドでの操作に慣れると何かと便利**
**3．作業内容を容易に共有出来る**

それでは順番に見ていきましょう。

###1．CUI→GUIで覚えるのは楽だが、逆は辛い
GUIを普段使っていたけど、CUIを勉強することになり、ひどく難しく感じた経験をした方も少なくないかと思います。
特に新人に関しては、難しい方から勉強させるメリットは大きいと思います。
また、**CUIをマスターした後にGUIに慣れるのは比較的楽**です。

###2．コマンドでの操作に慣れると何かと便利
CUIを採用するメリットはGitの学習だけに留まりません。
**ターミナル（コマンドプロンプト）の黒い画面に対して抵抗感を持ってしまう新人は少なくない**です（自分がそうでした）。
しかし、実際に業務を行うようになるとターミナルを操作する機会は多いはずです。
例えば、

・IPアドレスを調べる
・podファイルの操作をする

直近では上記の場面でターミナルを使用しました。これらをアプリなどで行うことも可能ではあります。
しかし、特に**環境設定の際には、コマンド入力は避けられない**こともあるので、早めの段階でコマンドに慣れておくことのメリットは思いのほか大きいです。

###3．作業内容を容易に共有出来る
GUIでGitを使う場合、内部の動きが見えないためエラー時の対処が比較的難しい場合があります。
一方、CUIでは、「どういうコマンドを打っていてどういうエラーが返ってくるのか」を言葉にしやすく、**画面を見せれば一発で解決出来る**というメリットがあります。
非情報系の新人にとって、**起きている問題を言葉で伝えるのは想像以上に難しい**です。そのため、状況を即座に共有出来るCUIは重宝します。

#新人に教えたい超基本コマンドと落とし穴
ここからは、新人が知っておいて絶対に損はない基本的なコマンド類と、陥りやすいエラーについて、実際の経験を元に解説していきます。
なお、今回扱う範囲は**「ディレクトリ作成～コミット」**です。

新人が引っかかりやすい部分を、
**:beginner:ここで引っかかる！**

しっかり指導することで後々のためになる部分を、
**:exclamation:しっかり教えたい**

上記の様に表現していきます。

##ディレクトリ作成
```
$ mkdir ディレクトリ名
```
いきなりですが、

**:beginner:ここで引っかかる！**

どこで躓いてんだ、と思うかもしれませんが、非情報系新人はこんなものです。
いきなり出て来るナゾの文字列を入力し間違い、ディレクトリの作成が出来ていないなんてこともあります。
初っぱなから躓いた新人に動揺しながらも、「make directoryの事だよ」と優しく教えてあげましょう。
`mkdir`以外にも英語や略称の類いは、その意味まで教えたり、あるいは調べさせたりすることで、その後の理解度が変わってくると思います。


##階層の移動
```
$ cd ディレクトリ名
```
**:exclamation:しっかり教えたい**

今度は、しっかりと指導しておきたいポイントです。
`$ cd　ディレクトリ名`で作ったディレクトリに移動するだけでなく、

```
$ cd ..  　 上の階層へ移動
$ cd ../..  ２つ上の階層へ移動
```
これくらいの情報を教えておけば、階層の中で迷子になっても、自力で一つ一つ移動して目的地にたどり着くことが出来ます。
慣れてきたら、相対パス、絶対パスの説明も併せて行いましょう。
今となっては当たり前すぎて意識しないことも、新人の頃は難しく感じるものです。
ちなみに私は階層で迷子になったとき、先輩から階層を紙に書いて整理してもらったことを良く覚えています。

##ステージングエリアへの追加
```
$ git add
```

**:beginner:ここで引っかかる！**

ステージングエリアへの追加でも躓きポイントがあります。
たとえばファイルへの変更を加えた後に`git add`だけ行うと、

```
$ git add（空白）
Nothing specified, nothing added.
hint: Maybe you wanted to say 'git add .'?
hint: Turn this message off by running
hint: "git config advice.addEmptyPathspec false"
```
このようなメッセージが表示され、何度繰り返しても`add`出来ません。
そのため、ステージングエリアへの追加を行うときは最低限以下を教えると良いです。

```
【対象の1ファイルを追加】
$ git add ファイル名

【カレントディレクトリにある全てのファイルを追加】
$ git add .
```


##ステージングエリアの内容をリポジトリにコミット

```
$ git commit
```
**:beginner:ここで引っかかる！**

初心者でありがちなのが、ファイルの内容を変更した後、ステージングエリアの追加を行わずにコミットを行ってしまうことです。
`add`する前に行ってしまうと、

```
$ git commit
On branch master
Changes not staged for commit:
```
このようなメッセージが出てコミットできず、慌ててしまいがちです。
ただ、**エラーが出てきたときにパニックにならず、エラーの内容を読める様にする**ためにもこのような間違いは決して無駄ではなく寧ろ一度は遭遇したい問題です。

##git status

```
$ git status
```
上記の様なエラーを出さないようにするためにも、**ステージングエリアの状態を見てからコミットすることを意識付けさせたい**ですね。

また、`git add`の前後でステージングエリアの状態を確認するよう指導してみてください。
どこにどのようなメッセージが出るかを知り、**英語で出るメッセージにも慣れる**ことが出来ると思います。

```
【ステージングエリアに何も無いとき】
% git status
On branch ブランチ名
nothing to commit , working tree clean

【ステージングエリアにaddされたファイルが存在するとき】
% git status
On branch ブランチ名
Changes to be committed:
 (use "git restore --staged <file>..." to unstage)
	modified:  ファイル名
```

##コミットメッセージ
**:exclamation:しっかり教えたい**

しっかり指導したいポイントとして、コミットメッセージの付け方があります。

```
$ git commit -m"コミットメッセージ"
```
コミットメッセージのルールに関してはそれぞれのプロジェクトで決まりがあると思います。
新人は、コミットメッセージをつけるという感覚がなく、軽視してしまうこともあるかと思うので、メッセージをつける意味や意義なども併せて教えたいです。

**:beginner:ここで引っかかる！**

初心者はコミットメッセージを頻繁に付け忘れます。そしてコミットメッセージを付けずにコミットを行うと、

```
【Viの画面】
ここにコミットメッセージを入力
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch ブランチ名
# Changes to be committed:
#    modified:  ファイル名
```

このような画面が出るかと思います。
Gitに初めて触るような非情報系の新人は、もちろん**Viにも触れたことがない**ので、
「突然画面が切り替わったが、何も操作ができない」状態になります。
実はここが一番パニックになるポイントかもしれません。
実際、**Gitのコマンドを解説している記事や動画ではViの操作に関する説明を割愛しているものも多く、**私も最初はここで躓きました。

ひとまず、INSERTモードでコミットメッセージを記入し、以下の画面が出ることを確認しましょう。

```
% git commit
[ブランチ名 000000] コミットメッセージ
 1 file changed, 1 insertion(+), 1 deletion(-)
```

##Viの操作
**:exclamation:しっかり教えたい**

Gitの勉強をスムースに行うためにも、しっかり**Viの操作**も指導しておきたいところです。
まずは下記の操作を教え、必要に応じて知識を増やすようにしましょう。

```
【モード】
i　　　　INSERTモードへ
o 　　　 1行足してINSERTモードへ
v　　　　VISUALモードへ
Esc     コマンドモードへ

【削除】
x	     1文字削除
dd       1行切り取り

【コピーアンドペースト】
yy	     現在の行をコピー 
p	     カーソル位置にペースト

【Vimの抜け方】
Escを押す
:q　 　　保存せず抜ける
:wq　　　保存して抜ける
:w	     内容を保存
:q!    	 保存せずに終了
```
このほかにも多くのコマンドが存在します。基本的な操作を覚えたら、便利なコマンドを勉強するのも良いと思います。


以上が、ディレクトリ作成～コミットまでの基本的な流れです。
ごく単純な操作の中にも、非情報系の新人にとっては沢山の落とし穴が隠れていることが分かったと思います。


#新人に教えたいコマンド（おまけ）
最後に、新人が困ったときに参考に出来るコマンドを紹介します。

```
% git
```
これもGitのコマンドなの？と思いますが、結構役に立ちます。

```
%  git
usage: git [--version] [--help] [-C <path>] [-c <name>=<value>]
           [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]
           [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]
           [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]
           <command> [<args>]

These are common Git commands used in various situations:

start a working area (see also: git help tutorial)
   clone             Clone a repository into a new directory
   init              Create an empty Git repository or reinitialize an existing one

work on the current change (see also: git help everyday)
   add               Add file contents to the index
   mv                Move or rename a file, a directory, or a symlink
   restore           Restore working tree files
   rm                Remove files from the working tree and from the index
   sparse-checkout   Initialize and modify the sparse-checkout

examine the history and state (see also: git help revisions)
   bisect            Use binary search to find the commit that introduced a bug
   diff              Show changes between commits, commit and working tree, etc
   grep              Print lines matching a pattern
   log               Show commit logs
   show              Show various types of objects
   status            Show the working tree status

grow, mark and tweak your common history
   branch            List, create, or delete branches
   commit            Record changes to the repository
   merge             Join two or more development histories together
   rebase            Reapply commits on top of another base tip
   reset             Reset current HEAD to the specified state
   switch            Switch branches
   tag               Create, list, delete or verify a tag object signed with GPG

collaborate (see also: git help workflows)
   fetch             Download objects and refs from another repository
   pull              Fetch from and integrate with another repository or a local branch
   push              Update remote refs along with associated objects

'git help -a' and 'git help -g' list available subcommands and some
concept guides. See 'git help <command>' or 'git help <concept>'
to read about a specific subcommand or concept.
See 'git help git' for an overview of the system.
```

コマンド集などではあまり見かけませんが、~~今まで書いてきた記事が半分くらい必要なかったのではないかと思うくらい~~非常に便利なコマンドです。
特に初心者にとっては、コマンドを忘れたときにこれを見れば自力で解決することが出来るのではないでしょうか。
ここまでの解説と共に、新人さんに教えてみてください。

最後まで読んでくださりありがとうございました。


##参考文献
岡本隆史・武田健太郎・相良幸範、『【改訂新版】Gitポケットリファレンス』、技術評論社