[Worked example]
上記ページのWorked exampleが分かりやすい。参照すべし。
[ローカルでの作業が容易]
サーバのリポジトリと通信できない環境でもローカルに履歴情報などがあるのでdiff等が取れる。
[patchがoutdatedになり難い]
マージする場合に履歴情報を使えるから。
[Each user has a full copy of the repository]
ローカルに履歴情報も含めたリポジトリ全体を保持する。
[There is no master repository]
ツールの仕組みとしては何処かのリポジトリをマスターとするようにはなっていない。
個々のリポジトリ同士で相互にリポジトリの差分を取ったり同期したりする事が出来る。メッシュ構造。
実際の運用では何処かのリポジトリがマスターとなって、そのリポジトリからpullしたりpushしたりする場合が多い。木構造。スター構造。
[DVCS repositories are much smaller, typically because they contain only a small number of highly-related projects]
ローカルに全部の情報を保持するので、基本的にはリポジトリは大きくなる。
ただ、CVCSと比較するとより関連の強い部分のみローカルに複製する事が多いので、実質小さくなる。
CVCSは新しいリポジトリを作るのにコストが掛かるので古いプロジェクトのリポジトリに新しいプロジェクトを追加するケースが多い。
DVCSは小プロジェクト毎にリポジトリを分けて作ることが多い。
マスターとして動作するための特別なプロトコルを話せるサーバを用意する必要がないので、新しい細かいリポジトリを起こしやすい。
[Changesets are identified by a hash of their contents]
リポジトリは空の状態から始まって、そこからのchangeset(patch, 差分)の連続として扱われている。
それぞれのchangesetは「直前のchangesetのhash値と変更内容」のsha1のhash値をIDとしている。
同じ変更を複数回行っても直前のchangesetへのポインタ(hash値)を含んでいるので区別出来る。
?? 違う変更内容のhash値が偶然同じ値になってしまった場合は??
[Git hashes can be shortened to any unique prefix]
hash値はIDとして使うには長いので、prefix 6桁を省略形として使う場合が多い。
小さいプロジェクトならもっと短い桁数、大きいプロジェクトならもっと長い桁数にしてもよい。
?? さらにhash値の衝突が発生しやすくならないか。
[The default 'trunk' is called 'master' in Git]
[The tip of the current branch is referred to as 'HEAD']
tipはそのbranchの先頭のversionの事。
branchはあるversion以前の変更すべてを含むchangesetで参照される。
[Creating, and switching between, branches is fast]
既に作成済のchangesetを参照するだけでbranchを作ったり切り替えたり出来る。
[Think of branches as throwaway changesets]
DVCSではbranchを沢山作成する運用になる。
何か試して捨ててしまうような変更はbranchを作成して試してみる。
[It's painful to merge in a CVCS; therefore branches tend not to happen]
[Merging in a DVCS like Git is trivial]
changesetにどこ更新をどこのversion(point,changeset)に対して行ったかが記録されているので、ツールが内容ではなくて履歴同士を合成する形でmerge出来る。
CVCSでは内容のみなので、履歴の情報がある分だけマージしやすくなる。
mergeとはあるlocal branchに別のlocal branchのchangesetをweavingして一つにする事。
mergeはworking directoryに対して行われるのではなくて直接repositoryに反映されるので注意!!
[Pulling and pushing in a DVCS like Git is trivial]
localのbranchとremoteのbranchの共通の祖先(ancestor)からtipまでのchangesetを送ったり(push)取得したり(pull)する。
どこが共通の祖先かはツールが知っているので気にしなくていい。
[Origin is the name of the default remote, but you can have many remotes per repository]
push/pullする先はremote nameとしてlocalのrepository毎に複数設定できる。
通常は最初にcloneしたremote nameがoriginとしてその対象になる。
他のremote nameを定義してそこを指定してpush/pullする事も出来る。
remoteはURLで指定する。
pullはremoteのbranchをlocalのbranchにmergeするという事。
['git init' creates a fresh repository in the current directory]
['git add' is used to add files and track changes to files]
['git commit' is used to commit tracked files]
gitにはindexという概念がある。
今commit対象になっているファイルの組。
addで追加できる。commitするとindexのファイルがcommitされる。
commitするたびにindexはclearされるので、再commitするためには再度addが必要。
['git branch' is used to create and list branches]
['git checkout' is used to switch branches]
['git checkout -b' is used to create and then switch branches]
checkoutは別のbranchのファイルを取り出すという事。
今後の作業対象のbranchも切り替わる。
今のbranchの作業内容はcommitしていないのとdiscardされるの注意!!
branchの作成はbranch pointのchangesetを指定してbranch nameをつける。
branch nameでtipを参照する。
[Rebasing replants your tree; but do it on local branches only]
git rebase [basebranch] [topicbranch]
topic branchにbase branchをmergeした場合と同じsnapshotになる。
異なるのはそこに至る履歴。
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、baseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
baseにtopicをfast-forward出来るようになる。
通常はmasterにpushする前に履歴を整理するために行う。
topic branchの履歴が変わってしまうため、changesetを他人に公開した後は行うべきではない。
git rebase --onto newbase [basebranch] [topicbranch]
topicとbaseの共通の祖先からtopicのtipまでのdiffを取る。
その後、newbaseのtipをcheckoutして、それにdiffを当てて、それをtopicのtipとする。
[補足]
[working directory]
repositoryからcheckoutされた作業対象。
[fast-forward]
git用語。tipの先に単にchangesetを追加するだけでmerge出来る場合のmergeの事。
[bare, non-bare]
履歴情報のみのbare repositoryと実際のworking directoryを持つnon-bare repositoryという概念がある。
詳しくはこちら。
git config --bool core.bare true もしくは false でbare属性を指定。
non-bare上でbareからpull、bareへpushすると言うのが普通の使い方。
?? gitにはfile lock機能がないので整合性を保つために必要らしい??
bareだとcheckout出来ない。non-bareへはpush出来ない。
[stage (index)]
staging: index に working copy の変更を登録する事。
git add: working copyをindexにstageする
git add -u: 変更を一括stageする
git add -p: 対話的に変更部分のstage/unstageを決められる。
git reset: Hirotryの内容をindexに取り出す。(unstage)
git checkout: indexの内容をworking copyに取り出す。
git commit: indexをHistoryに登録する。
git diff: working copyとindex差分
git diff --cached: indexとcommitの差分
http://marklodato.github.io/visual-git-guide/index-ja.html
図解されていて分かりやすい。
単純に任意のcommitからbranchを作成する場合。
git branch
何処からも参照されないcommitは破棄されてしまうのは注意が必要。
branchやtagを小まめに打つ必要がある??
?? tagやbranchが増えすぎで分かり難くならないか? 名前を考えるのも大変。
?? tagやbranchはいらなくなったら削除すべき?
[stash]
http://qiita.com/fukajun/items/41288806e4733cb9c342
working copy上に未commitのファイルがある状態でbranchを切り替えたい場合はgit stashを使う。
git stashすると未commitの修正がstash領域に一時退避される。
退避後にbranchをcheckoutしてstashをgit stash applyすれば退避していた修正がbranchのworking copyに乗る。
stashには修正が残ったままなので、git stash dropで小まめに消去する必要がある。
gitの基本としては、bransh作成、切り替えてからworking copyの変更を開始する。
[Reference, Book]
http://git-scm.com/doc
Gitをボトムアップから理解する
[その他]
GitのようなDVCSとCVS/SVNのようなCVCSはカラーテレビと白黒テレビの様な違いと例えられていた。
その便利さを知ってしまったらもう元には戻れないと言う意味で。
Egitでmerge toolを使うためにはローカルの変更ファイルをcommitしてからmergeする必要がある??
色々な人がWeb説明を書いているが、コマンドの詳細は意外と書いていない。
0 件のコメント:
コメントを投稿