gitコマンドまとめ

コマンドメモがわり
※ いろいろアレなので適宜追記・修正予定。。。

#参考
>[【Git】基本コマンド](https://qiita.com/konweb/items/621722f67fdd8f86a017)
[Gitのオプションことはじめ](https://qiita.com/kon_shou/items/e8494585e72403a5308e)

#基本


###初期化

```zsh:gitで管理したいプロジェクトのルートディレクトリまで移動してから
git init
```
Rails`5`系のプロジェクトの場合は最初からgit管理可能な状態っぽいので
`git init`は**不要**。

```zsh:
ディレクトリ内に
.git
ディレクトリが存在すれば、恐らく既に "git init"　済みかと
```


### アカウント登録
コミットするには登録済みの[githubアカウントの情報](https://github.com)を
ターミナルから設定しておく必要がある。下記コマンドで簡単に設定可能

```zsh
git config --global user.email ここに自分のアドレス
git config --global user.name ここに自分の名前
```
>[gitで起きたエラーの解決法](https://qiita.com/w-tdon/items/24348728c9256e5bf945)

### リモートリポジトリとの紐付け
Git管理したいプロジェクトのディレクトリを、Githubに登録したリモートリポジトリと紐付け設定する。これをしないと`git push`でリモートリポジトリへのアップロードができない。
（Githubでのリモートリポジトリ作成前でも実行可能。）

```vim:
git remote add origin https://github.com/ユーザー名/リポジトリ名.git
```
```zsh:確認
git remote -v
```
あとは[Github](https://github.com)でリモートリポジトリが作成されていれば、準備はOK。


#クローン作成
>[githubからだれかのリポジトリを落としてくるときに](https://qiita.com/mountcedar/items/682743c95fd3b8fc274b)

`URL`はgithubサイトの各リポジトリページの
**`Clone or download`**から**コピー**できる

（というか、そのページのURLに`.git`を付けるだけなんだけどね）

```zsh
#プロジェクト配置ディレクトリに移動
cd プロジェクト一覧ディレクトリパス
#クローン実行
git clone <uri>
#ディレクトリ名を指定すると任意のプロジェクト名で（書き換えて）cloneできる。
git clone <uri> [書換え後のディレクトリ名]
```

>[最新リビジョンのみ取得したい場合、--depthを用いて指定する。](https://qiita.com/wwacky/items/2f110ee76fc1cb681c3b)
[git リポジトリの最新の履歴だけを取得する shallow clone](https://qiita.com/usamik26/items/7bfa61b31344206077fb)

```zsh
git clone --depth 1 <gitのURL>

#ディレクトリ名を指定すると任意のプロジェクト名で（書き換えて）cloneできる。
git clone --depth 1 <gitのURL> [書換え後のディレクトリ名]
```

#追加操作
編集中のプロジェクト等で編集内容が確定し、ファイルをコミットする時とか

```zsh
#記録対象を指定
git add .

#コミット = Git（のリポジトリ）に保存する
# -m 以降はコメント（コミット内容の説明）
git commit -m "Initialize repository"
```

# Gitのリモートリポジトリに登録
[githubのリモートリポジトリ](https://github.com)にコミットした情報を登録する。
>https://git-scm.com/docs/git-push

```zsh
#git push  <リモートGit名> <ブランチ名> 
git push origin master

#登録先が同じ場合は、2回目以降下記のコマンドだけで実行可能
git push
```
2回目以降の`git push`は便利だけど、branchが複数ある場合は要注意
>[引数なしのgit pushは危険なので気をつけましょう](http://dqn.sakusakutto.jp/2012/10/git_push.html)

#削除＆取消し

###直前にコミットした時の状態に戻す

```zsh
#ファイル等の削除以前にコミットされていれば、コミットした時の状態に戻すことができる。
git checkout -f
```

###gitにpush済みのファイルをgitから削除
>[gitにpushしてしまっている場合下記のコマンドで削除 | ゼロイチ](https://programming-beginner-zeroichi.jp/articles/60)

```zsh
#既にgitにpushしてしまっている場合下記のコマンドで削除
#git rm --cached ファイル名
git rm --cached .DS_Store

#コミット、プッシュしてリモートリポジトリから削除する
git commit -m "Extermination .DS_Store"                                                                   
git push                                                                                               
```

※ ちなみに、`.DS_Store`に関しては`.gitignore_global`に
記述しておけば最初からGit管理対象に入れないようにできます。
>[グローバルで.gitignoreを適応する](https://qiita.com/katsew/items/5cade12fa743a2f31f25)



###直前コミット戻し ＆ add戻し

```zsh
#直前の コミット を取り消し （コミット履歴は残したまま）
git reset --soft HEAD^
#直前の add を取り消し
git reset HEAD
#ファイル単体で指定して add 取り消し
#git rm --cached ファイル名もしくはファイルパス
git rm --cached config/database.yml
```
```zsh:実行注意
#直前の コミット を取り消し → コミット履歴も消し去る！
git reset --hard HEAD^
```
>[さっきの取り消したい！って時のGitコマンドまとめ](https://qiita.com/kansiho/items/2bacecdb95d752cb38b7)

###ワーキングツリーを戻す
まだaddすらしていないファイル群が対象。
git管理されているファイルで変更（modified:）したものを戻す。

```zsh:すべて
git checkout .
```
```zsh:ファイル単体
git checkout <file>
```
>[【Git】ローカルの修正を前回のcommitまで戻す方法](https://qiita.com/kazu56/items/cf1ad99893ae4f172a7d)

###Untracked files(未追跡ファイル)を削除
新規追加したファイルなどでまだadd等していないのでgit管理されていないファイルが対象
:bangbang: **git clean コマンド実行後は元に戻せないので注意**

```zsh
#削除されるファイルを表示、実際のファイル削除はしない。
git clean -n
#作業ディレクトリから追跡対象外のファイルを削除する（取り消し不可）
git clean
#設定オプション clean.requireForce がfalse 出ない場合は、-f フラグが必須
git clean -f
```
>[git Untracked files(未追跡ファイル)を1発で消し去る](https://qiita.com/harapeko_wktk/items/f329ba818690bdee7dd8)

# git diff
Git管理している `ローカルPCのファイル` とGitの `リモートリポジトリのファイル` とで
**差分見る**やつ

```zsh:サンプル
# touch hoge.txt
```
```zsh:git_addする前に変更差分を確認
git diff

# 指定ファイルの変更差分を見る
git diff -- 指定ファイルのパス
```
↑ git push 後など、変更がなければ何も出力されない

```zsh:git_add後に変更差分を確認
# git add hoge.txt

git diff --cached
```
```zsh:git_commit後に変更差分を確認
# (「最新コミット」と「最新コミットのひとつ前」との差分)

# git commit -m "just hoge" -- hoge.txt

# git diff HEAD^..HEAD
git diff HEAD^..
```
```zsh:ほか
# ファイルごとの変更差分（対象行数）を表示
git diff --stat

# ブランチ同士で比較(ブランチ「hoge」と「master」の場合↓）
git diff hoge..master
```
### --name-only
差分のあるファイルのファイル名だけ出力

```zsh:ファイル名だけ出力して確認
## addの前
git diff --name-only
## add後
git diff --cached --name-only
## commit後
git diff HEAD^ --name-only
```
```zsh:git_addのドライラン時にファイル名で差分確認
#「git add」のドライラン時に「git diff」の結果をファイル名だけで一覧出力
git add -n .; git diff --name-only
```
### ほかオプション
```zsh:
# 改行コード・空白を無視して表示
git diff -w

# 空行を無視して表示
git diff --ignore-blank-lines

# 単語単位で差分比較する
git diff --color-words
```

ほか、詳しくはこちら ↓

>
[忘れやすい人のための git diff チートシート - Qiita](https://qiita.com/shibukk/items/8c9362a5bd399b9c56be)

# git log
コミットログを表示

```zsh:
git log
```
```zsh:オプション例
# 番号とコミットコメントをセットで表示
git log --oneline

# 変更されたファイル（+変更量）を併せて表示
git log --stat

# 完全な差分表示
git log -p
```

# git show
コミットの詳細（変更差分など）を表示

```zsh:
git show
```
```zsh:コミット番号指定で見る場合
# logで番号を確認してから番号指定する

git log --oneline
# or
git log --pretty=format:%h ブランチ名 | head

git show 番号
```
>
[私の使うGitコマンドまとめ 見る編](https://naokirin.hatenablog.com/entries/2011/12/02#git-show)

#.gitignore関連
###すでにGitの管理下にあるものを除外したい
**すでに管理対象となっているファイル**は、.gitignoreに記述しただけでは対象から外れない。下記のように**コマンドラインでの操作が必要**。

```zsh:個別でやる場合
# ファイルの場合　　git rm --cached ファイル名
git rm --cached mfp.cache.js
#  ディレクトリの場合 (-r を忘れずに!)  git rm --cached -r ディレクトリパス
git rm --cached -r cache/

# コミットする(.gitignore変更後にaddしてから)
git add .gitignore
git commit -m "Rewrite .gitignore"
```
```zsh:一気にやっちゃう場合
# 一旦全てを対象から外す
git rm --cached -r .
# あらためて、全てを対象に含める (.gitignoreに記述されたものは除外される)
git add -A .
# コミットする
git commit -m "Rewrite .gitignore"
```

>[Git: バージョン管理の対象から外したいファイルを「.gitignore」に記述する](http://sutara79.hatenablog.com/entry/2015/07/21/115842)
>[git のコミットメッセージ用例集がほしい（2）](http://note103.hateblo.jp/entry/2016/01/20/174218)

# branch関連のコマンドまとめ
```zsh:各コマンドをalias登録しとくと楽なんじゃね？
# branch一覧表示
git branch

# branch作成
git branch ブランチ名

# branch移動
git checkout 移動先のブランチ名

# branch作成 + 移動
git checkout -b 新規作成＆移動先のブランチ名

# branch削除
git branch -d 削除したいブランチ名

# branch名の変更
git branch -m 変更前ブランチ名　名称変更後のブランチ名
# git branch -m hoge piyo

# branchのマージ
git merge ブランチ名
```
```zsh:作業後に指定したブランチ内容をmasterブランチに反映↓

#指定のブランチで作業している想定で
git add .
git commit -m "test commit"
git checkout master
git merge 指定のブランチ名
```
作業ブランチで作業後に`add`,`commit`をせずに`master`ブランチに`checkout`したりすると、作業した内容がそのままmasterブランチに**反映されてしまう**:scream:ので

`ブランチを切り分けて作業している場合`は**checkoutする前に必ずadd/commit作業をする**ことを忘れない様にしたい。:angry:

>別のブランチに元のブランチの修正内容を引き継ぎたくないのであれば、元のブランチでコミットしてからチェックアウトしてください。
[Git - git guiで勝手にマージされる(39310)｜teratail](https://teratail.com/questions/39310)

---

>
[Git ブランチ操作をディレクトリ操作のように使いたいときのエイリアス](https://qiita.com/passionate-engineer/items/a6cc658c7fc32c6d6287)
[ブランチを切り替える](https://backlog.com/ja/git-tutorial/stepup/stepup2_3.html)
[ブランチをマージする](https://backlog.com/ja/git-tutorial/stepup/stepup2_4.html)

---

いや、`git stash`があるよ？:sunglasses:

# git stash
作業ファイルの一時退避コマンド。
`add`したファイルを一時的に退避状態にして他のブランチに移動しても影響が無い様に作業できる。

```zsh:コマンド例
vim hoge.txt
# add
git add hoge.txt
# ファイルを退避
git stash
#Saved working directory and index state WIP on hoge1: c888888 hoge test

# ブランチ移動しても影響なし
# git checkout hoge2

git stash list
#stash@{0}: WIP on hoge1: c888888 hoge test
```
```zsh:一覧表示
# 退避中のファイル一覧を表示
git stash list

# 変更内容つきで確認
git stash list -p

# 変更内容の詳細確認
git stash show スタッシュ名
```

```zsh:ファイル復活
# 退避ファイルの復活
#git stash apply スタッシュ名

git stash apply stash@{0}
```
※ のちのち追記予定

>
[変更を一時的に退避！キメろgit stash](https://qiita.com/fukajun/items/41288806e4733cb9c342)
[色々な git stash](https://qiita.com/akasakas/items/768c0b563b96f8a9be9d)


# 部分merge（cherry-pick）関連
branch から branch へコミット情報を一部反映させる手順的な
**この項目は、コマンドを試していて挙動が不明確な部分があったので、参考までに。。。**


```zsh:merge
# 現在のブランチのコミットログを表示
git log

# 指定のブランチ(hoge)のコミットログを表示
git log hoge

# コミット番号を省略（先頭番号だけに）して表示
#git log --pretty=format:%h ブランチ名
git log --pretty=format:%h master

# コミット番号とコメントをセットで（さらに直近の部分だけにして）表示
#git log --oneline ブランチ名 | head
git log --oneline master | head

git log --oneline develop | head
```
```zsh:cherry-pick
# 現在のブランチを確認
$ git branch
  master
* develop

### [ master <- develop ] したい場合 ###

# 1. ブランチを master ブランチに切り替える
$ git checkout master

# 2. git cherry-pick コマンドで特定のコミット（例：79g584f）をマージする
$ git cherry-pick 79g584f
```
```zsh:
developブランチの「79g584f」コミットだけmasterブランチに反映される
```
この時、コミットの番号はマージ元のブランチからコピーされるわけではなく
マージしたコミット番号として新規登録される。
:bangbang:**これが「マージコミット」とみなされない場合があるので、まだ確認中。。。**

>
[gitで1ファイル（１部分）ずつmergeしたい](https://blog.bgbgbg.net/archives/2197)
[Git で特定のコミットをマージする方法メモ](https://qiita.com/ina_ryu/items/c0cd4a529562f2d5b13e)


```zsh:取り消し
# 一つ前のコミット番号を表示
$ git show | head -1
commit 2dthk7ad36e88b22300ba7dfse656h315g0fcc1z

# マージコミットを取り消し
git revert -m 1 2dthk7
```

>注意が必要なのは、このようにマージコミットを打ち消すと、打ち消されたブランチに含まれていた変更が、その後、そのブランチを再度マージしたとしても、取り込みが発生しない、という事になります。これは、revert により変更自体は打ち消されても、マージの事実が歴史上に残り続けるからです。
[git merge の取り消し方法。reset と revert コマンドについて。](http://www-creators.com/archives/2111)

```zsh:マージコミットの取り消しエラー
error: mainline was specified but commit 49b40aad36e88b25100ba7e7d76e3e315f0fcc1a is not a merge.
fatal: revert failed
```
上記のようなエラーが表示された場合、マージコミットではなく普通のコミットとして記録されているので`git revert HEAD`で戻せる（ ※直前コミットの場合）

```zsh:
git revert HEAD        
```




# git pull
リモートリポジトリの情報を基準としてローカルに同期する。

ローカルで編集中のファイルがあったり、addやcommitしたものがある場合は調整しなければならないが、そうでなければ（`nothing to commit, working tree clean`なら）下記のコマンドで1発同期できる

```zsh:
git pull origin master
```
>
[git pullを使ってリモートリポジトリと同期する方法](https://techacademy.jp/magazine/10274)
[git pull と git pull –rebase の違いって？図を交えて説明します！](http://kray.jp/blog/git-pull-rebase/)
[git pull を強制し、リモートでローカルを上書きする方法](http://www-creators.com/archives/1097)