Git Basics Memo

# Basic Configuration

あなたが何者であるかを Git に登録するところから始めます。

```
inohana:~ inoko$ git config --global user.name 'your name'
inohana:~ inoko$ git config --global user.email 'your email address'
```

次のコマンドでステータスを確認。

```
git config -l
```

コマンドの全量は以下の Man ページをみるべし。

参考リンク
git-scm.com

#  レポジトリ作成

以下のコマンドを入力すると、カレントディレクトリがレポジトリになります。

```
git init
```
コマンドの後ろに名前を入れると、指定した名前のレポジトリが作成できます。
この手順で作られるレポジトリは full repositry と呼ばれます。

```
inohana:~ inoko$ git init gitrepo
Initialized empty Git repository in /Users/inoko/gitrepo/.git/

inohana:gitrepo inoko$ ls
inohana:gitrepo inoko$ ls -la
total 0
drwxr-xr-x   3 inoko  staff   102  7 24 16:29 .
drwxr-xr-x+ 44 inoko  staff  1496  7 24 16:29 ..
drwxr-xr-x  10 inoko  staff   340  7 24 16:29 .git

inohana:gitrepo inoko$ tree .git
.git
├── HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 14 files
```

Tree コマンドがない場合にはこちらの手順でインストールします。
http://qiita.com/kanuma1984/items/c158162adfeb6b217973

以下のコマンドで作成されるのはベアレポジトリです。
先ほど見た .git と同様のディレクトリ構造になっています。ベアレポジトリは.git からワーキングディレクトリを除いたものです。

```
inohana:gitrepo inoko$ git init --bare barerepo
Initialized empty Git repository in /Users/inoko/gitrepo/barerepo/
inohana:gitrepo inoko$  tree barerepo/
barerepo/
├── HEAD
├── branches
├── config
├── description
├── hooks
│   ├── applypatch-msg.sample
│   ├── commit-msg.sample
│   ├── post-update.sample
│   ├── pre-applypatch.sample
│   ├── pre-commit.sample
│   ├── pre-push.sample
│   ├── pre-rebase.sample
│   ├── pre-receive.sample
│   ├── prepare-commit-msg.sample
│   └── update.sample
├── info
│   └── exclude
├── objects
│   ├── info
│   └── pack
└── refs
    ├── heads
    └── tags

9 directories, 14 files
inohana:gitrepo inoko$
```
http://www.nekotricolor.com/entry/theory-of-bare-and-non-bare-repository-manage-wordpress-themes-with-git

```
- ノンベアリポジトリはワーキングディレクトリを持つ。
- ベアリポジトリはワーキングディレクトリを持たない。更新情報だけを持っている。
```

# Cloning Repositories

プロジェクトが始まるとそれまでの Version をクローンするところから始まります。

その前に RSA Key を作成。ここの詳しい手順は他で解説されているのでそちらを参照してください。ここではログだけ貼っておきます。

```
inohana:.ssh inoko$ ssh-keygen -t rsa -C "xxx@jp.xxx.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/inoko/.ssh/id_rsa): inoko@github.com
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in inoko@github.com.
Your public key has been saved in inoko@github.com.pub.
The key fingerprint is:
SHA256:2Jrxxxxxxxxxxxxxxx+K+99R2/OU0 xxx@jp.xxx.com
The key's randomart image is:
+---[RSA 2048]----+
xxxxx
+----[SHA256]-----+

# 公開鍵と秘密鍵が作成された。

inohana:.ssh inoko$ ls -la
total 48
-rw-r--r--   1 inoko  staff   106  4 26 14:21 config
-rw-------   1 inoko  staff  1766  7 24 20:06 inoko@github.com
-rw-r--r--   1 inoko  staff   398  7 24 20:06 inoko@github.com.pub
```
作成した公開鍵を GitHub に登録。
そして config を編集しておきます。ここに接続する時にはこの秘密鍵を使うよーというお約束です。

```
inohana:.ssh inoko$ cat config
Host github.com
	HostName github.com
	IdentityFile ~/.ssh/inoko@github.com
	Port 22
	User git
```

