そろそろGUIじゃなくてCUIでgitを使ってみたい人向け講座

#### 対象

- Source Treeなどでgitの基本操作、用語をある程度理解している

- cdコマンドなど基本的な操作はわかってるorググって理解できる(当記事内でそこから解説しようとするとあまりにも量が膨大になり厳しいため)

- CUIのgitに興味があるが、GUIに慣れているのもありなかなか移行できずにいる

- (Windowsの場合は)git bashなどがインストールしてある
インストールされてなければ今からインストールしましょう！

## まえがき
　Source Treeがクラッシュして嘆いている後輩がいたので、「git bash使おう」と冗談っぽく助言してみましたが、せっかくなのでスムーズにCUIへ移行する助けをしようと思いこの記事を書いた次第です。CUIに興味があるけど、敷居が高いと感じたりしてCUIを使えずにいる人の助けになったらいいなぁと思います。

　さて、「git CUI 入門」のように検索すると色々な記事が出てきますし、いくつか覗いてみましたがそれらの記事は結構しっかりと書かれています。
　では、なぜこの記事を書いたのか？それは断片的な情報は各所に転がっているものの、最初に知りたいと思っていた知識を包括的に書いてくれている記事は見つからなかったこと、基本的な使い方を分かった程度では最初のうちは不便が多いCUIにわざわざ移行しようと思わないからです。

　私はできるだけCUIで作業した方が早いと感じるので、CUIを推奨したい派です。しかし基本操作を知った程度ではおそらく「慣れているGUIの方が作業が早いし、GUIで良いのでは？」と思うことでしょうし、実際その通りでしょう。

　この記事ではCUIを使う利点と、GUIよりも快適に扱うためのノウハウや設定まで少し触れていきます。まあ結局は慣れなので、なんとなく何をすればいいか分かったら、あとはとにかく使ってみることでどんどん使えるようになっていくはずです。そしてそのうちGUIよりCUIを好んで使うようになるかもしれません。なんだかかっこよさそうで憧れてたCUIにデビューしてみよう！ぐらいの気持ちで始めてみてください。

# CUI gitの基本　gitリポジトリを作る
前置きが長くなりましたが、本題となるgitコマンドの説明をしましょう。
とは言っても、gitリポジトリを作るのは超簡単です。gitで管理したいフォルダまでcdコマンドで移動して

```bash
$ git init
```
です。

githubなどからクローンしてくるなら

```bash
$ git clone (githubなどのURL)
```
です。

gitに限った話ではないのですが、CUIはとにかくtabキーを押す癖を付けることで色々教えてくれて、とてもユーザーフレンドリーになります。お使いのシェルや設定にもよりますが、「cd 」まで入力してtabを2回ほど押せば今そこにあるファイルをばーっと表示してくれるはずです。

MacやLinuxはデフォルトのbashで特に問題ないですが、コマンドプロンプトはもう色々なところでつらいので、Windowsユーザーはgit bashを使うことで最も手軽にまともなシェル環境を体験出来るのでおすすめです。

とにかくできるだけ多くtabキーに頼ることでCUIへの抵抗感が大きく減るのでぜひお試しください。~~そしてそのうち.bashrcや.zshrcをいじり始めるようになります~~

もちろんgitコマンドが動けば問題ないので、git bash以外に何かCUI環境がインストールしてあったり、既にコマンドプロンプトを愛用している方は、そちらをそのまま使って頂いて構いません。

# CUI gitの基本　コミット編
当然ですが、やることはguiと変わりません。例を示してみます。

```bash
$ git status
$ git diff
$ git add .
$ git commit -m "bug fixed"
$ git push origin develop
```

ここで行なっているコマンドの流れは、基本操作である

1. 変更のあったファイルを確認
1. それぞれの差分を確認
1. 変更をステージング
1. メッセージをつけてコミット
1. リモートへプッシュ

の手順です。

git pushはリモートブランチの話になるので後述します。

「git status」は変更のあったファイルを確認できます。「git diff」は変更した箇所を見れます。[diffの使い方は色々あるので、詳しい使い方は別の記事におまかせしておきます。](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be)

「git add . 」はステージングです。gitはコミットしたいファイルとしたくないファイルを分けるために、ステージングしてからコミット、という流れがあるんでしたね。ステージングしているファイルはgit diffにオプションをつけないと差分を見れなくなるので注意してください。
　「git add (ファイル名)」とすれば、そのファイルだけステージングすることができます。
　「git add .」で変更されているファイルを全てステージングします。

いま何がステージングされているかは「git status」で確認することができます。gitにおけるlsコマンドのようなものなので、こまめに git status しましょう。

間違えてステージングした！という場合は「git reset」でキャンセルできます。

