Git 導入メモ

#参考
https://www.udemy.com/course/unscared_git/learn/lecture/7176854

#Git入手先

https://gitforwindows.org/
からダウンロード

#Github

https://github.com/

#基本操作
Git をインストールすると"Git CMD"というアプリが使えるようになるのでそれを起動

##バージョン確認

```
$ git version
git version 2.26.2.windows.1
```

##ユーザ登録
```
$ git config --global user.name "<ユーザ名>"

$ git config --global user.email "<メールアドレス>"
```

##ローカルリポジトリの作成
対象のディレクトリで

```
$ git init
```

##リモートリポジトリ(github)の作成
githubのWebから"Start a project"や"New"をクリックし、プロジェクト名等を入力してプロジェクトを作成。

##ファイルの追加・変更の反映

追加したい、または変更反映したファイルを以下コマンドでステージングエリアに追加。


```
$ git add <ファイル名 or ディレクトリ名 or .(ドット)>
```

##ファイルの削除

```:ファイルごと削除
$ git rm <file名>
```

```:ファイルは残す
$ git rm --cached  <file名>
```

```:ディレクトリを削除
$ git rm -r <ディレクトリ名>
```

##ファイルの移動

```
$ git mv <旧ファイル> <新ファイル>
```

##ローカルリポジトリにcommit

```:オプション無
$ git commit
```

```:メッセージ付き
$ git commit -m "<メッセージ>"
```

```:変更内容をエディタで確認
$ git commit -v
```

エディタが開かれコミットメッセージの入力を求められるので、入力しエディタを閉じるとコミット完了。

##リモートリポジトリにpush
githubで作成したプロジェクトのページに載っているのでそちらも参考。
まず、リモートリポジトリのURLを知らせる。
以下のコマンドで`origin`に`<対象プロジェクトのURL>`を割り当てる。

```
$ git remote add origin <対象プロジェクトのURL>
```

上記実行したら、下記でpushする。`-u`オプションをつけることで、次回以降は`origin master`を省略してもoriginのmasterにpushされる。

```:初回
$ git push -u origin master
```

```:2回目以降
$ git push
```

```:指定のブランチにpushする場合
$ git push origin <ブランチ名>
```


##リポジトリの状況確認
```
$ git status
```

##リポジトリのログ確認

```:オプション指定なし
$ git log
```

```:1行表示
$ git log --oneline
```

```:ファイル差分表示
$ git log -p <ファイル名>
```

```:最新の3つの履歴だけ表示
$ git log -n 3
```

##差分の表示
```:ワークツリーとステージングエリアとの差分
$ git diff
```

```:ステージングエリアとリポジトリの差分
$ git diff --staged
```

後ろにファイル名を付けることもできる。

##リモートリポジトリのコピー
```
$ git clone <URL>
```

##エイリアスの設定
```
$ git config --global alias.<エイリアス名> <コマンド>
```

##管理外ファイルの設定
`.gitignore`ファイルに、管理外としたいファイル名またはディレクトリ名を記載。

#変更の取り消し


##変更ファイルの取り消し

```
$ git checkout -- <ファイル名 or ディレクトリ名 or .(ドット)>
```

変更ファイルを取り消す、というよりは、ステージに置かれているものをワークツリーに引っ張り出す(=上書きする)というイメージのほうがわかりやすい？

##ステージに追加した変更の取り消し

```
$ git reset HEAD <ファイル名 or ディレクトリ名 or .(ドット)>
```

ステージへの追加を取り消すだけであるため、ワークツリーのファイルは変更されない。

##直前のコミットをやり直す

```
$ git commit --amend
```

リモートリポジトリにpushしたcommitはやり直してはいけない。

#リモートリポジトリとのやり取り

##リモートリポジトリ情報表示

```:オプション無
$ git remote
```

```:URL表示
$ git remote -v
```

```:詳細表示
$ git remote show <リモート名>
```

##フェッチ

```
$ git fetch <リモート名>
```

フェッチしたデータは、ローカルの`remotes/<リモート名>/<ブランチ名>`というブランチに格納される。ワークツリーには即座に反映されない。
ワークツリーに反映するには`git merge <リモート名>/<ブランチ名>`が必要。

##プル

```:マージ型
$ git pull <リモート名> <ブランチ名>
```

```:リベース型
$ git pull --rebase <リモート名> <ブランチ名>
```

プルであれば、リモートの情報取得、およびマージ(またはリベース)を一度にできる。
ただしプルの挙動は、「今いるワークツリーのブランチを、プルするブランチで上書きする」というものであるため、今いるワークツリーのブランチとプルするブランチが異なっている場合は、両者のファイルが入り乱れてしまうので注意が必要。

##リモートリポジトリに紐づけている名前の変更