# Advanced Configuration

Git の設定には以下の種類があります。

- System
    - /etc
    - 全レポジトリ、対象のシステムに関する全ユーザに影響する
- Global
    - ~/.gitconfig
    - 単体のユーザに対する全レポジトリに影響する
- Local
    - .git/config
    - 対象のレポジトリのみに影響する

以下のコマンドで編集可能。

```
git config -e --global
git config -e --local
```

Tips:
man git-config コマンドで MAN ページが開かれます。

# Creating Alias

```
git config --global alias.lg `log --graph --oneline --decorate`

git config --global alias.lga `log --graph --oneline --decorate --all`

```
# Checking Status

```
inohana:gitrepo inoko$ pwd
/Users/inoko/gitrepo
inohana:gitrepo inoko$ ls -la
total 0
drwxr-xr-x   4 inoko  staff   136  7 26 09:47 .
drwxr-xr-x+ 50 inoko  staff  1700  7 26 09:47 ..
drwxr-xr-x  10 inoko  staff   340  7 26 09:22 .git
drwxr-xr-x  10 inoko  staff   340  7 26 09:23 barerepo
inohana:gitrepo inoko$
inohana:gitrepo inoko$ vi file1
inohana:gitrepo inoko$ ls -la
total 8
drwxr-xr-x   5 inoko  staff   170  7 26 09:48 .
drwxr-xr-x+ 50 inoko  staff  1700  7 26 09:48 ..
drwxr-xr-x  10 inoko  staff   340  7 26 09:22 .git
drwxr-xr-x  10 inoko  staff   340  7 26 09:23 barerepo
-rw-r--r--   1 inoko  staff    40  7 26 09:48 file1
inohana:gitrepo inoko$
inohana:gitrepo inoko$ git status
On branch master

Initial commit

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

	barerepo/
	file1

nothing added to commit but untracked files present (use "git add" to track)
inohana:gitrepo inoko$ ls -la
total 8
drwxr-xr-x   5 inoko  staff   170  7 26 09:48 .
drwxr-xr-x+ 50 inoko  staff  1700  7 26 09:48 ..
drwxr-xr-x  10 inoko  staff   340  7 26 09:48 .git
drwxr-xr-x  10 inoko  staff   340  7 26 09:23 barerepo
-rw-r--r--   1 inoko  staff    40  7 26 09:48 file1
inohana:gitrepo inoko$
inohana:gitrepo inoko$ echo test > file2
inohana:gitrepo inoko$ ls -la
total 16
drwxr-xr-x   6 inoko  staff   204  7 26 09:50 .
drwxr-xr-x+ 50 inoko  staff  1700  7 26 09:48 ..
drwxr-xr-x  10 inoko  staff   340  7 26 09:48 .git
drwxr-xr-x  10 inoko  staff   340  7 26 09:23 barerepo
-rw-r--r--   1 inoko  staff    40  7 26 09:48 file1
-rw-r--r--   1 inoko  staff     5  7 26 09:50 file2
inohana:gitrepo inoko$ git add file1
inohana:gitrepo inoko$ git status
On branch master

Initial commit

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

	new file:   file1

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

	barerepo/
	file2

inohana:gitrepo inoko$ git add file2
inohana:gitrepo inoko$ git status
On branch master

Initial commit

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

	new file:   file1
	new file:   file2

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

	barerepo/

inohana:gitrepo inoko$ git add -h
usage: git add [<options>] [--] <pathspec>...

    -n, --dry-run         dry run
    -v, --verbose         be verbose

    -i, --interactive     interactive picking
    -p, --patch           select hunks interactively
    -e, --edit            edit current diff and apply
    -f, --force           allow adding otherwise ignored files
    -u, --update          update tracked files
    -N, --intent-to-add   record only the fact that the path will be added later
    -A, --all             add changes from all tracked and untracked files
    --ignore-removal      ignore paths removed in the working tree (same as --no-all)
    --refresh             don't add, only refresh the index
    --ignore-errors       just skip files which cannot be added because of errors
    --ignore-missing      check if - even missing - files are ignored in dry run
    --chmod <(+/-)x>      override the executable bit of the listed files

inohana:gitrepo inoko$ git add --all
inohana:gitrepo inoko$ git status
On branch master

Initial commit

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

	new file:   barerepo/HEAD
	new file:   barerepo/config
	new file:   barerepo/description
	new file:   barerepo/hooks/applypatch-msg.sample
	new file:   barerepo/hooks/commit-msg.sample
	new file:   barerepo/hooks/post-update.sample
	new file:   barerepo/hooks/pre-applypatch.sample
	new file:   barerepo/hooks/pre-commit.sample
	new file:   barerepo/hooks/pre-push.sample
	new file:   barerepo/hooks/pre-rebase.sample
	new file:   barerepo/hooks/pre-receive.sample
	new file:   barerepo/hooks/prepare-commit-msg.sample
	new file:   barerepo/hooks/update.sample
	new file:   barerepo/info/exclude
	new file:   file1
	new file:   file2

inohana:gitrepo inoko$ echo modified > file2
inohana:gitrepo inoko$ git status
On branch master

Initial commit

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

	new file:   barerepo/HEAD
	new file:   barerepo/config
	new file:   barerepo/description
	new file:   barerepo/hooks/applypatch-msg.sample
	new file:   barerepo/hooks/commit-msg.sample
	new file:   barerepo/hooks/post-update.sample
	new file:   barerepo/hooks/pre-applypatch.sample
	new file:   barerepo/hooks/pre-commit.sample
	new file:   barerepo/hooks/pre-push.sample
	new file:   barerepo/hooks/pre-rebase.sample
	new file:   barerepo/hooks/pre-receive.sample
	new file:   barerepo/hooks/prepare-commit-msg.sample
	new file:   barerepo/hooks/update.sample
	new file:   barerepo/info/exclude
	new file:   file1
	new file:   file2

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file2

inohana:gitrepo inoko$ git status -sb
## Initial commit on master
A  barerepo/HEAD
A  barerepo/config
A  barerepo/description
A  barerepo/hooks/applypatch-msg.sample
A  barerepo/hooks/commit-msg.sample
A  barerepo/hooks/post-update.sample
A  barerepo/hooks/pre-applypatch.sample
A  barerepo/hooks/pre-commit.sample
A  barerepo/hooks/pre-push.sample
A  barerepo/hooks/pre-rebase.sample
A  barerepo/hooks/pre-receive.sample
A  barerepo/hooks/prepare-commit-msg.sample
A  barerepo/hooks/update.sample
A  barerepo/info/exclude
A  file1
AM file2
```
# Basic Committing 
レポジトリはサンドボックス。
Indexはステージングエリア。