git resetはコマンド名と実際の動作がいまいち直感的でないので、最初のうちは混乱するかもしれません。参考記事のひとつを掲載しておきます。

https://qiita.com/forest1/items/f7c821565a7a7d64d60f

---
ステージングが終わったら、コミットです。基本は2つの方法を覚えればよいです。

```bash
$ git commit
または
$ git commit -m "コメント"
```

単に「git commit」と入力するとエディタが起動します。コミットメッセージを書き込んで保存することで、コミットされます。
環境次第ですが、viが起動する気がします。
この記事の読者はCUIに慣れていない人を想定しているので、さらっと簡潔なviの操作も書いておきましょうか。詳しくはvim専門の記事をご参照ください。

----

最低限コミットメッセージを書くために覚えるべきviの操作はたった3つだけです。

1. インサートモードにする
viにはモードの概念があり、最初はノーマルモードで起動します。
まずはモードを切り替えて、インサートモードにしないと文字入力ができません。
モード変更は i キーを押すだけです。日本語入力になってないかは気をつける必要があります。(n敗)
インサートモード中に変な操作は必要ありません。普通に文字を入力できます。
通常、1行目はタイトル、2行目は空行、3行目以降に詳細な説明を書きます。**1行目をあんまり長くすると後で表示が崩れるので気をつけます。**

2. インサートモードを解除する
コメントを書き終わったらESCキーを押します。ノーマルモードに戻ります。

3. viを終了する
ノーマルモードの状態で
:wq と入力すると保存して終了＝コミットされます
:q! と入力すると保存せず強制終了＝コミットはされません 

以上です。

最後のコミットメッセージなら commit --amend で後から簡単に直せますし、怖がらずにとりあえずやってみましょう！~~そのうち.vimrcをいじり始めるようになる~~

なんかよくわからない操作をしてしまった！というときには、とにかくESC連打してノーマルモードに戻り「:q!」を打てば強制終了できるので保存されません。vimはうっかりキーボードに手が触れてしまっただけでモード切り替えされてしまいがちなので、焦らず対応しましょう。

---

長々とviの操作について記載してみましたが、「git commit -m "メッセージ"」と -m オプションをつければメッセージを直接書いてコミットできます。もっと簡単ですね。

ちなみに：git commit -a というオプションもあるのですが、事故の元なのでこちらはおすすめしません。git add が省略できます。

---

ここでちょっとした開発テクニックの紹介。

ステージングしてコミットする基本な動きをするだけなら、極端に言えば「git add .」と「git commit -m "save"」を交互に使っているだけで成立します。同じコマンドを繰り返すということは、履歴が使えます。
作業中にキリが良くなったら、あらかじめ開きっぱなしにしておいたgit bashなどのウィンドウに切り替えて「↑↑Enter↑↑Enter」と入力するだけで、作業中のスナップショットの保存が簡単にできます。これなら慣れてなくてもGUIよりすばやく操作できるのではないでしょうか。上上エンター上上エンター

これをやると当然saveとしか書かれてないコミットが大量に出てきますが、ある程度完成したところでちゃんとしたコメントを書いたコミットを作れば、重要な節目はちゃんと分かるので問題ないでしょう。こまめにスナップショットが保存できるのでgitの強みを発揮できます。

チーム開発のリポジトリなどで履歴が気になるなら、あとでrebaseしてまとめればいいわけです。rebaseするのはややめんどくさいので、この記事では触れないんですが…
慣れないうちはコンフリクトの解消やリベースにはsourceTreeを使っていました。CUIとGUIを併用して対処するのもスマートなやり方ではないでしょうか。

-----

# CUI gitの基本　ブランチ編

ブランチを新しく作って、チェックアウトして、マージできるようになりましょう。
git-flowに関しては拡張機能もあるので興味があれば調べてみるとよいでしょう。

developブランチを作ってチェックアウトする例

```bash
$ git branch develop # ブランチを作る
$ git checkout develop # チェックアウトする
```

上と同じ操作を1つのコマンドで実施することもできます。私は基本こちらを使っています。

```bash
$ git checkout -b develop # 新しいブランチを作りつつ、チェックアウトする
```

「git checkout ブランチ名」と指定すればブランチを移動できます。
「git checkout ハッシュ値」とすればそのハッシュ値に移動できます。


**※↓コメント欄より追記**

git-flowでチーム運用している場合など、リモートにあるブランチを直接ローカルにも作りたい、という場面が結構あると思います。その場合

```bash
$ git checkout -b hoge origin/hoge
```

で実現可能です。

---

新しいブランチ名をつけず「git branch」とだけ入力すると、ブランチの一覧が見れます。
アスタリスク(*) ついてるのが今いるブランチです。

```bash
$ git branch
* develop
  master
```

