Git備忘録（自分用）

# Gitメモ
## まずはgit設定ファイル
```bash
[user]
  name = Hoge Fuga
  email = hogefuga@example.com
[color]
  ui = auto
[alias]
  br = branch
  ch = checkout
  st = status
  co = commit
  fe = fetch
  gr = log --graph --date-order -C -M --pretty=format:\"<%h> %ad [%an] %Cgreen%d%Creset %s\" --all --date=short
  difff = diff --word-diff
[core]
  quotepath = false
  whitespace = cr-at-eol
```
## gitのコマンド備忘録
### 基本編
基本的な操作はこれが出来ればOK的なもの
#### 作業ツリーの状態を確認
```bash
git status
```
#### 差分を見る
```bash
git diff
```
#### git indexにファイル追加
```bash
# ファイル1つ追加
git add '<ファイル>'
```
```bash
# ディレクトリごと追加もできちゃう
git add <ディレクトリ>
```
```bash
# カレントディレクトリ以下を丸っと追加
git add .
```
#### git indexに追加されているファイルをローカルリポジトリに反映
```bash
git commit -m '<コミットメッセージ>'
```
```bash
# -mオプション付けないとコミットエディタが起動する
git commit
```
#### ローカルリポジトリの内容をリモートリポジトリに反映する
```bash
# <remote>はデフォだとorigin
git push <remote> <ブランチ名>
```
```bash
# remoteの向き先設定されていれば指定しなくてOK
git push
```
#### リモートリポジトリの変更をとってくる
```bash
# 内部的にはfetchとmergeを実行
git pull
```
### 初期設定編
順番が逆な気もするけど
#### gitのconfig設定
```bash
git config --global user.name "Hoge Fuga"
git config --global user.email "hogefuga@example.com"
```
#### リモートリポジトリを持ってくる
```bash
#<作成するディレクトリ名>を指定しないとリポジトリ名で作成される
git clone <リポジトリURL> <作成するディレクトリ名>
```
#### 新しいリポジトリ作成する
```bash
mkdir <project-dir> && cd $_ #プロジェクト用のディレクトリ作成＆移動
git init #初期化
touch README.md #適当なファイルを作成
git add README.md
git commit -m "first commit"
git remote add origin <リポジトリURL>
git push -u origin master
````
#### 既存のローカルリポジトリをプッシュ
```bash
git remote add origin <ブランチ名>
git push -u origin master <リポジトリURL>
```
### ブランチの操作
#### ブランチを表示
```bash
# ローカルのブランチのみ表示
git branch
# リモートのブランチのみ表示
git branch -r
# 全てのブランチ表示
git branch -a
```
#### 現在のブランチからブランチを作成
```bash
git branch <作成するブランチ名>
```
#### ブランチ移動
```bash
git checkout <移動するブランチ名>
# 作成して移動（gitのバージョンによって使えないかも）
git checkout -b <移動するブランチ名>
```
#### 作成する起点を指定
```bash
# リモートリポジトリもOK
git branch <新しいブランチ名> <別のブランチ名|タグ名|リビジョン>
#
```
#### ブランチの名前変更
```bash
# 新しいブランチ名のブランチがあるとエラー
git branch -m <既存ブランチ名> <新しいブランチ名>
```
#### 持っているブランチのマージ状態を知りたい
```bash
# マージ済みのブランチを表示
git branch --merged
# マージされていないブランチを表示
git branch --no-merged
```
#### ブランチ削除
```bash
# どこにもマージされていないとエラーになっちゃうよ
git branch -d <ブランチ名>
# マージされていないブランチを強制削除
git branch -D <ブランチ名>
```
### マージあれこれ
#### 別のブランチの変更を取り込む
```bash
# commitまでされるよ！
git merge <ブランチ名>
# commitしないでマージだけする
git merge --no-commit <ブランチ名>
```
#### 1つのコミットだけマージしたい
```bash
# commitまでされるよ！！
git cherry-pick -n <リビジョン>
# commitしないで取り出す
git cherry-pick --no-commit <リビジョン>
```
#### 他のブランチの履歴を1つの新しい履歴としてマージしちゃう
```bash
# commitされないので自分で1つのコミットとする感じ
git merge --squash <取り込むブランチ名>
```
### タグ
#### タグの表示
```bahs
git tag
```
#### 現在のブランチにタグを付ける
```bash
git tag <タグ名>
# 指定のコミットに付ける場合は？TODOあとで調べる
```
#### タグを削除
```bash
git tag -d <タグ名>
```
### 履歴
#### 履歴を表示
```bash
git log
# 一行で表示する
git log --oneline
```
### リモートリポジトリ
#### リモートリポジトリから変更だけ取得
```bash
git fetch
```
#### ローカルブランチをリモートリポジトリにプッシュ
```bash
git push <リモートリポジトリ名> <ローカルブランチ名>:<リモートブランチ名>
```
#### リモートブランチを削除する
```bash
# :（コロン）が重要！！
git push <リモートリポジトリ名> :<リモートブランチ名>
```
### 応用などあれこれ
#### 直前のコミットメッセージを直したい！
```bash
git commit -m "<メッセージ>" --amend
# エディタ立ち上がる
git commit --amend
```
#### addしたファイルを戻したい
```bash
git reset HEAD
```
#### 作業ツリーの変更をリモートの状態に戻したい
```bash
git checkout <filename>
```
#### 作業ツリーがわけわからなくなったらHEADの状態に戻したい！
```bash
git reset --hard HEAD
```
#### 作業ツリーが変更されていてgit操作ができないよ！
##### stashで変更分を一旦隠す
```bash
git stash
# メッセージもつけられる
git stash save "<メッセージ>"
```
##### 直前にstashしたものを戻す
```bash
git stash apply
# 指定したstashを戻す
git stash apply <stash@{1}>
```
##### stashしたリストを表示
```bash
# 表示された行頭から:（コロン）までがstashの識別子（stash@{1}とかになってと思う）
git stash list
```
##### 取り出したstashがずっと残ってるんですけど
取り出しても残るので削除する必要がある  

```bash
git stash drop <stash@{1}>
```
##### 実は取り出して削除することもできちゃう
```bash
git stash pop
git stash pop <stash@{1}>
```
##### 隠した内容からブランチを作れちゃう！！
```bash
# 直前のstashから
git stash branch
# 指定stashから
git stash branch <stash@{1}>
```
stashしたあとに作業ツリーでガンガン作業しちゃった時とかブランチ作ってマージとかがいいかなーっと
##### stashに保存されているものを全部削除しちゃう！！
※※※通常の操作では二度と戻せないので注意※※※

```bash
git stash clear
```
##### 消したくないstashを間違えて消しちゃった。。。
まだ戻せるかもしれないよ

```bash
git fsck --unreachable | grep commit | cut -d\  -f3 | xargs git log --merges --no-walk --grep=WIP
```

上記で戻したいコミット見つかればリビジョンをメモる

```bash
git cherry-pick -n -m1 <リビジョン>
```
でなんとか戻すことは可能

#### rebase とか
基本的にリモートリポジトリの変更には使わないこと
どうしてもの場合には共有してから行いましょう
##### 現在のブランチの起点を他のブランチのHEADにしたい
```bash
git rebase master
```
開発用ブランチを作成したあとmasterが進んでしまった時など履歴が綺麗になる
##### うまくrebase出来ない場合。。。
###### コンフリクトを手動で解消してrebaseを続行する
```bash
git rebase --continue
```
###### エラーなんて関係ない！で続行
```bash
git rebase --skip
```
###### もうrebase無理。。。あきらめた
```bash
git rebase --abort
```
###### インタラクティブモード（対話式）で色々できちゃう
```bash
# 指定したリビジョン以降のコミットが取り上げられる
git rebase -i <リビジョン>
# git log --onelineで確認すると楽
```
git log --oneline と git rebase -i で立ち上がったエディタのコミット順が逆になるので注意
* p|pick そのままにしておく
* r|reword コミットメッセージを変える
* e|edit コミットファイルを変える
* s|squash 一個前（インタラクティブモードだと一個上）のコミットと合体させる
* f|fixup squashのコミットメッセージ変更しない（メッセージも合体する）

#### リモートリポジトリをローカルリポジトリに強制的にあわせちゃう
```bash
git push -f <リモート> <ブランチ名>
```
歴史の改変になるので、複数メンバーで開発している場合は使わないこと