#topicpath();
/////////////////////////////////////////////////////////////////////////////////
#contents();

/////////////////////////////////////////////////////////////////////////////////
* Links [#links]
** Git について [#about-git]
- [[Gitを使いこなすための20のコマンド>http://sourceforge.jp/magazine/09/03/16/0831212]]
- [[サルでもわかるGit入門>http://www.backlog.jp/git-guide/]]
- [[もっと早く知りたかった! Gitが鬼のようにわかるスライド厳選7選>http://www.find-job.net/startup/7-git-slides]]
- [[Git の基礎勉強 ~ Git によるバージョン管理>http://tracpath.com/bootcamp/learning_git_firststep.html]]
- [[Gitによるバージョン管理入門 for windows>http://www.plowman.co.jp/school/Git/Git.html]]

** Downloads [#xb3ff64e]
- [[Git 配布元>http://git-scm.com/]]



/////////////////////////////////////////////////////////////////////////////////
* 使い方 [#qe3c4374]
//===============================================================================
** git init : 新規リポジトリ作成 [#git-init]
+ 空リポジトリの作成
 $ mkdir hoge.git         # bare repository 用の空ディレクトリを作成
 $ cd hoge
 $ git init --bare --shared=true   # bare repository として初期化。管理ファイル群が生成される。共有にするには --shared=true にする
+ 作業用リポジトリの作成
 $ cd ..
 $ git clone hoge          # hoge.git から hoge という名前で bare ではないリポジトリとして複製する
+ 作業用リポジトリでファイルを登録
 $ cd hoge
 /* 何かしらの方法で新しいファイル fuga を置く */
 $ git add fuga           # ファイル "fuga" が登録対象になる(まだ登録されていない)
 $ git commit             # 前の git add で指定されたファイルが登録される 


//===============================================================================
** git clone : git リポジトリの複製 [#v0292b1a]
- 書式:
 $ git clone [options...] <repository> [<directory>]
-- <repository> で指定したリポジトリを複製する
- オプション
|~option |~description |
|--recursive |リポジトリ内に含まれる [[submodule>#git-submodule]] も同時に複製する。|
|--bare |bare repository として clone する |
|-o (--origin) <origin-repository> |複製先で使用する、複製元のリポジトリ名を <oritin-repository> として指定する&br;指定しなかった場合は "origin" が使われる |
|-b (--branch) <branch-name> |複製先の HEAD が指すブランチの名前を <branch-name> で指定する。&br;指定しない場合は、複製元の HEAD が指すブランチが使われれる。 |
|--morror |ミラーリポジトリとして複製元リポジトリを複製する。&br;複製元リポジトリ自体もミラーリポジトリだった場合は、その追跡ブランチなどの参照情報も、複製元から完全にコピーされる。|



//===============================================================================
** git commit : 登録済みのファイルに変更が加えられた場合 [#git-commit]
- 再び add, commit を行う
 $ git add <変更を加えたファイル>
 $ git commit

//-------------------------------------------------------------------------------
*** git commmit --amend : commit をやり直す [#git-commit--amend]
- 既に commit 済みのものを修正して commit する場合、
 (1)再度 commit する。履歴は全て別々に残る
 (2)commit をやり直す。履歴はやり直した分だけが残る
の2つの選択肢がある。やり直しの対象となる commit のログを残したくない場合、やり直し時に "--amend" オプションをつけることで実現できる。
 $ git add hoge
 $ git commit --amend

//===============================================================================
** .git [#q72b64dd]
- リポジトリの中に出来る .git の中身は以下のようになっている:
 $ ls -l .git/
 合計 60
 -rw-r--r--   1 user1 user1    24 11月 22 18:13 COMMIT_EDITMSG
 -rw-r--r--   1 user1 user1   293 10月 10 14:19 FETCH_HEAD
 -rw-r--r--   1 user1 user1    48 10月 28 02:13 GITGUI_MSG
 -rw-r--r--   1 user1 user1    23  5月  4  2015 HEAD
 -rw-r--r--   1 user1 user1    41 10月 10 14:19 ORIG_HEAD
 drwxr-xr-x   2 user1 user1     6  5月  4  2015 branches
 -rw-r--r--   1 user1 user1   315 10月 28 02:14 config
 -rw-r--r--   1 user1 user1    73  5月  4  2015 description
 drwxr-xr-x   2 user1 user1  4096  5月  4  2015 hooks
 -rw-r--r--   1 user1 user1 19357 11月 22 18:12 index
 drwxr-xr-x   2 user1 user1    20  5月  4  2015 info
 drwxr-xr-x   3 user1 user1    28  5月  4  2015 logs
 drwxr-xr-x 186 user1 user1  4096  9月 20 19:08 objects
 drwxr-xr-x   5 user1 user1    43  5月  4  2015 refs

- それぞれは、以下のように使われる 
|~name |~description |
|HEAD |現在チェックアウトされているブランチ(HEAD)がどういう参照情報化が書かれている |
|config |この git リポジトリの設定内容 |
|description |この git リポジトリの説明が記述される。&br;GitWeb でリポジトリを HTTP 公開したり、メールでコミットメッセージを送信するときなどに利用される。 |
|hooks/ |このディレクトリは如何にフックスクリプトを配置する |
|info/ |この git リポジトリで無視したいファイルを info/exclude に記述する |
|objects/ |この git リポジトリで管理する git オブジェクトの実体がここに配置される |
|refs/ |ブランチやタグが指す git オブジェクトがどれかという参照情報がここに置かれる |



//===============================================================================
** git revert : commit を取り消す [#git-revert]
- 「取り消す」とはいっても、 commit の痕跡自体は消せるわけではなく、単に元に戻すための commit ができますよ、という機能。
+ まず、git log で対象 commit の hash を確認
 $ git log
 commit bdf1da8aecdfbe5a83ce93e78e2ad8a241b1530b
 Author: hogehoge <hogehoge@fuga.com>
 Date:   Mon May 4 13:33:13 2015 +0900
 
     fix build break for System
 
 commit 1072326e20c9dd482d5e1db46419b0412317d693
 Author: hogehoge <hogehoge@fuga.com>
 Date:   Mon May 4 13:12:33 2015 +0900
 
     delete Makefile.bak
 
 ...
+ 対象を確認したら、 hash を指定して revert する
 $ git revert bdf1da8aecdfbe5a83ce93e78e2ad8a241b1530b
-- 即座に commit log 編集画面になる。

//===============================================================================
** git reset: git commit や git add をなかったことにする [#git-reset]
 $ git reset [commit-hash]
- [commit-hash] を取り消す
- [commit-hash] を指定しなかった場合、HEAD が指定されたとみなされる
- [commit-hash] には以下が使用出来る:
-- HEAD: 最新
-- <commi-hash>^ or <commit-hash>^1 : <commit-hash> の1個前
-- <commi-hash>^^ or <commit-hash>^2 : <commit-hash> の2個前
- 但し、remote へ push 済みの commit に対して reset を行なっても、 reset を remote には push 出来ないようなので注意が必要。
- --hard を使用すると、作業中のリポジトリに状態が反映される
- --soft (もしくは指定ナシ)の場合、git のステータスが変わるだけになる。

//-------------------------------------------------------------------------------
*** commit を取り消すには [#obe3c6fc]
- local にのみ commit されていて remote に push されていない commit は、commit 自体を取り消すことが出来る。~
これは [[git revert>#git-revert]] のように「commit を打ち消す内容の変更差分を生成して commit する」のとは違い、履歴から commit 自体を抹殺する。
- 取り消したい commit の hash を AAAA とすると、
 $ git reset --hard AAAA^   # AAAA の1個前の commit まで戻る
※コミット自体を取り消す場合には、少なくとも対象のより1個前の commit まで履歴を戻るのがポイント。


//===============================================================================
** branch の名前 [#branch-name]
*** リポジトリの現在の branch 名を表示 [#g036243a]
 $ git branch
 * work

*** branch 名を変更する [#x3a53663]
- デフォルトでは "master" になっているが、用途に合わせて任意の名前を付けることが出来る。
- 変更するリポジトリ内にて、以下のようにする:

 $ git branch -m <元の名前> <新しい名前>



//===============================================================================
** git push: リポジトリの変更を他のリポジトリに反映する [#git-push]
 $ git push <反映先> <反映元>
- options
|~option |~description |
|-u, --set-upstream |新規に作成したリポジトリやブランチを push する際に、ローカルリポジトリと push 先のリポジトリとのブランチ対応付けを行う。&br;対応付けを行うことにより、次回以降 push 時にブランチ名を省略できる。|
|--all |ブランチを全て push する |
|--tags |全ての tag を push する(*) |
|--mirror |リモートリポジトリに、ローカルリポジトリの内容をそのまま複製したいときに使用する。ローカルで削除されたブランチはリモートでも削除される |
|--delete |リモートリポジトリのブランチを削除する |
|-n, --dry-run |変更情報の送信とリモートリポジトリへの反映結果を確認する。実際にはリモートリポジトリへの反映は行われない |
|-f, --force |リモートブランチがローカルブランチの派生元でない場合でも、強制的に上書きする。&br;リモートブランチのコミット情報を失う場合があるので、注意が必要 |
|--progress |標準エラーに進捗状況を出力する |
|<repository> |push 対象となるリポジトリを指定する。リモート名または URI を指定する |
|<refspec> |<src>:<dst> のフォーマットで送信元:送信先ブランチを指定する。例えば、branch-a から branch-b に push する場合、次のように指定する:&br;branch-a:branch-b |
- (*): git push --tag では、ローカルの全てのタグが送信される。この場合は意図しないものまで送信してしまう可能性もある。タグの push は、以下のように1つずつ指定して行うのが安全である:
 $ git push <dst-branch> <local-tag-name>:<remote-tag-name>

//-------------------------------------------------------------------------------
*** branch を明示して push する [#p03ee305]
 $ git push <src-branch-name>:<dst-branch-name>

//-------------------------------------------------------------------------------
*** local で新規作成した branch を remote へ push する [#f9525e3f]
 $ git push <remote-repository> <local-new-branch-name>

//-------------------------------------------------------------------------------
*** push 出来ない [#gefdcd5c]
- push.default が設定されていない場合
-- push 先のリモートブランチが指定されてない場合に起きる
-- デフォルトリモートブランチを設定して解決する
 $ git config --add branch.<local-branch-name>.remote <remote-name>
 $ git config --add branch.<local-branch-name>.merge <remote-branch-name>
 $ git push -u <remote-branch-name> <local-branch-name>

//===============================================================================
** branch 操作 [#y0bb3352]
*** branch 作成 [#t63da454]
- 例として新しく作成する branch の名前を "work1" とする
- (例えば masterのディレクトリ内で)次の操作を行う
 $ git checkout work1
*** branch 切り替え [#d2701e8e]
- 切り替えの時も git branch を実行する。操作が成功すれば以下のようにブランチが切り替わったことを通知するメッセージが表示される
 $ git checkout work1
 Switched to branch 'work1'
-- この時、元の branch と work1 の間に差分があれば、現在のディレクトリの内容も work1 の最新の状態に切り替わる
-- 但し、元の branch で修正して commit さてていない変更点がある場合、その差分はそのまま残される。つまりその変更点が存在する状態で work1 に切り替わっている

*** 不要になった branch の削除 [#wdab01db]
- 不要になった branch work1 を削除するには、
 $ git branch -d work1

//===============================================================================
** 他の branch に commit を反映する [#git-merge]
 $ git merge <反映先 branch>


//===============================================================================
** tag  [#git-tag]
- 現在のリポジトリの最新に対してタグ <tag-name> を付ける場合
 $ git tag <tag-name>
- 特定の commit <commit-hash> に tag  を付ける場合
 $ git tag <tag-name> <commit-hash>
- 既に親 repository に push してしまった commit に後から tag を打っても、親 repository には反映できない。~
→ git push --tags を使う
 $ git push --tags # 全ての tag 情報を push する
- tag の削除
 $ git tag -d <tag-name>

//===============================================================================
** commit されていない変更点の確認 [#v1309767]
- 全ての差分を表示
 $ git diff
- 変更された管理対象のファイルの一覧を見る
 $ git clean [-n]
-- -n の代わりに -f を付けると、全ての変更を revert する
- 管理対象外のファイルも含め、変更ファイルの一覧を見る
 $ git status


//===============================================================================
** conflict への対処 [#conflict]
- 競合する修正が入っている場合、手元のファイルが最新ではないと判断されるため、push に失敗する。そこで一旦 pull をすることになるが、ここで下記のようなエラーメッセージが表示される:
 $ git pull
 remote: Counting objects: 5, done.
 remote: Compressing objects: 100% (2/2), done.
 remote: Total 3 (delta 0), reused 0 (delta 0)
 Unpacking objects: 100% (3/3), done.
 From /home/kazu/work/git_test/a
    1413a9c..ac702ad  master     -> origin/master
 Auto-merging 1.txt
 CONFLICT (content): Merge conflict in 1.txt
 Automatic merge failed; fix conflicts and then commit the result.

- conflict の発生例
 AAAAA
 <<<<<<< HEAD
 BBBBBBBBB
 CCCCCCCCCCCCCCCCCCCCCCC
 DDDD
 EEEEEEEEEEEEE
 =======
 111111111111111111
 22222222222
 33333333333333333333
 4444444
 >>>>>>> ac702ad3f09388ac676c926b7a03c2a97a77f94f
-- 書式
  <<<<<<< HEAD
 (手元での修正)
 =======
 (<commit-name> によって変更された修正)
 >>>>>>> <commit-name>

- conflict の編集
-- git mergetool を実行すると merge 用のプログラムが呼び出される。
--- emacs + magit を使用している場合は、magit の画面から通常の手順で ediff を呼び出す
-- conflict 編集後、 git add <file-name>; git commit すると、conflict を解消した旨のコメントが予め用意された log 記入画面が表示される:
  Merge branch 'master' of /path/repos-dir
  
  Conflicts:
      1.txt
  #
  # It looks like you may be committing a merge.
  # If this is not correct, please remove the file
  #   .git/MERGE_HEAD
  # and try again.
  ...


//===============================================================================
** git log : ログの表示(変更履歴の閲覧)[#git-log]
- オプション無し
 commit 772a23b56ce10fd0b986d84a265ed25d5723cee8
 Author: user-name <hoge@example.com>
 Date:   Sun Jul 5 12:16:20 2015 +0900
 
     [mod] disc.shtml: modify link URI

- --stat ファイル名を表示する
 commit 772a23b56ce10fd0b986d84a265ed25d5723cee8
 Author: user-name <hoge@example.com>
 Date:   Sun Jul 5 12:16:20 2015 +0900
 
     [mod] disc.shtml: modify link URI
 
  disc.shtml |    2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

- --name-status : ファイル名とステータスを表示する(svn log -v とほぼ同内容の情報)
 commit 772a23b56ce10fd0b986d84a265ed25d5723cee8
 Author: user-name <hoge@example.com>
 Date:   Sun Jul 5 12:16:20 2015 +0900
 
     [mod] disc.shtml: modify link URI
 
 M       disc.shtml

- --numstat
 commit 772a23b56ce10fd0b986d84a265ed25d5723cee8
 Author: user-name <hoge@example.com>
 Date:   Sun Jul 5 12:16:20 2015 +0900
 
     [mod] disc.shtml: modify link URI
 
 1       1       disc.shtml

- --name-only : ファイル名の情報のみ追加する
 commit 772a23b56ce10fd0b986d84a265ed25d5723cee8
 Author: user-name <hoge@example.com>
 Date:   Sun Jul 5 12:16:20 2015 +0900
 
     [mod] disc.shtml: modify link URI
 
 disc.shtml

//===============================================================================
** git reflog : リポジトリ上での git 作業履歴を表示する [#git-reflog]
- [[git log>#git-log]] が commit 履歴のみを表示するのに対し、git reflog では、 commit 以外の作業履歴、例えば pull reset の履歴も表示する。
- 操作例
 $ git reflog
 fff7841 HEAD@{9}: pull: Merge made by the 'recursive' strategy.
 9fdb195 HEAD@{10}: commit: Modify Link URI
 e56109d HEAD@{11}: reset: moving to HEAD^
 d5df2c7 HEAD@{12}: reset: moving to d5df2c7858f198496fca335d22dec36a50bb91b0
 69ab6a1 HEAD@{13}: pull: Fast-forward
 d5df2c7 HEAD@{14}: reset: moving to d5df2c7858f198496fca335d22dec36a50bb91b0
 69ab6a1 HEAD@{15}: pull: Fast-forward
 d5df2c7 HEAD@{16}: reset: moving to d5df2c7858f198496fca335d22dec36a50bb91b0
 69ab6a1 HEAD@{17}: commit: 再修正
 d5df2c7 HEAD@{18}: commit: リンク集 URI 修正

//===============================================================================
** git show : 詳細を表示する [#git-show]
- git show <commit-hash>
-- 指定した <commit-hash> の詳細を表示する
- git show <tag>
-- tag が -a や -m で付加情報付きで打たれている場合、Date, Tagger などの情報を表示する。


//===============================================================================
** git stash : ローカルの変更内容を隠蔽する [#m78f093c]
- ローカルに変更がある状態では、 git pull, git push どちらも操作不可能になることがある。こうした場合に、一旦ローカルの変更内容を隠蔽した上で git pull し、競合などを解消させてからローカルの変更を push すれば良い。
//-------------------------------------------------------------------------------
*** git stash : ローカルの変更を隠蔽する [#jee86ab2]
 $ git stash

//-------------------------------------------------------------------------------
*** git stash list : 隠蔽したローカルの変更一覧を表示する [#l1f16854]
 $ git stash list

//-------------------------------------------------------------------------------
*** git stash pop : stash の最新を1つ適用し、stash のリストから削除する [#c4d0a3ba]
 $ git stash pop

//-------------------------------------------------------------------------------
*** git stash apply : stash を適用する [#qc1ff45f]
 $ git stash apply
- 実行後、 stash のリストは変更されない

//-------------------------------------------------------------------------------
*** git stash drop : stash のリストからエントリを削除する [#n2e35862]
 $ git stash frop


//===============================================================================
** git rebase [#git-rebase]
- branch の分岐点を変更する
- options

//-------------------------------------------------------------------------------
*** 分岐元のコミットを変更 [#l46bcfcf]
- branch_X から branch_Y が分岐した点を A から A2 に変更する場合
 $ git rebase A2 branch_Y
~
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 ===== --- branch_X
     |
     +== B1 == B2 == B3 == B4 ===             --- branch_Y
 
                  ↓
 
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 =====   --- branch_X
                    |
                    +== B1 == B2 == B3 == B4 =  --- branch_Y
 

- branch_X から branch_Y が分岐した点を A から branch_X の最新に変更する場合
 $ git rebase branch_X branch_Y
~
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 ===== --- branch_X
     |
     +== B1 == B2 == B3 == B4 ===             --- branch_Y
 
                  ↓
 
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 =====   --- branch_X
                                      |
                                      +== B1 == B2 == B3 == B4 =  --- branch_Y
 
//-------------------------------------------------------------------------------
*** 分岐元の branch を変更する [#pe4e10a8]
- branch_Z の分岐元を、元々の分岐元 branch_Y から branch_X に変更する~
→ branch_Z を、branch_Y の内容を含まない、branch_X から直接分岐した branch に変更する
 $ git rebase --onto branch_X branch_Y branch_Z
~
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 ===== --- branch_X
     |
     +== B1 == B2 == B3 == B4 ===             --- branch_Y
                     |
                     +=== C1 ==== C2====      --- branch_Z
 
                  ↓
 
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 =====   --- branch_X
     |
     +== B1 == B2 == B3 == B4 ===             --- branch_Y
     |
     +=== C1 ==== C2====      --- branch_Z
 
//-------------------------------------------------------------------------------
*** rebase の再開・スキップ・中止 [#pb771d9d]
 $ git rebase --continue | --skip | --abort
|~option |~description |
|--continue |競合解決中に、 rebase を再開したい場合に指定する |
|--skip |競合解決中に、 その commit を skip したいときに指定する。skip した commit は適用されない |
|--abort |競合解決中に、rebase を中止し、 rebase 開始前の状態に戻りたい場合に指定する |



//===============================================================================
** git remote : remote の repository を指定する [#git-remote]
- リモート名<name> で、<url> の repository にアクセス出来るように設定する。
- 書式
 $ git remote add [-t <branch>] [-f] [--tags|--no-tags] [--mirror] <name> <url>
- オプション
|~option |~description |~remark |
|-t <branch> |pull で更新内容を取得するリモートブランチを限定出来る。 |ブランチは複数指定可能 |
|-f |リモートを設定した後、リモートリポジトリから fetch する | |
|--tags &#x7c; --no-tags |remote コマンドでは、デフォルトではリモートブランチのHEAD から参照出来る tag のみ取得する。&br; このオプションが指定されると、tag を取得しない。 | |
|--mirror |リモートリポジトリがベアリポジトリの場合、push 実行時にローカルリポジトリの内容を常にリモートリポジトリに複製するようになる。 |バックアップ用途、他のサーバにリポジトリのコピーを置きたい場合に使用する。 |
|rm <name> |リモート名 <name> の設定とローカルリポジトリに取得されたリモートブランチ(リモート追跡ブランチ)を削除する | |


//===============================================================================
** git bundle : 直接通信できないリポジトリと同期を取る [#git-bundle]
- ファイルベースでリポジトリの差分をやり取りする方法
- 作成したバンドルファイルは、リポジトリと同様、 clone, fetch, pull の対象とすることが出来る。
- バンドルファイルの作成
 $ git bundle create <file> <git-rev-list-args>
-- <file> : 出力先のファイル
-- <git-rev-list-args> : branch や tag、commit などを指定する~
あるタグから特定ブランチの HEAD まで等、範囲指定も可能。
-- tag hoge-tag から branch <fuga> の HEAD までの範囲を指定して作成する場合は、次のようにする:
 $ git bundle create <file> hoge-tag..fuga

- バンドルファイル <file> の妥当性を確認する
 $ git bundle verify <file> [refname]
-- [refname] : branch 名、 HEAD などを指定し、特定の branch 名や HEAD に関連する情報のみを表示する

- バンドルファイル <file> 内で定義されている commit などの情報を表示する
 $ git bundle list-heads <file> [<refname>...]
-- <refname> : branch 名、HEAD などを指定できる。指定したものに関連する情報のみ表示されるようになる。

- バンドルファイルを使った clone, fetch, pull
-- clone
+++ clone する
 $ ls
 hoge.bundle
 $ git clone hoge bundle hoge
 Cloning into 'hoge'...
 Receiving objects: 100% (1616/1616), 15.62 MiB | 0 bytes/s, done.
 Resolving deltas: 100% (629/629), done.
 Checking connectivity... done.
 warning: remote HEAD refers to nonexistent ref, unable to checkout.
+++ ここで clone した中身を見ると、.git しか存在しない
 $ cd hoge
 $ls -a
 . .. .git
+++ branch を checkout して、初めて管理下のファイルが姿を現す
 $ git checkout master
 Branch master set up to track remote branch master from origin.
 Already on 'master'
 $ ls
 archive  chat  index.shtml  menu.html   pukiwiki-plugins  wiki
 bbs      img   linux.css    menu.shtml  test


//===============================================================================
** git pull [#b02dc842]
- git pull は、"git fetch; git merge" を実行するのと同じである。

//-------------------------------------------------------------------------------
*** git pull --rebase [#d59c5526]
- local に未 push の commit がある状態で git pull --rebase を実行すると、その local commit を自動的に rebase する。つまり
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 ===== --- remote branch
     |
     +== B1 == B2 : local repository に commit された変更(local の HEAD が A0から分岐したB2になった状態)
                  ↓
                git pull --rebase
                  ↓
 
 == A0 ==== A1 ==== A2 ===== A3 ==== A4 =====   --- remote branch
                                     |
                                     +== B1 == B2 : local repository に commit された変更(local の HEAD が A4から分岐したB2になった状態)
 
 
//-------------------------------------------------------------------------------
** branch を指定した pull [#dce3e1a8]
- refspec を指定する
 $ git pull <refspec>





//===============================================================================
** fetch と pull [#o20ecc07]
- fetch と pull は、いずれも remote repository の変更を取得する
- 変更取得後、fetch はマージを行わず、 pull はマージを行う(pull = fetch + merge)
- 機械的な merge により競合が意図しない解決をされてしまうのを避けるには、pull の使用を避け、fetch と merge を別個に行うのが好ましい。



//===============================================================================
** git submodule : リポジトリに他のリポジトリを組み込む [#git-submodule]
- git のリポジトリの中に、他のリポジトリを組み込むためのもの

//-------------------------------------------------------------------------------
*** submodule の組み込み [#git-submodule-add]
- 既存のリポジトリ foo のディレクトリ構造の中に、別のリポジトリ bar を組み込む場合
 foo: http://foobar.com/foo.git   # aa.txt が commit されている
 bar: http://foobar.com/bar.git   # ps-ax.log が commit されている
+ foo.git の clone
 $ git clone http://foobar.com/foo.git
+ foo 内にディレクトリ baz を作り、外部リポジトリの http://foobar.com/bar.git を組み込む
 $ cd foo
 $ git submodule add http://foobar.com/bar.git baz  # ここでディレクトリ foo/baz が作成される
 Cloning into 'baz'...
 done.
 $ ls -a
 .  ..  .git  .gitmodules  aa.txt  baz  # .gitmodules と baz が追加された
 
 # ここで、baz が初期化される場合とされない場合がある。
 # git submodule とtype したときに表示される hash に "-" がついていれば、 baz は初期化されていない。
 # この場合は次のように手動で初期化する必要がある
+ baz の初期化
 $ git submodule init baz
 Submodule 'baz' (http://foobar.com/bar.git) registered for path 'baz'
 $ git status
 # On branch master
 # Changes to be committed:
 #   (use "git reset HEAD <file>..." to unstage)
 #
 #	new file:   .gitmodules
 #	new file:   baz
 #
+ 組み込んだ submodule を commit & push する。この時 git add は不要。
 $ git commit
 $ git push
 
//-------------------------------------------------------------------------------
*** submodule を組み込んだリポジトリを clone する [#la4acbc3]
+ foo を clone する
 $ git clone http://foobar.com/foo.git new-foo
 $ cd new-foo
 $ ls
 aa.txt  baz  # 先ほど追加し、 commmit & push した baz が出来ている
 $ ls -a baz
 .  ..     # 単にからディレクトリが出来ただけ。
 $ git submodule
 -386b630fd974b3f3147d462cda2c1f50813131fc baz    # hash に "-" が付いており、初期化されていないことが分かる
+ submodule を初期化する
 $ git submodule init baz
 Submodule 'baz' (http://foobar.com/bar.git) registered for path 'baz'
 $ ls -a baz
 .  ..     # この段階でも、まだ baz は空ディレクトリのままになっている
+ submodule の中身を最新にする
 $ git submodule update
 Cloning into 'baz'...
 done.
 Submodule path 'baz': checked out '386b630fd974b3f3147d462cda2c1f50813131fc'
 $ ls -a baz/
 .  ..  .git  ps-ax.log    # bar.git の中身が baz に clone される



//===============================================================================
** git diff : 差分を表示する [#git-diff]
- git diff を実行すると diff/patch 風の差分を表示するが、実はこのままでは余計な付加文字列があるために patch コマンドで使用することは出来ない。~
patch で使えるフォーマットで差分を出力したい場合には
 $ git diff --no-prefix
とする必要がある。

//===============================================================================
** git config : 各種設定 [#git-config]
- 設定を記録するファイルは、下記の3つがある。
-- ${HOME}/.gitconfig --- ユーザのグローバルな設定
-- ${REPOSITORY_DIR}/.git/config --- git リポジトリ ${REPOSITORY_DIR} 内限定で有効な設定
-- ${prefix}/etc/gitconfig --- システムワイドな設定

//-------------------------------------------------------------------------------
*** ユーザアカウントに関する設定 [#git-config-user]
- ユーザアカウント、メールアドレスを登録出来る。これらは commit log で commit したユーザの情報として使用される。
- global で設定しても、 local で設定しても良い(が、通常は global になるだろう)。
 $ git config --global user.name "UserName"
 $ git config --global user.email "account@example.com"


//-------------------------------------------------------------------------------
*** alias の設定 [#git-config-alias]
- Subversion における "svn commit" に対する "svn ci" のようなエイリアスは git にはデフォルトでは存在しないが、しかし自分で好きなように設定することが出来る。
 $ git config --global alias.ci "commit"   # "git commit" を "git ci" でも実行できるようにする
 $ git config --global alias.co "checkout"
 $ git config --global alias.st "status"

//-------------------------------------------------------------------------------
*** defalut の設定を無効にする [#jb1a54c6]
- 設定項目に対して空文字列を指定する
- pager を使わないようにする
 $ git config --global core.pager ''

//-------------------------------------------------------------------------------
*** 設定項目 [#zdb3844f]
|~configuration item |~description |~remark |
|user.name |ユーザ名を指定する | |
|user.email |ユーザのメールアドレスを指定する | |
|receive.denyNonFastFowards |true に設定すると、 push 時に repository 上の commit が含まれない commit を送信しようとしたときに branch の更新を拒否する |shared repository で設定する |
|receive.denyDeletes |true に設定すると、ブランチの削除を拒否する |shared repository で設定する |
|receive.fsckObjects |true にすると、push されたときにデータ一貫性のチェックを行う。信頼性が向上するが、 push 処理に時間が掛かるようになる。|shared repository で設定する |
|core.pager |pager を指定する |例えばless, lv など |
|alias.<alias-name> |任意の git コマンド(commit, checkoutなど)を <alias-name> でも呼び出せるようにする | |



//-------------------------------------------------------------------------------
*** 設定をエディタで編集する [#hde2f8b0]
 $ git config <--local|--global|--system> <-e|--edit>

//-------------------------------------------------------------------------------
*** 現在の設定を確認する [#vc27d4b7]
 $ git config <-l|--list>

//-------------------------------------------------------------------------------
*** 設定を削除する [#delete-config]
- 指定した <key> の設定を削除する
 $ git config [--local|global|--system] --unset <key>
- 全ての設定を削除する
 $ git config [--local|global|--system] --unset-all


//===============================================================================
** .gitignore : git が無視するファイルを指定する [#cab5fdf3]
- ローカルの git リポジトリ上に存在し得るもので、且つ git の管理対象にしたくないことが分かっているファイルは、 .gitignore ファイルに記述する
- .gitignore に記述することで、git status で非表示に出来たり、git add などのコマンドでうっかり追加してしまったりすることを防ぐことが出来る。
- .gitignore の記述方法は、ファイル名や * を使って指定できる
- .gitignore の記述例
 *.bak
 *.o
 tmp
- 作成した .gitignore は、リポジトリにコミットしておく
 $ git add .gitignore
 $ git ci -m "[add] .gitignore"
 $ git push

/////////////////////////////////////////////////////////////////////////////////
* <refspec> とは [#refspec]
- git の説明によく出てくる <refspec> とは、pull や push で指定する
 <src>:<dst>
の書式による、ブランチ指定のこと。


/////////////////////////////////////////////////////////////////////////////////
* [[Subversion>VersionCtl/Subversion]] とのコマンド対比 [#q65add11]
|~Git |~Subversion |~Description |
|git init |svnadmin create |リポジトリ作成 |
|git clone |svn checkout |リポジトリのコピー |
|git add <file> |svn add <file> |ファイルの追加 |
|git add <file>; git commit |svn commit [file] |ファイルの更新をリポジトリに反映 |
|git rm <file> |svn rm <file> |ファイルの削除(別途、要 commit) |
|git status |svn status | |
|git log [file] |svn log [file] |ログを表示する |
|git log --shortstat --name-status | svn log -v |追加・変更されたファイル名を含めたログを表示する |
|git log -<number> | svn log -l <number> |最新から <number> 個のログエントリを表示する |
|git blame <file> |svn blame <file> |<file> の各行がいつ誰によって変更されたかを表示する |
|git checkout <branch> |svn switch <branch> | |
|git merge <branch> |svn merge <branch> | |
|git checkout <file> |svn revert <file> |ファイルに対して行った(リポジトリに未反映の)変更を元に戻す |
|git clean -f |svn revert [dir] |~|
|git pull <remote> <local> | svn up[date] |<remote> の最新状態を <local> に merge する |


/////////////////////////////////////////////////////////////////////////////////
* tools [#tools]
//===============================================================================
** git-sh [#y50d6b1c]
- git コマンドを打つときに "git" と入力するのを省略できるようになる
- 現在のリポジトリと branch の名前がプロンプトに表示されるため、 branch コマンドを打つ必要もなくなる。



/////////////////////////////////////////////////////////////////////////////////
* tools on emacsen[#tools]
//===============================================================================
** [[magit>VersionCtl/Git/magit]] [#magit]
- リポジトリ: https://github.com/magit/magit.git
- debian の場合、 magit パッケージを install すると、即使えるようになる。
- psvn.el のように、 "e" (※注: "E" ではない)で差分を ediff で閲覧・ merge 出来る

//===============================================================================
** git-gutter+ [#git-gutter-plus]
- リポジトリ: https://github.com/nonsequitur/git-gutter-plus.git
- [[git-gutter>#git-gutter]] よりも高速らしい

//===============================================================================
** git-gutter [#git-gutter]
- [[git-gutter.el>http://emacs-jp.github.io/packages/vcs/git-gutter.html]]


/////////////////////////////////////////////////////////////////////////////////
* GUI tools [#gui_tools]
//===============================================================================
** gitk [#gitk]
- 起動
 $ gitk
- Tk で書かれている
- committer, commit 日時、 log, diff などを1画面で表示する UI になっており、個々の commit の内容を追いかける場合には非常に見やすい
- 閲覧にはいいが、commit の機能はない


//===============================================================================
** git-gui [#git-gui]
- 起動
 $ git gui
- git の公式な GUI である模様
- X 版は Tk で書かれている
- Windows 版もある
- merge, branch 操作、 commit など、ある程度の操作が出来る。


トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS