Gitの基本的な使い方メモ

今まで TortoiseGit を使って SVN のノリでだましだまし使ってたけど、そろそろちゃんとコマンドを覚えようと。

#環境
##OS
- Windows 7 64bit SP1

#インストール
[Git for Windows](http://msysgit.github.io/) をインストールする。

#リポジトリを作成する
```text:
> git init

> dir /b /a
.git
```

- `git init` でカレントフォルダを Git のリポジトリにできる。
- `.git` という名前の隠しフォルダが作成される。
- カレントフォルダが、そのまま __作業ディレクトリ__ にもなる（SVN とちょっと違う）。
- 以下のようにフォルダ名を指定することもできる。

```text:
> git init my_repo
```

#リポジトリをクローンする
```text:
> git clone <リポジトリフォルダへのパス>
```

- `git clone` でリポジトリのクローンが作成できる。
- カレントフォルダにリポジトリと同じ名前のフォルダが作成され、そこがクローンしたリポジトリ兼作業ディレクトリになる。

#コミット時のユーザー名・メールアドレスを設定する
```text:
> git config --global user.name <ユーザー名>

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

- `git config` で Git の設定をできる。
- `user.name` がコミット時のユーザー名、 `user.email` がメールアドレスの設定。
- `--global` オプションをつけると、現在のユーザー（OS）で Git を使った場合のデフォルト値を設定できる。
- `--global` を省略した場合は、現在のリポジトリだけで有効な設定になる。

##global 設定が保存されているファイル
- `--global` 指定で保存した設定は、 `<ユーザーのホームフォルダ>\.gitconfig` に保存されている。
- ホームフォルダは、 `C:\Users\<ユーザー名>` （Windows7 の場合）。
- この `.gitconfig` を直接編集しても問題ない。

```text:.gitconfig
[user]
	name = hoge
	email = hoge@gmail.com
```

##設定値を確認する
```text:
> git config <確認したい設定の名前>

> git config --list
```

- `git config <確認したい設定の名前>` で、指定した設定の現在の値を確認できる。
- `--list` オプションで、全ての設定値を確認できる。

##設定を削除する
```text:
> git config --unset <削除したい設定の名前>
```

#ファイル（フォルダ）をステージングに追加する
```text:
> git add <ファイル or フォルダ>
```

- `git add` で、リポジトリに変更のあったファイルやフォルダを __ステージング__ に登録できる。

##ステージング
![git.JPG](https://qiita-image-store.s3.amazonaws.com/0/28302/fe15424a-80cf-609d-4173-313284b770cd.jpeg)

ステージングは、 SVN には無かった概念。
SVN では、作業ディレクトリの変更内容を直接リポジトリにコミットしていた。
この概念を理解せずに SVN のノリで Git を使っていると、なんだかモヤモヤした感じで Git を使うことになる。

Git では、コミットしたい変更内容を一旦「ステージング」と呼ばれる領域に登録する。
そしてコミットをすると、ステージングに登録されていた変更内容だけがリポジトリに反映される。

`add` コマンドは、このステージングに変更内容を登録するためのコマンドであり、リポジトリにファイルなどを新規追加するためのコマンドではない（SVN の add とは違う）。
なので、既にリポジトリに存在するファイルも、更新してコミットしたい場合は、 `add` コマンドでステージングに一旦登録することになる。

ステージングが存在することで、１つのコミットに含める変更内容をファイル単位で細かく制御できるようになる。

インデックスとも呼ぶ。
help を見ると index って書いてるから、インデックスが正解なのかも。

#ステージングに登録した内容を取り消す
```text:
> git reset
```

- `git reset` すると、ステージングに登録した変更内容を全て取り消す。
- 作業ディレクトリのファイルは一切変更されない（変更内容が元に戻ることはない）。

##ファイルを指定して取り消す
```text:
> git reset <ファイル>
```

- ファイルを指定して取り消すこともできる。
- この場合も、ファイルの内容は一切変更されない。

#コミットする
```text:
> git commit
```

- 現在ステージングに登録されている変更内容を、リポジトリにコミットする。
- デフォルトでは、コミットコメントを記述するために CUI のテキストエディタが立ち上がる。
- 使い方は vi エディタとだいたい同じで、エディタを終了するとコミットが完了する。

##コミットコメントを指定する
```text:
> git commit -m "commit comment"
```

- `-m` オプションでコミットコメントをコマンドと一緒に指定できる。
- この場合、専用のエディタは起動せずにそのままコミットが実行される。

##コミット時のエディタを変更する
```text:
> git config --global core.editor '<エディターを実行するためのコマンド>'
```

- `core.editor` を設定することで、コミット時のエディタを任意のエディタに変更できる。
- 自分は Windows ユーザーで、普段サクラエディタを使っている。
- 試しに `git config --global core.editor 'sakura'` としたら、普通にサクラエディタが開いてくれた。
- ※サクラエディタのインストールフォルダにパスを通しておく必要があります。

#作業ディレクトリとステージングの状態を確認する
```text:管理外のファイルが存在する場合
> git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        text.txt

nothing added to commit but untracked files present (use "git add" to track)
```

```text:ステージングにコミット待ちのファイルが存在する場合
> git status
On branch master

Initial commit

Changes to be committed:
  (use "git rm --cached <file>..." to unstage)

        new file:   text.txt
```

```text:作業ディレクトリとリポジトリに差異がなく、ステージングも空の場合
> git status
On branch master
nothing to commit, working directory clean
```

- `git status` コマンドで以下のことが確認できる。
    - 現在の作業ディレクトリとリポジトリとの間で差異がないか。
    - ステージングにコミット待ちのファイルが存在するか。

#無視するファイルを指定する
```text:
> type .gitignore
*.class
```

- `.gitignore` というファイルを作成して、リポジトリで管理したくないファイルを列挙する。
- ワイルドカード（`*`）を使える。

#コミットログを確認する
```text:
> git log
```

- 現在のリポジトリの全コミットログが閲覧できる。
- 量が多い場合は、 `less` でファイルを見た時みたいにページング操作ができる形で表示される。

```text:出力例
commit b5572844e448af6f8325e27d5f17a41227742599
Author: opengl8080 <tomcat.port.8080+github@gmail.com>
Date:   Sat Sep 13 23:16:33 2014 +0900

    modify

commit 3c1313cbf48401af6e79153c00a6f0713e31dbc0
Author: opengl8080 <tomcat.port.8080+github@gmail.com>
Date:   Sat Sep 13 23:06:53 2014 +0900

    add
```

##表示件数を制限する
```text:
> git log -n <表示上限>
```

- `-n` オプションで、表示件数を制限できる。

##各コミットを１行で表示させる
```text:
> git log --oneline
b557284 modify
3c1313c add
```

- `--oneline` オプションで、１つのコミットの表示を１行に絞れる。

##コミットコメントで検索する
```text:
> git log --grep="<検索パターン>"
```

- `--grep` オプションで、コミットコメントを条件にした検索ができる。

##特定のファイルのコミットログだけを確認する
```text:
> git log <ファイルパス>
```

## ログをグラフ形式で表示する
```
> git log --graph
```

#最近実行したコマンドの履歴を確認する
```text:
> git reflog
```

- `git log` は commit のログだけが確認できるが、 `reflog` は commit 以外のコマンドの履歴が確認できる。
- 記録されている数には限りがある。

#ファイルを削除する
```text:
> git rm <削除するファイル>
```

- `git rm` でファイルを削除できる。
- 作業ディレクトリからも、物理的にファイルが削除される。

#特定のリビジョンに戻る
```text:
> git checkout <コミットハッシュ>
```

- 現在の作業コピーの状態を、指定したコミットハッシュの時点に戻すことができる。
- コミットハッシュは、 `git log` コマンドで確認できる。

```text:コミットハッシュの確認
> git log
commit 142d5a4f287a914c88e595ae10b4372a13ebfbe5
Author: opengl8080 <tomcat.port.8080+github@gmail.com>
Date:   Sun Sep 14 11:10:02 2014 +0900

    modify2

> git log --oneline
142d5a4 modify2
```

- `142d5a4f287a914c88e595ae10b4372a13ebfbe5` または `142d5a4` がコミットハッシュ。

##ファイルを指定する
```text:
> git checkout <コミットハッシュ> <ファイル>
```

- ファイルを指定して、特定のリビジョンに戻すことができる。

##リポジトリの最新に戻す
```text:
> git checkout <ブランチ名>
```

- master で作業しているなら `git checkout master`。

#過去のコミットを打ち消す
```text:
> git revert <コミットハッシュ>
```

- `revert` は、過去のコミットを削除するのではなく、過去のコミットを打ち消す形で新規にコミットを行うコマンド。
- `revert` コマンドが実行されると、コミットコメント用にエディタが起動し、エディタを終了するとそのままコミットが実行される。

##自動コミットしないようにする
```text:
> git revert -n <コミットハッシュ>
```

- `-n` をつけると、自動コミットしないようにできる。
- コミットは、後で手動で行う。

##revert を取り消す
```text:
> git revert --abort
```

- 自動コミットオフや、コンフリクトして `revert` がコミットされていない状態になることがある。
- そのときに、 revert を取り消すには `git revert --abort` を実行する。

#現在の変更内容を取り消す
## ファイルを指定
```text
> git checkout HEAD <ファイルパス>
```

## 全ファイル一括で取り消す
```text:
> git reset --hard
```

- ステージングに登録されている変更を取り消し、作業ディレクトリのファイルの変更内容も取り消される。
- 編集中のファイルは、編集前の状態に戻される。

#リポジトリに登録されていないファイルを削除する
```text:
> git clean -f
```

- リポジトリに登録されていないファイルを削除するには `git clean -f` を使う。
- `-f` オプションは、 `clean.requireForce` 設定オプションが true の場合は必須になる（デフォルトは true なので、指定が必須になる）。

##clean で削除されるファイルを確認する
```text:
> git clean -n
```

- `-n` オプションを指定すると、削除されるファイルをリストアップできる。

#変更内容の差分を確認する
```text:
> git diff
```

- 作業ディレクトリ内で変更のあったファイルを探し、差分を表示する。
- 変更があったファイル全部が表示の対象になる。

##ファイルを指定して差分を確認する
```text:
> git diff <ファイル>
```

- ファイルを指定して差分を確認できる。

##WinMerge で差分を確認する
- まず、 `.gitconfig` を以下のように設定する。

```text:.gitconfig
[diff]
    tool = WinMerge
    guitool = WinMerge
[difftool "WinMerge"]
    path = C:/Program Files/WinMerge/WinMergeU.exe
    cmd = \"C:/Program Files/WinMerge/WinMergeU.exe\" -e -ub -dl \"Base\" -dr \"Mine\" \"$LOCAL\" \"$REMOTE\"
```

- WinMergeU.exe の場所はデフォルトのインストール先なので、違うのであれば適宜修正。
- diff を確認するときは、以下のように `difftool` コマンドを使用する。

```text:
> git difftool
```

- 変更のあったファイル１つごとに、 `Lanch 'WinMerge' [Y/n]:` という確認メッセージが表示され、 `Y` を入力すると WinMerge が起動して差分が確認できる。
- WinMerge を閉じると、次のファイルを確認してよいか再び確認メッセージが表示される。
- １ファイルずつ指定して確認したい場合は、 `git difftool <ファイル>` とする。

#ブランチを作成する
```text:
> git branch <ブランチ名>
```

- ブランチを作成するだけで、作業ディレクトリは変更されない。

#存在するブランチを確認する
```text:
> git branch
* master
  sample
```

- 現在のリポジトリに存在する全てのブランチを一覧表示する。

#ブランチを削除する
```text:
> git branch -d <ブランチ名>
```

- 指定した名前のブランチを削除する。
- マージしていないコミットが存在する場合はエラーになる。
- マージしてなくても削除した場合は `-D` オプションを指定する。

#ブランチを切り替える
```text:
> git checkout <ブランチ名>
```

- `checkout` でブランチを切り替えることができる。

#ブランチを新規に作成して、同時に作成したブランチに切り替える
```text:
> git checkout -b <ブランチ名>
```

- `<ブランチ名>` で指定したブランチを作成して、そのブランチを `checkout` する。

#ブランチをマージする
```text:
> git merge <マージするブランチ名>
```

- `git merge` で、現在のブランチに指定したブランチの変更をマージできる。
- マージで競合が発生した場合は、競合を解決してから `add` -> `commit` する。

#サーバー用のリポジトリを作成する
```text:
> git init --bare
```

- カレントディレクトリをサーバー用のリポジトリにする。
- サーバー用と言っているのは、プロジェクトのメインとなるリポジトリであることを指す。
- 開発者はこのリポジトリをローカルにクローンして、 push, pull を使ってコードを更新する。
- `--bare` オプションを設定してリポジトリを作成しないと、 push, pull ができない。

#クローン元のリポジトリから最新のコードを取得する
```text:
> git pull
```

- クローン元のリポジトリから最新のコードを取得し、ローカルのリポジトリにマージする。
- 競合が発生した場合は、手動で修正してコミットする。

#クローン元のリポジトリに、ローカルのリポジトリを反映する
```text:
> git push
```

- 現在のブランチの情報をクローン元に反映する。
- ローカルに pull してから push するまでに別の push が行われていた場合は、エラーが発生して push できない。
    - その場合は、 pull して最新をマージしてから push し直す。

#タグを作成する
```text:
> git tag <タグ名>
```

- 名前だけの単純なタグを付ける場合は、 `git tag <タグ名>` で作成する。
- コレを、__軽量タグ__と呼ぶ。

##コメントを付ける
```text:
> git tag -a <タグ名> -m "<コメント>"
```

- `-a` オプションを指定することで、コメントを付けたタグを作成できる。
- これを、__注釈付きタグ__と呼ぶ。

#タグを確認する
```text:
> git tag
```

- 存在するタグの一覧が表示される。

#タグを削除する
```text:
> git tag -d <タグ名>
```

- `-d` オプションを指定することで、タグを削除できる。

#タグの詳細情報を表示する
```text:
> git show <タグ名>
```

- 指定したタグのコメントなど、詳細な情報が表示される。

#参考
- [Git チュートリアルとトレーニング| Atlassian](https://www.atlassian.com/ja/git/)
- [Gitの外部エディタにTextmateやvimを使う - Seasons.NET](http://blog.seasons.cc/entry/20090331/1238526187)
- [Gitのdiff・mergeをgitconfigだけでWinMergeにする - ぷちてく - Petittech](http://ptech.g.hatena.ne.jp/noromanba/20120602/1338633091)
- [タグ | サルでもわかるGit入門 〜バージョン管理を使いこなそう〜 | どこでもプロジェクト管理バックログ](http://www.backlog.jp/git-guide/stepup/stepup4_1.html)