```
inohana:gitrepo inoko$ git diff
diff --git a/file2 b/file2
index 9daeafb..2e09960 100644
--- a/file2
+++ b/file2
@@ -1 +1 @@
-test
+modified
inohana:gitrepo inoko$ git commit
[master (root-commit) b7daa30] create files.
 16 files changed, 545 insertions(+)
 create mode 100644 barerepo/HEAD
 create mode 100644 barerepo/config
 create mode 100644 barerepo/description
 create mode 100755 barerepo/hooks/applypatch-msg.sample
 create mode 100755 barerepo/hooks/commit-msg.sample
 create mode 100755 barerepo/hooks/post-update.sample
 create mode 100755 barerepo/hooks/pre-applypatch.sample
 create mode 100755 barerepo/hooks/pre-commit.sample
 create mode 100755 barerepo/hooks/pre-push.sample
 create mode 100755 barerepo/hooks/pre-rebase.sample
 create mode 100755 barerepo/hooks/pre-receive.sample
 create mode 100755 barerepo/hooks/prepare-commit-msg.sample
 create mode 100755 barerepo/hooks/update.sample
 create mode 100644 barerepo/info/exclude
 create mode 100644 file1
 create mode 100644 file2
inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file2


modified a file.

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$ git add -a
error: unknown switch `a'
usage: git add [<options>] [--] <pathspec>...

    -n, --dry-run         dry run
    -v, --verbose         be verbose

    -i, --interactive     interactive picking
    -p, --patch           select hunks interactively
    -e, --edit            edit current diff and apply
    -f, --force           allow adding otherwise ignored files
    -u, --update          update tracked files
    -N, --intent-to-add   record only the fact that the path will be added later
    -A, --all             add changes from all tracked and untracked files
    --ignore-removal      ignore paths removed in the working tree (same as --no-all)
    --refresh             don't add, only refresh the index
    --ignore-errors       just skip files which cannot be added because of errors
    --ignore-missing      check if - even missing - files are ignored in dry run
    --chmod <(+/-)x>      override the executable bit of the listed files