ブランチを消すときは-dです。

```bash
#developブランチにいるとdevelopが消せないのでmasterへ移動
$ git checkout master
$ git branch -d develop
```

---


```bash
$ git branch # ブランチ一覧
$ git branch develop # ブランチを作成
$ git branch -d develop # ブランチを削除

$ git checkout -b hoge # ブランチを作成しつつチェックアウト
$ git checkout -b hoge origin/hoge # リモートブランチをローカルにも作成しつつチェックアウト
```

branchの基本をまとめました。
何か間違えても -f オプションなどをつけない限り致命的な操作はブロックされるので問題ありません。安心して使い、慣れてましょう。

---

## マージ

マージも、コマンドを使うだけなら簡単です。add-fileブランチを作成し、masterにマージする例を示してみます。
※touchは空のファイルを作るunixコマンドです

```bash
# ここはファイルを作ってコミットを作るパート
$ git checkout -b add-file
$ touch hoge.txt
$ git add .
$ git commit -m "test"

#ここからがマージ操作
$ git checkout master # まずは master に移動して
$ git merge add-file # add-file を取り込み
$ git branch -d add-file # 取り込んで不要になったので add-file を消しておく
```

マージするときは「git merge (マージする相手のブランチ名)」です。
自分が今いるブランチにマージされますので、事前にチェックアウトするのを忘れないようにしましょう。(n敗

マージすると、マージコミットのメッセージを書くためにviが起動します。

```bash
Merge branch 'develop'

# Please enter a commit message to explain why this merge is necessary,
# especially if it merges an updated upstream into a topic branch.
#
# Lines starting with '#' will be ignored, and an empty message aborts
# the commit.
```

こんな感じで最初からメッセージが書かれているはずです。

特に追加説明が必要なければ、そのまま :wq と保存すればマージ完了です。
コンフリクトが起きた場合はSource Treeなどいままで使っていたGUIクライアントを起動します。この記事を読んでCUIに興味を持った段階のレベルなら、無理に頑張ってCUIで解決する必要はありません。今まで使っていたものに頼るべきです。

git-flowコマンドで拡張していると、このあたりの名称は少し変わってきますが、内部的に実行するコマンドの対応関係は同じです。

---

tips　tab補完

環境設定次第ですが、ブランチ名も補完が効きます。
少なくとも git bash は効きますので試してみてください。

例えば「de」まで入力してtab押したらdevelopに補完されます。

候補が複数で特定できない場合はすぐには補完されませんが、tabを何度か押下すれば候補も出してくれるはずです。

-----

# CUI gitの基本　リモート編

githubとかを使うときの設定です。
まずはリモートブランチのURLを設定します。

```bash
$ git remote add origin https://hogehoge...
```

今までおまじないのようにoriginを使っていたかもしれませんが、このoriginはURLにつける名前（エイリアス）のようなものです。
普通はoriginが使われます。

複数のサーバーにプッシュしたりする場合は、当然別の名前で設定する必要があります。

```bash
$ git remote add github (githubのリポジトリURL)
$ git remote add gitlab (gitlabのリポジトリURL)
```

とすれば github と gitlab の2つを使うことができます。
使い分けも origin と書いているところを github/gitlab に置き換えるだけです。

git cloneでどこかから落としてきた場合はそのcloneしてきたリポジトリのURLがoriginとして設定されているのでこの操作は必要ありません。

逆に言えば、cloneしてきたときに自動で設定される名前がoriginなので、自分で設定する場合もoriginを使うのがわかりやすくてよいということになります。

その他コマンドがいくつかあるので例を並べてみます。

```bash
git remote add origin https://hogehoge... # リモートを追加

git remote set-url origin http://piyopiyo # すでに追加されているoriginのURLを変更

git remote remove origin # リモートを削除

git remote -v # リモートの一覧を取得
```

----

リモートが設定できたら、通信してみましょう。
フェッチ・プル・プッシュなどは全部似たようなコマンドで出来ます。

```bash
git fetch origin -p # -p をつけないと消えたブランチを反映してくれません
git pull origin
git push origin develop
```

方法は割愛させて頂きますが、originを省略したりもできます。
originと入力するのも億劫になるぐらいgitの概念とCUIに慣れてきたら調べてみてください。--set-upstream などで出てきます。

----

# CUIのgitを使いやすくしよう

ここまででgitの基本的な操作は説明できました。

最後に、実戦向けとして使いやすくするために設定をしてみましょう。ということで私の.gitconfigを晒します。そんなにgitの設定にこだわってないので大したことないですが…(逆にごちゃごちゃしてなくて見やすいかも？)


```:.gitconfig
[alias]
	tree = log --graph --all --format=\"%x09%C(cyan)%h%Creset%x09%C(green bold)%an%Creset %C(magenta bold)%d%Creset %s\"
	cho = checkout
	st = status
	br = branch
	co = commit
[core]
	autoCRLF = false
	quotepath = false
[merge]
	ff = false
[pull]
	ff = only
[difftool "sourcetree"]
	cmd = '' \"$LOCAL\" \"$REMOTE\"
[mergetool "sourcetree"]
	cmd = "'' "
	trustExitCode = true
```

※ メールアドレスなどの設定は削除しています
※ treeはどこかの設定をコピーして持ってきたはずなのですが、設定したのはもう何年も前なので引用元がわからなくなってしまいました。申し訳ないです。

.gitconfigはホームディレクトリに配置します。Windowsでは "C:\Users\ユーザー名" ですね。「cd ~」で移動できる位置です。

---

エイリアス設定を使うときは、例えばtreeなら「git tree」です。シェル環境でのエイリアスではなく、gitコマンド内でのエイリアスなので頭に git はつける必要があります。

tree の動作は見たほうが早いので実行結果をお見せしましょう。
個人開発だといい感じの履歴がなかったので、「git tree」を[OpenSiv3D](https://github.com/Siv3D/OpenSiv3D)のリポジトリで使ってみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212031/9430f2bd-afae-7c87-834a-cb8bda5693a0.png)

視覚的にわかりやすく履歴を表示してくれます。
これならCUIでもなんとかgitを使えそうな気がしてきませんか？

「コミットメッセージの１行目は短くした方がいい」と書いていたのを覚えているでしょうか？ここで表示が崩れてしまうから必要だったんですね。
また、コミット数が増えると当然縦に長くなります。1ページで収まらない場合はvimと似た操作になり「q」を押すと終了できます。

tree コマンドは元がgit logなので「-数字」で表示する行数を指定することもできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/212031/e079347b-9ba3-d050-c7b2-74bdb0045085.png)

CUIなので、動作も非常に早いです。
慣れてしまえば、もう重いGUIアプリで確認する必要はないですね！

---

それ以外のエイリアスは単に文字入力を減らすものです。

```
	cho = checkout
	st = status
	br = branch
	co = commit
```

使用頻度が高いコマンド、checkoutなどは8文字も必要なのでめんどくさいです。
ああ、本当にめんどくさい。
死ぬほどめんどくさい。
cho なら3文字なので2倍以上の速度で入力が終わります。
嬉しい！
もう1文字で c にしてもいいですね。さらに3倍早くなりますよ。やったー！！

という冗談はさておき、文字数減らしておくのは快適性に直結するので極めて重要です。
tabキーを連打して補完をガンガン使えば入力は減りますが、そもそも日常的に繰り返すコマンドでtab押すこと自体が面倒です。
私は一文字変数を使いたくないので最低限の意味が読み取れる2字以上でエイリアスを作っていますが、設定はあなたの信念に従ってカスタマイズしてください。

---

```
[core]
	autoCRLF = false
	quotepath = false
```

autoCRLFは改行コード周りの設定です。改行コードはエディタ側で設定すべきという考えなので私はfalseですが、場合によってはかなり重要な設定になるかもしれません。宗派や所属しているプロジェクトの規約に応じて設定しましょう。
quotepathはfalseにすることで日本語のファイルがまともに表示されるようになります。ファイル名に日本語をつけることの是非はともかく、表示設定ぐらいしておくのがベターかと思います。

---

```
[merge]
	ff = false
[pull]
	ff = only
```

mergeがfast forwardになることを防ぎます。
ffになってしまうとマージしたときのメッセージが残せないので、どこでマージが起きたのかわからなくなります。
すっきりした一本のツリーを好むなら必要はありませんが、私はマージしたことをしっかり履歴に残したいので設定しています。

つまりこれも宗派によりますね。設定なんてものはだいたい人次第です。

pullしたときにffにならないのは何か運用がおかしいときになりますので、検知する意味でonlyにしています。これについては宗派関係なくonlyでよいはず。

---

いくつかオプションを紹介しましたが、最低でもgit treeだけでも使えるように設定しましょう。

ホームディレクトリに.gitconfigファイルを直接作成・編集することでも反映されますが、gitコマンドから設定することもできます。
st = status を設定する例：

```bash
$ git config --global alias.st status 
```

※treeコマンドは色々特殊文字入ったりしてるせいで上手く行かなかったので設定ファイルに直接書いたほうがよいです

設定に関する色々な情報は他にもたくさんありますので、気になるところがあればお好みにカスタマイズしてみましょう。
その頃のあなたには、この記事は不要になっていると思います。

# 最後に
gitとか関係なくCUIと仲良くなるためにtabを押す癖をつけよう！！！まずはそれからだ！！！