Git add, commit, push, pull, などの基本コマンドでの操作と GitHub への連携操作

**これは個人の学習メモです**

## どんな記事か

git コマンドの超基礎。

会社で学習したことと、自分のブログ (https://kei-s-lifehack.hatenablog.com/) の記事を統合した

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243383/09dc7918-7cfd-33f3-f4bd-6d9f924cef40.png)

## 基本コマンド (add, reset, commit, push)  

### add, index に追加

#### 全て add する

```
git add .
```

git の管理下(index)に全部足す, add all

#### 1ファイルだけ add する
```
git add hoge.txt
```

hoge.txt一個だけ管理下に置くとき, Add just the file　
`create-react-app` などでプロジェクトを作成したとき、最初に `.gitignore` をあげるときによく使う

#### .gitignore とは

`node_modules` など、** git 管理下におかないもの ** は`.gitignore` に記載する

参考
[".gitignore file - ignoring files in Git | Atlassian Git Tutorial"]
(https://www.atlassian.com/git/tutorials/saving-changes/gitignore)

また、`.gitignore` に `node_modules` を新しく記載しても `node_modules` を
`git add .` で一緒に index に add すると反映されないで `node_modules` も push されてしまう。

なので前述のように先に `.gitignore` のみ先に commit する必要がある

#### git reset

```
git reset
```

以前の状態に戻す

### commit, 差分記録

```
git commit
```

前回の commit からの差分を現在のブランチの内部に記録する

### push, リモートブランチへの押し出し

```
git push <HEAD> <branch>
```

commit を 主にリモート (origin) の feature ブランチに送る。

なおチーム開発では master への直 push は NG なので注意
rebase や reset でなかったことにできるが、まとめて編集すると非常に面倒くさいことになるので
そもそも **作業ごとに commit を分割しておくこと** が非常に重要である

### pull, リモートから引っ張ってくる

```
git pull <HEAD> <branch>
```

リモートの方が新しい場合，その内容をパソコンの内部(ローカル)に
引っ張ってくる。ブランチなどを作成する時に先にしておかないとコミットが絡まって首が絞まる

### stash, 一時待避

```
git stash
```

参考
[【git stash】コミットはせずに変更を退避したいとき]
(https://qiita.com/chihiro/items/f373873d5c2dfbd03250)

>
「とあるブランチで作業中だけど、いますぐやりたいことができた。
作業すごく中途半端だからコミットはしたくない。」
というときに、stashが使えます。
stashを使用すると、コミットしていない変更を退避することができます。
stashで変更を退避させて、今すぐやりたい作業をして、退避させていた変更を戻して作業を再開することができます。

>
コミットしていない変更がある状態で上記のコマンドを実行すると、変更した部分が退避されます。
コミットしていない変更とは、addしたものもaddしていないものもどちらも含まれます。
ブランチは変更が取り消されたきれいな状態となります。


commit するまでもない変更を退避させる。
他のブランチに行く前にワーキングディレクトリに変更があって commit したくない時はこれをしないと動けない。
stash に保存して、ワーキングディレクトリを、最後に commit されている地点まで巻き戻す。

```
git stash
Saved working directory and index state WIP on 20200708-daily-report: 9ecbd48 applied report template
```

commit してないファイルの変更を退避して、最後の commit の変更までワーキングディレクトリを巻き戻した。

> 以下のコマンドで退避した作業の一覧を見ることができます。
```
git stash list
// こんな感じで出力されます
stash@{0}: WIP on test: xxxx
stash@{1}: WIP on commit-sample: xxxx
```

>stash@{X}がstashの名前で、WIP onのあとはブランチ名です。xxxxはstashをしたときのHEADのコミットハッシュとコミットメッセージになります。

```
git stash apply
```
これで git stash をする前に戻せる。



### git fetch

```
git fetch <HEAD> <branch>
```

参考
https://www.git-tower.com/learn/git/faq/difference-between-git-fetch-git-pull

> git fetch really only downloads new data from a remote repository 
> but it doesn't integrate any of this new data into your working files

* git fetch は リモートリポジトリから 新しいデータ(変更)をダウンロードするだけ
* ダウンロードした新しいデータを、ワーキングファイル（ワーキングディレクトリ）に統合することはない

> git pull, in contrast, is used with a different goal in mind:

* 対して git pull は 全く違うゴールで作られている

> to update your current HEAD branch with the latest changes from the remote server. 

* 現在の HEAD ブランチをリモートサーバーの最新の変更に更新する(というゴールだ)

だからよく pull は fetch と merge だと言われるのだな。
次の項目でリモート参照ブランチを交えて図示して説明する。

### リモート参照ブランチと fetch と merge について

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243383/46be320f-d6e9-8b97-3678-7204d5c96875.png)

2020/10/11 追記

世の中にはローカルで master ブランチをほとんど使わない人がいるらしい。
彼らは新しくブランチを切るときには

```
git checkout -b NEW_BRANCH origin/master
```

で手元の master ブランチからではなく、origin/master から新しいブランチを作成する

これはリモートから直接 ローカルの新しいブランチを作るのではない。

**リモート参照ブランチ** に `git fetch` して、そこから `git checkout -b origin master` で 新しいブランチを作ることができる

私は普段の `git pull` では　リモートの GitHub から **ローカルの origin/master** に `fetch` して そこから ローカルの master ブランチに `merge` していた。

ローカルが持つリモートブランチの情報は ref (参照) だが、
その参照の情報というものも更新してあげないといけない、それが `git fetch`

参照先が変わったら参照も更新する必要があるそこが　`git fetch` と `git merge` の間にある リモート参照ブランチ origin/master である。

------------------------

## URL 操作, remote 設定

主に作成されたリモートの新しい GitHub リポジトリとローカルのディレクトリを接続する文脈で説明する。

```
git remote -v
```
一番使う．
今の push 先の URL を確かめる。
これで確認しないで作業を始める、前使っていたリモートリポジトリに push しようとしてしまう恐れがある。


```
git init
```

`.git/` の初期化．新しく git 連携のレポジトリを作る時に行う
これでリモートの接続先もリセットされる。

```
git remote add origin yourURL
```

https://github.com/new

などで作成した push 先のリモートブランチがある場合，
そこの URL をローカルブランチの push 先に追加できる

例えば ユーザー <kaede0902> の `hoge-blog` というリポジトリを SSH でリモート設定する場合は

```
git remote add origin git@github.com:kaede0902/hoge-blog.git
```

となる。

```
git remote set-url origin NEWURL
```

リモートの URL が予め設定されていて、それを変更するときはこっち。

これらが完了すれば、ステージング、コミット、push、をした時にその設定したリポジトリにコミットが送信されるようになる。


-------------------------------------------------

## CONFIG設定  

リモートリポジトリとの連携がうまくいかない場合は直接 .git/ の設定ファイルを編集する必要が出てくる。

### config 確認

参考
https://docs.github.com/en/github/using-git/setting-your-username-in-git

```
git config --global user.name
```

で現在の username が返ってくる
e-mailも同様。

また，コマンドではなくconfig fileを直接開ける．

`vi .git/ ` すると

.git/config にこういうのがある．

```text:.git/config
    [remote "origin"]
        url = https://yourusername@github.com/yourusername/repositoryname.git  
        fetch = +refs/heads/*:refs/remotes/origin/*  
    [branch "master"]  
        remote = origin  
        merge = refs/heads/master  
    [user]  
        name = yourusername  
        email = your@adress
```

url が https のままだと毎回作業時にユーザーネームとパスワードを聞かれて面倒なので，

ssh の設定をして書き換えておくと楽。

## git commit -m でnanoが開いてしまう場合

私はあまり nano を使いたくないので default を vim にしたかった

参考
https://qiita.com/wnoguchi/items/f7358a227dfe2640cce3

これで 

```
git config --global core.editor 'vim -c "set fenc=utf-8"'
```

をしておけばコミットメッセージなしでコミットしても，自動的に vim が開いてくれる

（私はメッセージ付きコミットより，vim開いてメッセージ書いた方がやりやすいので、コミットメッセージなしで `git commit` で vim でコミットメッセージを 開く場合が多い。）

以上です。