```
$ git remote rename <旧リモート名> <新リモート名>
```

リモートリポジトリ自体は変更されない。

##リモートリポジトリに紐づけている名前の削除

```
$ git remote rm <リモート名>
```

リモートリポジトリ自体は削除されない。

#ブランチとマージ

##ブランチ一覧表示

```:
$ git branch
```

```:リモート含めて全て表示
$ git branch -a
```

##ブランチ新規追加

```
$ git branch <ブランチ名>
```

##ブランチ切り替え

```
$ git checkout <ブランチ名>
```

```:ブランチを新規作成して切り替える
$ git checkout -b <新ブランチ名>
```

##ブランチ名の変更

```
$ git branch -m <新しいブランチ名>
```

自分が作業しているブランチの名前を変更する。

##ブランチの削除

```
$ git branch -d <ブランチ名>
```

masterにマージされていない変更がある場合は削除しない。
強制削除したい場合は以下。

```:強制削除
$ git branch -D <ブランチ名>
```

##マージ

```
$ git merge <ブランチ名>
```



```:リモートリポジトリの内容をブランチする場合
$ git merge <リモート名>/<ブランチ名>
```

引数のブランチの内容を今のブランチに取り込む。
コンフリクトが発生した場合は下記のようなメッセージが発生する。

```
Auto-merging index.html
CONFLICT (content): Merge conflict in index.html
Automatic merge failed; fix conflicts and then commit the result.
```

`git status`を打てば、再度どのファイルでコンフリクトが起きたのかがわかる

```
Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   index.html
```

コンフリクトが発生したファイルには以下のようにコンフリクトの内容が記載されている。

```
<<<<<<< HEAD
<p>コンフリクト</p>
=======
<p>conflict</p>
>>>>>>> feature
```

所望の内容に変更し、さらに`<<<<<<< HEAD`, `=======`, `>>>>>>> feature`の行を消してコミットすればコンフリクト解消となる。

#リベース

##親コミットを別のブランチに置き換える

```
$ git rebase <ブランチ名>
```

尚、pushしたコミットをリベースすると、ローカルで認識している親コミットと、リモートで認識している親コミットが異なるため、再度pushすることができなくなる。

##複数のコミットをやり直す
まずは対話的リベースモードに入る。`コミットID`に`HEAD~3`と書くと、3つ前のコミットが対象になる。

```
$ git rebase -i <コミットID>
```

すると、(`コミットID`に`HEAD~3`と書いた場合、)以下のようなテキストが記載された状態でコミットエディタが起動する。

```:例
pick 086f7d8 first.html追加
pick 962beec second.htmlを追加
pick b26fcbe third.htmlを追加
```

- コミット内容を編集（やり直したい）したい場合、
    1. 該当行を`pick`から`edit`に変更してコミットエディタを閉じる。
    2. やり直したい内容を修正後、`$ git commit --amend`実行
    3. やり直し完了後、`$ git rebase --continue`実行
- コミット内容を取り消したい場合、該当行を消してコミットエディタを閉じる。
- コミットの順番を入れ替えたい場合、該当行を入れ替えてコミットエディタを閉じる。
- コミットをまとめたい場合、該当行を`pick`から`squash`に変更してコミットエディタを閉じる。
- コミットを分割したい場合、
    1. 該当行を`pick`から`edit`に変更してコミットエディタを閉じる。
    2. `$ git reset HEAD^`を実行し、ステージングの内容をリセットする。
    3. 分割したい内容でcommit後、`$ git rebase --continue`実行

#タグ

##タグ一覧表示

```
$ git tag
```

```:パターンを指定
$ git tag -l "<パターン>"
```

##タグ作成

```:注釈無し
$ git tag <タグ名>
```
上記の後ろにコミット名をつけることで、タグを後付けすることができる。

```:注釈付き
$ git tag -a <タグ名>
```
上記の後ろに`-m "<メッセージ>"`も付加することで、エディタ起動無でタグ付けができる。

##タグ詳細表示

```
$ git show <タグ名>
```

##リモートへタグを送信

```
$ git push <リモート名> <タグ名>
```

```:タグを一斉送信
$ git push <リモート名> --tags
```

#作業一時避難

##一時避難

```
$ git stash save
```

`save`は省略可能

##一時避難させた内容の確認

```
$ git stash list
```

##一時避難させた内容の復元

```:最新の内容を復元
$ git stash apply
```

```:ステージの状況も復元
$ git stash apply --indes
```

```:特定の内容を復元
$ git stash apply [スタッシュ名]
```

復元しても、スタッシュ自体は削除されず残っている。

##一時避難させた内容の削除

```:最新の内容を削除
$ git stash drop
```

```:特定の内容を削除
$ git stash drop [スタッシュ名]
```

```:全てを削除
$ git stash clear
```