[Git][備忘録][Windows]Pro Gitと入門gitでGitの復習 ブランチ編
前回までのあらすじ
今回はローカルブランチから。
参考
- http://progit.org/:title
- 入門git
他のVCSとの違い
- Subversionなどは各ファイルに対しての差分を時間軸で持っていた
- Gitではコミットのたびにその時のリポジトリ全体のスナップショットをとる
- ただし、変更がなかったファイルは以前のスナップショットで格納したファイルへのリンクを貼っている
Gitのオブジェクト
Gitには大きく分けて4つのオブジェクトが存在する。
- Commitオブジェクト
- Treeオブジェクト
- Blobオブジェクト
- Tagオブジェクト
Commitオブジェクト
リポジトリのルート。ファイル情報(ツリー)やメタデータを格納している。以下のコミットのCommitオブジェクトを見てみる。
$ git log --pretty=oneline
5f431a8cf6023e7398102dfef8b88baf1c581023 Typo 4
log –pretty=rawコマンドを実行するとハッシュタグがいろいろと。
$ git log --pretty=raw 5f431a8cf6023e7398102dfef8b88baf1c581023
commit 5f431a8cf6023e7398102dfef8b88baf1c581023
tree de445cf5b526c554dea465d09cea6d65059d1f80
parent a59ff99de68cbf359c814f25cda9c926ef9cdad9
author kk_Ataka <test@example.com> 1329818747 +0900
committer kk_Ataka <test@example.com> 1329819044 +0900
Typo 4
|*commit|このコミットに対するSHA1名|
|*tree|このコミットの中身を記載しているSHA1名|
|*parent|一つ前のコミットのSHA1名。存在しない場合はそれが一発目(Rootコミット)、マージされた場合は1つ以上になる場合もある|
|*author|作成者|
|*committer|コミッター|
author, committerあたりがメタデータになるのかな。
Treeオブジェクト
あるコミット時点の中身を格納している。ls-treeコマンドかshowコマンドで確認が出来る。ls-treeコマンドの方が詳しい。
$ git ls-tree 5f431a8cf6023e7398102dfef8b88baf1c581023
100644 blob 27f338f5bd0c368f96e063127705bd1bb81e992a README # ファイル
100644 blob 0dc64072619bf0734c878d90e9150b6978898083 index.html # ファイル
100644 blob 543200914423ddc0cb2249c322f262e31ee11c55 menu.html # ファイル
100644 blob c447b5cfd585f44aafef7d513c5efea5471e2848 convert.rb # ファイル
040000 tree a1117a81580de591d292b9e6d80deee3e1cabd85 testdata # ディレクトリ
#testdataディレクトリを調査
$ git ls-tree a1117a81580de591d292b9e6d80deee3e1cabd85
040000 tree a9da0b188817cc119eff96f4c8db5306d0be009d init # ディレクトリ
#initディレクトリを調査
$ git ls-tree a9da0b188817cc119eff96f4c8db5306d0be009d
100644 blob 2918a6642d19aadf2b11213978ae6044166a87e0 read_cell # ファイル
showで調査する場合はこんな感じ。ファイル名だけ?
#initディレクトリを調査
$ git show a9da0b188817cc119eff96f4c8db5306d0be009d
tree a9da0b188817cc119eff96f4c8db5306d0be009d
read_cell
実行権、ファイルタイプ、SHA1名、ファイル名が出力される。ファイルタイプは超ざっくりこんな感じみたい。
|*blob|普通のファイル|
|*tree|ディレクトリ|
Blobオブジェクト
ファイルそのもの。showコマンドで見る事が出来るのはファイルの中身。
#READMEを調査
$ git show 27f338f5bd0c368f96e063127705bd1bb81e992a
Hello Wrld
#index.htmlを調査
$ git show 0dc64072619bf0734c878d90e9150b6978898083
<html>
<head>
<title>Welcome</title>
</head>
<body>
<h1>Hello</h1>
<p>Hello world !!</p>
</body>
</html>
#menu.htmlを調査
$ git show 543200914423ddc0cb2249c322f262e31ee11c55
<html>
<head>
</head>
<body>
<h1>menu</h1>
</body>
</html>
で、ブランチ
ブランチはこの一つのCommitオブジェクトをさすポインタとなる。今は最新がこれ。
$ git log --pretty=raw 5f431a8cf6023e7398102dfef8b88baf1c581023
commit 5f431a8cf6023e7398102dfef8b88baf1c581023
tree de445cf5b526c554dea465d09cea6d65059d1f80
parent a59ff99de68cbf359c814f25cda9c926ef9cdad9
author kk_Ataka <test@example.com> 1329818747 +0900
committer kk_Ataka <test@example.com> 1329819044 +0900
Typo 4
で、branchコマンドでブランチを確認すると……。
$ git branch
* master
masterというブランチがある。これは最初にコミットした時点で作られるブランチ。次にまたコミットをするとmasterブランチはそれを追いかけていく。
ブランチの作成
branch [newbranch]で作成。
$ git branch checkpoint1
branchコマンドで確認ができる。アスタリスクがついているのブランチが今のブランチ。
$ git branch
checkpoint1
* master
ブランチの確認
基本はbranchコマンドで確認できる。
$ git branch
checkpoint1
* master
vオプションでCommitオブジェクトのSHA1とログなどを冗長に確認できる。今は全部同じだが……。
$ git branch -v
checkpoint1 5f431a8 Typo 4
* master 5f431a8 Typo 4
rオプションでリモートのブランチも確認できる。(まだよくわかってない)
$ git remote -v
rem1 c:/project/testRemote/remote1.git (fetch)
rem1 c:/project/testRemote/remote1.git (push)
rem2 c:\project\testRemote\remote2.git (fetch)
rem2 c:\project\testRemote\remote2.git (push)
$ git branch -rv
rem1/master 5f431a8 Typo 4
rem2/master 5f431a8 Typo 4
ブランチの削除
branch d [branch]、またはbranch D [branch]で削除する事ができる。
$ git branch -d checkpoint1
Deleted branch checkpoint1 (was 5f431a8).
$ git branch
* master
ちなみになうなブランチは削除できない。
$ git branch -d master
error: Cannot delete the branch 'master' which you are currently on.
dオプションとDオプションの違いは”今のブランチから到達不可能なブランチの削除を試みた場合”、警告を出す(d)か強制削除(D)か、らしい。どういうことだろう?
→parent,parentで過去へ遡及はできそうだけど、そこから未来には進めなさそう?
ブランチを切り替える
checkoutコマンドを使う。
$ git branch checkpoint1
$ git checkout checkpoint1
Switched to branch 'checkpoint1'
$ git branch
* checkpoint1
master
ブランチを作りつつcheckoutも同時に行う事もできるcheckout -b [newbranch] [branch]
$ git checkout -b check-b master
Switched to a new branch 'check-b'
$ git branch
* check-b
checkpoint1
master
ただし、作業ディレクトリにファイル作りっぱなしとかステージングしっぱなしの状態だと原則としてブランチの切り替えはできない。
$ git checkout master
error: Your local changes to the following files would be overwritten by checkout:
index.html
Please, commit your changes or stash them before you can switch branches.
Aborting
HEAD??
Git系のBlogエントリとか読んでるとちょいちょい出てくるHEAD。これは.gitディレクトリの中のHEADファイルに定義されていて、常に今作業中のブランチを指す、という事になっている。よく見たら前のエントリ]でgit reset HEAD [resetfileというコマンドをうっていた!
$ git branch
check-b
checkpoint1
* master
$ cat .git/HEAD
ref: refs/heads/master
masterの時はHEADもmasterだ。
$ git checkout checkpoint1
Switched to branch 'checkpoint1'
$ git branch
check-b
* checkpoint1
master
$ cat .git/HEAD
ref: refs/heads/checkpoint1
別のブランチに切り替えるとHEADも変わる。logコマンドでCommitオブジェクト(SHA1)の代わりにHEADを指定すると見れる!
$ git log --pretty=raw HEAD
commit 5f431a8cf6023e7398102dfef8b88baf1c581023
tree de445cf5b526c554dea465d09cea6d65059d1f80
parent a59ff99de68cbf359c814f25cda9c926ef9cdad9
author kk_Ataka <test@example.com> 1329818747 +0900
committer kk_Ataka <test@example.com> 1329819044 +0900
Typo 4
commit a59ff99de68cbf359c814f25cda9c926ef9cdad9
(略)
この辺は各々のブランチの歴史を進めた上で比較しないと全部同じだからわかりづらいな。次はマージから。