Gitチートシート

[Gitチートシート](https://qiita.com/ktarow/items/1d8c8ae698a88b1d6f0f)の補い

## 特定のファイルだけコミットする
`--`のあとでスペース区切りでファイルを指定

```
git commit -m "update" -- foo.cpp hoge.cpp
```

## .gitignoreの書き方
([出典](https://qiita.com/inabe49/items/16ee3d9d1ce68daa9fff))

```
# "#" で始まる行はコメント
*.exe # 拡張子exeは無視
bin/  # binの中身は無視
!/bin/readme.txt # ただし/bin/readme.txtは含める
package/**/*.xml # packageフォルダ内の拡張子xmlのファイルは無視
*local_back/     # 階層にかかわらずlocal_backという名前のフォルダをすべて除外する
```


## .gitignoreを反映させる
`git add .`などした後に、.gitignoreを更新した場合はこうする、
ローカルのファイルが削除することなく、gitのキャッシュを削除する。([出典](https://qiita.com/fuwamaki/items/3ed021163e50beab7154))

```
git rm -r --cached .          //ファイル全体キャッシュ削除
git rm -r --cached [ファイル名]  //ファイル指定してキャッシュ削除
```

## 最後のコミットに変更を追加する
([出典](https://qiita.com/piruty/items/402b5bf83479f7e3480a))

```
$ git add . 
$ git commit --amend --no-edit
```

## コミットメッセージを変更する
一番新しいコミットのメッセージを変更する。([出典](https://qiita.com/piruty/items/2fbfd26fd8dcbfed592a))

```
git commit --amend -m "new comment"
```

2つ以上前のコミットのメッセージを変更する。([出典](https://tmg0525.hatenadiary.jp/entry/2017/10/12/181416))

```
$ git rebase -i HEAD~2
pick <コミット1のhash> update hoge.cpp
pick <コミット2のhash> 古いコメント
// 以下に書き換える
pick <コミット1のhash> update hoge.cpp
edit <コミット2のhash> 新しいコメント
$ git commit --amend 
$ git rebase --continue
``` 

## コミットを取り消す

```
git reset --soft HEAD^ // ローカルファイルには影響しない
git reset --hard HEAD^ // ローカルファイルもコミット前に戻す
```

## 初回のコミットを取り消す
この方法で初回のコミットを取り消すことができるが、初回のコミットの場合以外でも使える。([出典](https://suzuken.hatenablog.jp/entry/2014/03/28/100311))

```
git update-ref -d HEAD
```

## コミットの取り消しを取り消す
`git reflog`で内容を確認して、取り消す地点を選ぶ。([出典](https://qiita.com/ngron/items/7870fc8a803b882af9bd))

```
$ git reflog
4231432 HEAD@{1}: reset: moving to HEAD^
5432554 HEAD@{2}: commit: update foo
5432656 HEAD@{3}: commit: update bar
$ git reset --soft HEAD@{1}
```

## コミットの順番を入れ替える
([出典](https://qiita.com/Ishidall/items/28a955a6d3e96ad4b9bf))

```
// 過去3つ分のコミットを表示
$ git rebase -i HEAD~3
pick <コミット1のhash> update hoge.cpp
pick <コミット2のhash> update fuga.cpp
pick <コミット3のhash> update piyo.cpp
// コミット2とコミット3を入れ替える
edit <コミット1のhash> update hoge.cpp
pick <コミット3のhash> update piyo.cpp
pick <コミット2のhash> update fuga.cpp
// 保存して完了
```

## コミットをまとめる
```
$ git rebase -i HEAD~3
pick <コミット1のhash> update hoge.cpp
pick <コミット2のhash> update fuga.cpp
pick <コミット3のhash> update piyo.cpp
// コミット2にコミット3を統合する
pick <コミット1のhash> update hoge.cpp
pick <コミット2のhash> update fuga.cpp
fixup <コミット3のhash> update piyo.cpp
// 保存して完了
```

## 複数個前のコミットにさかのぼって履歴を書き換える
([出典](https://qiita.com/zaneli@github/items/8d519a229653a2ed9ec6))

```
$ git rebase -i HEAD~3
pick <コミット1のhash> update hoge.cpp
pick <コミット2のhash> update fuga.cpp
pick <コミット3のhash> update piyo.cpp
// さかのぼりたいコミットのpickをeditに変更して保存
edit <コミット1のhash> update hoge.cpp
pick <コミット2のhash> update fuga.cpp
pick <コミット3のhash> update piyo.cpp
$ git add hoge.cpp     
$ git commit --amend    // 新しいhoge.cppの変更をコミット1に加える
$ git rebase --continue // コミット1の書き換えが完了
```

## CommiterとAuthorを変更する
([出典](https://qiita.com/sea_mountain/items/d70216a5bc16a88ed932))
### 以降のコミットに反映させる
Commiterを変更する

```
git config --local user.name "your-name"
git config --local user.email "foo@example.com"
git commit --amend
```
Authorを変更する

```
git commit --amend --author="your-name <foo@example.com>"
git rebase --continue
git push -f
```

### 過去のコミットをすべて変更する
```
git filter-branch -f --env-filter "GIT_AUTHOR_NAME='your-name'; GIT_AUTHOR_EMAIL='foo@example.com'; GIT_COMMITTER_NAME='your-name'; GIT_COMMITTER_EMAIL='foo@example.com';" HEAD 
```