inohana:gitrepo inoko$ git add -A
inohana:gitrepo inoko$ git commit
[master 2a7aa4b] modified a file.
 1 file changed, 1 insertion(+), 1 deletion(-)
inohana:gitrepo inoko$
inohana:gitrepo inoko$
inohana:gitrepo inoko$ git status
On branch master
nothing to commit, working tree clean
inohana:gitrepo inoko$ echo modified2 > file2
inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file2

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$ git diff
diff --git a/file2 b/file2
index 2e09960..226081b 100644
--- a/file2
+++ b/file2
@@ -1 +1 @@
-modified
+modified2
inohana:gitrepo inoko$ git commit -m "second modified."
On branch master
Changes not staged for commit:
	modified:   file2

no changes added to commit
inohana:gitrepo inoko$ git add -f file2
inohana:gitrepo inoko$ git commit -m "second modified."
[master f5eb4f9] second modified.
 1 file changed, 1 insertion(+), 1 deletion(-)
inohana:gitrepo inoko$


inohana:gitrepo inoko$ git status
On branch master
nothing to commit, working tree clean
inohana:gitrepo inoko$ cat file2
modified2
inohana:gitrepo inoko$ echo modified3 > file2
inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file2

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$ git diff
diff --git a/file2 b/file2
index 226081b..18bb937 100644
--- a/file2
+++ b/file2
@@ -1 +1 @@
-modified2
+modified3

# -a オプションで全ファイルをAdd
# -v オプションで差分表示を実施
# メッセージを入力せずに Quit すると Commit されない

inohana:gitrepo inoko$ git commit -av
Aborting commit due to empty commit message.

inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file2

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$
```

# Advanced Committing

複数の更新があるが、別々にコミットしたい場合以下のコマンドを使用。

```
git add --patch
git add -p
```

```
inohana:gitrepo inoko$ git status
On branch master
nothing to commit, working tree clean
inohana:gitrepo inoko$ vi file1
inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file1

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$ git diff
diff --git a/file1 b/file1
index 399645f..1ecc582 100644
--- a/file1
+++ b/file1
@@ -1,4 +1,5 @@
 #01
+line1
 #02
 #03
 #04
@@ -6,5 +7,6 @@
 #06
 #07
 #08
+line8
 #09
 #10
inohana:gitrepo inoko$ git add -p
diff --git a/file1 b/file1
index 399645f..1ecc582 100644
--- a/file1
+++ b/file1
@@ -1,4 +1,5 @@
 #01
+line1
 #02
 #03
 #04
Stage this hunk [y,n,q,a,d,/,j,J,g,e,?]? y
@@ -6,5 +7,6 @@
 #06
 #07
 #08
+line8
 #09
 #10
Stage this hunk [y,n,q,a,d,/,K,g,e,?]? n

inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	modified:   file1

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file1

inohana:gitrepo inoko$ git commit -m "line1 committed"
[master c384fd1] line1 committed
 1 file changed, 1 insertion(+)
inohana:gitrepo inoko$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file1

no changes added to commit (use "git add" and/or "git commit -a")
inohana:gitrepo inoko$ git diff
diff --git a/file1 b/file1
index abcada0..1ecc582 100644
--- a/file1
+++ b/file1
@@ -7,5 +7,6 @@ line1
 #06
 #07
 #08
