忘れっぽい人のgitコマンドあれこれ

#利用頻度は低いが、大事なときに使うgitコマンド
いつもWeb検索しているので、備忘録として残す（随時更新していく予定）。

##ワーキングディレクトリ（ローカル）では編集するが、ステージングエリアに反映したくないとき
###`.gitigonre`で対応する場合
####1. `.gitigonre`に追加
対象のディレクトリまたはファイルを追加する。

```text:.gitignore
*.swp
/path/hogehoge
```

####2. cacheを削除
ステータス変更があるファイルについて`git rm --cached`を実行。

```shell-session
$ git rm --cached [file1 file2...]
```
なお、ステータス変更があるファイルすべてを対象にしたいとき下記コマンドを実行。

```shell-session
$ git rm --cached .
```

[こちら](http://qiita.com/white_aspara25/items/64eafa107b61c6568f01)が参考になる。

###.gitignoreにも記載したくないとき
下記コマンドを実行する、

```
$ git update-index --assume-unchanged [file1 file2...]
```

##やってしまったとき
###はじめに
[こちら](http://qiita.com/shuntaro_tamura/items/db1aef9cf9d78db50ffe)が非常にわかりやすく説明の記載があるので、怖いコマンドを実行する前に自信がないときは一読する。

###`git add`の取り消し
####既にgit管理されている場合
ファイルを指定しない場合、対象がすべてになる。なお`[]`内は省略可能。

```shell-session
$ git reset [[--mixed] HEAD] [file1 file2...]
```

####git管理されていない場合
ファイルではなく`.`を指定すると、対象がすべてになる。

```shell-session
$ git rm --cached [file1 file2...]
```

###`git commit`の取り消し

####ワーキングディレクトリに取り消したcommit内容を反映させる場合
再び、addやcommitができる。

```shell-session
$ git reset --soft HEAD^ 
```

####ワーキングディレクトリに取り消したcommit内容を反映させない場合
元に戻せなくなるので注意が必要。

```shell-session
$ git reset --hard HEAD^ 
```

###`git push`の取り消し
####方法1
`commit_id`値は`git log`で事前に確認しておく。

```shell-session
$ git revert commit_id
$ git push origin branch_name
```

####方法2
強引に戻すので、いったん現状のブランチをバックアップする。`commit_id`値は`git log`で事前に確認しておく。

```shell-session
$ git branch backup_branch
$ git reset --hard commit_id
$ git push -f origin this_origin
```

最後に`force push`をしているので、`git push origin :this_branch`でリモートリポジトリを削除してから、`git push origin this_branch`でもいいが、どちらにしてもこの方法2の利用は避けたいところ。

####方法3
`reflog`に残っている場合。`git reflog`で元に戻したい`HEAD@{n}`を確認し、`git reset --hard`を実行する。
この方法が個人的には一番安全のように思えるが肝心な時に限って`reflog`に残っていないことが多い。

```shell-session
$ git reset --hard HEAD@{n} 
```

####その他
[参考資料](http://tmtms.hatenablog.com/entry/20101221/git)に記載されている内容も確認する。

###特定のファイルを元に戻すとき
特定のファイルをあるコミットの状態に戻したい場合は以下のコマンド。`file`はパスも指定する必要がある。

```shell-session
$ git checkout commit_id file
```

なお、commit前の特定のファイルをheadの状態に戻したい場合は、以下のコマンド。

```shell-session
$ git checkout file
```

##`git config`コマンド
###アカウント変更
プロジェクトごとに変更したい場合、`--global`を省くこと。

```shell-session:
$ git config --global user.name "last first"
$ git config --global user.email local-parts@domain.tld
```

###エディタ変更
emacsに変更したい場合。

```shell-session:
$ git config --global core.editor emacs
```

###`git commit`時のメッセージをテンプレート化する
`~/message/template1.txt`にテンプレートを記載する。

```shell-session
$ git config --global commit.template ~/message/template1.txt
```

###ファイルのパーミッションを変更しても、無視する設定
`chmod`でgit管理下にあるファイルのパーミッションを変更すると、変更したファイルとして扱われてしまう。下記コマンドを実行することで、ファイルのパーミッションを変更しても無視扱いとなる。

```shell-session
$ git config core.filemode false
```

###configの確認
下記コマンドで全てのconfig内容が確認できる。なお、`--list`ではなく`--l`でも結果は同一。

```shell-session
$ git config --list
```

`core.filemode`だけ確認したいときは、下記コマンドで。

```shell-session
$ git config --list | grep core.filemode
```

##`git stash`関連
###リスト表示
まずはstashされている内容を確認する。

```shell-session
$ git stash list
```

###n番目のstash
下記コマンドについて、最新のstashを戻す場合、`stash@{n}`は不要。

####対象ファイル一覧
stashされているファイルの一覧を確認するときは、下記コマンドを実行。

```shell-session
$ git stash show stash@{n}
```

####変更差分
stashされているファイルと現在のワーキングディレクトリの差分を確認するときは下記コマンドを実行。

```shell-session
$ git stash show -p stash@{n}
```

HEADとの差分は下記で確認できる。

```shell-session
$ git diff HEAD..stash@{0}
```

####適用
#####適用したstashを削除する場合
stashされている内容をワーキングディレクトリに反映させた後、そのstashを削除するには下記コマンドを実行。

```shell-session
$ git stash pop stash@{n}
```

#####適用したstashを削除しない場合
stashされている内容をワーキングディレクトリに反映させた後、そのstashを削除しないときは下記コマンドを実行。

```shell-session
$ git stash apply stash@{n}
```

####削除
stashされている内容が不要で、削除するときは下記コマンドを実行。

```shell-session
$ git stash drop stash@{n}
```

##リベース
[こちら](http://www.karakaram.com/git-rebase-i-usage#whats-rebase-i)の資料が非常によくまとまっている。

###master取込
`git merge origin/master`か`git pull origin master`で済ませてしまうことが多い。
`merge`と逆なので非常に注意が必要。失敗することもあるので、`-i`オプションを指定して、インタラクティブモードで処理をしたほうが安全だと思われる。

```shell-session
$ git checkout master
$ git pull origin master
$ git rebase origin origin_target
```

##cherry-pick
`git fetch`を忘れずに。別のブランチでcommitされた内容をワーキングディレクトリに反映させたいときは下記コマンドを実行。

```shell-session
$ git cherry-pick commit_id
```

##パッチ
パッチの扱いについて記載。

###作成
`git add`する前に変更した内容をパッチとして作成したいときは、下記コマンドを実行。

```
$ git diff > branch_name.patch
```

###適用
パッチをワーキングディレクトリに反映させるときは下記コマンドを実行。
ここでは、`-p0`を指定しているので、同じ階層であることに注意。

```shell-session
$ patch -p0 < branch_name.patch
```