+line8
 #09
 #10
```
# Viewing History

```
git log
git log --graph
git log --graph --oneline
git log --graph --oneline --decorate
git log --graph --oneline --decorate --all
git show [SHA-1]
gitk --all
```

1行目はこのコミットのSHA-1 Hash
2行目は親
3行目は作業者
4行目は日付
その他 コメント

```
inohana:gitrepo inoko$ git log
commit c384fd1a4e3d24f8874e3124ccd0b420e4037802
Author: INOKO <xxx@jp.xxx.com>
Date:   Wed Jul 26 10:11:43 2017 +0900

    line1 committed
```

# Renaming and Deleting files

git オプションをつけると自動でステージング(add)に追加される。

```
inohana:gitrepo inoko$ git status
On branch master
nothing to commit, working tree clean
inohana:gitrepo inoko$ ls
barerepo	file1		file2
inohana:gitrepo inoko$ git mv file1 file3
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    file1 -> file3

inohana:gitrepo inoko$ git diff
inohana:gitrepo inoko$ git diff --cached
diff --git a/file1 b/file3
similarity index 100%
rename from file1
rename to file3
inohana:gitrepo inoko$ vi file3
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:



  (use "git reset HEAD <file>..." to unstage)

	renamed:    file1 -> file3

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   file3

inohana:gitrepo inoko$ git add file3
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    file1 -> file3

inohana:gitrepo inoko$ vi newfile1
inohana:gitrepo inoko$ cat newfile1
inohana:gitrepo inoko$
inohana:gitrepo inoko$ git mv newfile1 newfile2
fatal: not under version control, source=newfile1, destination=newfile2
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    file1 -> file3

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



test
	newfile1

inohana:gitrepo inoko$ git add -A
inohana:gitrepo inoko$ git commit -a
[master af21070] test
 2 files changed, 1 insertion(+)
 rename file1 => file3 (88%)
 create mode 100644 newfile1
inohana:gitrepo inoko$ git status
On branch master
nothing to commit, working tree clean


hello
inohana:gitrepo inoko$ ls
barerepo	file2		file3		newfile1
inohana:gitrepo inoko$ git mv newfile1 newfile2
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    newfile1 -> newfile2

inohana:gitrepo inoko$ git diff --cached
diff --git a/newfile1 b/newfile2
similarity index 100%
rename from newfile1
rename to newfile2
inohana:gitrepo inoko$ vi newfile2
inohana:gitrepo inoko$ cat newfile2
hello
goodbye
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    newfile1 -> newfile2

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   newfile2

inohana:gitrepo inoko$ git add newfile2
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	deleted:    newfile1
	new file:   newfile2

inohana:gitrepo inoko$ ls
barerepo	file2		file3		newfile2
inohana:gitrepo inoko$ mv file2 file4
inohana:gitrepo inoko$ ls
barerepo	file3		file4		newfile2
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	deleted:    newfile1
	new file:   newfile2

Changes not staged for commit:
  (use "git add/rm <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	deleted:    file2

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

	file4

# ファイル内容の変更が大きいと、new file として認識される

inohana:gitrepo inoko$ git add file2 file4
inohana:gitrepo inoko$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

	renamed:    file2 -> file4
	deleted:    newfile1
	new file:   newfile2

```
# Ignore Files
トラッキングしたくないファイルは以下のファイルにファイル名を記述しておくと git status で見えなくなる。
正規表現も使用可能。サブディレクトリも対象となる。

```
.gitignore
```

レポジトリ作成の際自動的にできる以下のファイルに記述しても同様。

```
.git/info/exclude
```

global config に記述も可能。
自分のレポジトリでバージョンファイルを行いたくないものを記載。

```
inohana:info inoko$ git config core.excludesfile
/Users/inoko/.gitignore_global
inohana:info inoko$ cat ~/.gitignore_global
*~
.DS_Store
```
.gitignore, .gitignore_global どちらに記載すべきかはこちらを参照。
http://qiita.com/elzup/items/4c92a2abdab56db3fb4e