Git memo

From Ecal

Jump to: navigation, search

注意:一般的なversion管理packageとかなり違う。

Contents

バージョン管理システムgitでなにができるか?

gitはある指定したディレクトリより下にあるファイルやディレクトリのを含むツリー構造 (以下、「作業ツリー」と呼ぶ)の変更履歴を管理していくシステムです。 たとえばecal/というディレクトリがあって、 その下にfp/, fp/test..., subs/, ...などがあるとします。gitでは、 ecal/.gitにすべてのecal下の「作業ツリー」 の変更履歴(スナップショット)が収納していけます(.gitをrepositoryとよぶ)。 この収納操作を「コミットする」といいます。

一番簡単なgitの使いかた

初期化などのあと、最低限、覚えるべきはgit-add git-rm git-status git-diff git-commit git-branchです。 そのあとmergeするのにgit-pull, git-pushなどかな。

1. ブランチはmaster一本槍でいく(git branchで*branchとなってることを確認)、git add, git rmなどで何をcommitするかを決め、それをgit statusで確認しときどきcommitする。(commitしたら何を格納するか?を書いたindex fileというものが.git内のどこかにありそれを、addやrmなどで修正していく。「git rm -f ファイル名」だと作業ツリーにあるものまできえてしまうので注意)。 この場合、「タイムマシン」としてつかえる。すなわち、git checkout ID -fで過去のcommit状態の作業ブランチを再現できる。 git branchとすると*no branchになっている。Untracked filesは変更を受けない.git checkout master -fで作業ツリーを完全に元に戻せる。

git commit --amendも頻繁につかうといい。

2. もし「ecal下に大きい計算データがありそれも含めてバックアップとりたいとき」は、 branch allをつくって、そのbranchではgit commit . でとる。 というようなこともできる。

イメージをつかむための簡単な説明

変更履歴は、時系列にそってrep0-rep1-rep2-rep3-...という感じで収納されている。 (すべて.gitに収納されてる)。どのタイミングで収納したのかは、 以下で説明するgit commitコマンドをいつ実行したかによる。

で、たとえば、いまrep3の状態にいるとします。 これはそのcommitコマンドをある時点で実行した直後の状態です。 このときには、ecal以下のファイルシステムはrep3と完全に整合しています。 すなわち「rep3="ecal以下のファイルシステム"」という状況になっています (正確にいえば意図的に除外したファイルをのぞいてです。 もっと正確にはむしろどのファイルをrep3に入れるかを指定します)。 いわばrep3は作業ツリーのある時刻でのスナップショットであり、commitは、 その時点でのスナップショットをとってgitに格納する命令です。

gitを利用すると、どの時点のスナップショットrep*にでも 簡単に作業ツリーを戻すことができます。 たとえばrep1にまで簡単に戻せます(そして、またrep3にすぐ戻れますーーーただこの 過去に戻る操作は、下のほうの太字の説明に対応してて分岐をつくっちゃう作業となってしまうので注意)。

また(実際には)、branchingをすることができて

rep0-rep1-rep2-rep3-rep4....
          |
         rep2_1-rep2_2-rep2_3...
                   |
                rep2_2_1-rep2_2_1...

というような形で、いろんなスナップショットが分岐しながら(.gitに)格納されてます。 系図のようなものですが、一個一個は「スナップショット」です。 gitでは主家筋はmaster (branch)と呼ばれます。主家筋の名前はmasterです(変えることもできる)。

master: rep0-rep1-rep2-rep3-rep4....

です。また、この図ではふたつの分家筋

branch1: rep0-rep1-rep2-rep2_1-rep2_2-rep2_3...
branch2: rep0-rep1-rep2-rep2_1-rep2_2-rep2_2_1-rep2_2_2...

があります。これらは仮りにbranch1,branch2などと呼んでますが、分家筋(でもrep0から履歴としては考えます)を発生させるときに名付けますーーー(branch1ならrep0-rep1-rep2の時点で発生させる。この時点では、masterとまったく同じコピーが名前branch1で生成される)。

で、こういう分岐ができたときには、分岐を行き来しながら作業できます。 (それに応じて、作業ツリーをその分岐でのrepに入れ替えれます)。

この一個一個のrep*に下に説明してある16進のIDがつきます。

また、さきほどの例ではecal/以下の全てのファイルをふくむ作業ツリーといいましたが、 それは正確ではなくその一部分を指定します(最初に指定します)。で、それを 「トラッキングされるファイル」とよびます。

それで、いったんcomitした後、作業ツリーにファイルが作られたり消されたり修正されたりするわけですが、 git statusすると「トラッキングしてたファイルのうちそれらが消されたか修正されたか移動されたか」 の情報を表示してくれます。そこで、それを見ながらどれらを次のcomitで格納するかを指定してから (git add {file},git rm {file}などを使います)、 git commitのコマンドであらたなスナップショットを.gitに格納します(git commit -aのオプションが便利です。

また、git diff HEAD (HEADは最先端のcommit ID (以下に説明あり)の略号です)で、その 更新部分の差分がgit commitする前に詳細に確認できます。

もっと具体的にどういうコマンドで操っていくかは以下の説明をみてください。 実際にはgit checkout(ファイルとりだし)に-fをつけないと 作業ツリーは変更されないようになってます。安全対策みたいですが、以下の木野氏 によると、余計に不便かもしれない(たえず-fをつけるようにするということでいいのかもしれない)。

で、こういうことをやってるとすくなくとも、各ブランチの先端のやつをいずれは マージさせるひつようがでてきます。がそういうこともうまくできるようです (まだ正確にはわかってません。小谷)。

また、git guiとすると、guiが立ち上がりますが、これとconsoleでのコントロールを併用すると 便利なようです.

考え方

  • 数字が増えていく形でのversion番号はないが16進のIDが付く。
version番号はreleaseするときに自分でつける。
  • 自分でつけるbranch名とその下でのIDで管理する。
最初のbranch名は必ず'master'
  • repositoryは.git/の中にある。
  • 新しい機能をつけるには作業用のbranchをつくりそこで試す。後でrelease用のbranchとmergeする。(作業用をそのまま使ってもいい。)
  • 同じdirectoryでbranchを切り替えることでファイルを取り換える。

以下{filenames}など{}で囲われている名前は自分が指定するファイルなどを示す。

使い方

whoami

[git config --global user.name "My Name"]

[git config --global user.email My.name@some.company]

directory毎やる必要はない。user毎に一度でいい。$HOME directory以下にできる。

init

[git init]

.git/ をつくる。作業pathの一番上で実行。 repositoryを取ってくるなら不要。

repositoryにいれる

( ( [git add .] or [git add {filenames}] ) and [git commit] ) or [git commit -a]

たとえば、[git add {filenames}]してから[git commit]ということ。

  • [git add .]はtop directory以下のすべてのファイル、subdirectoryを入れる。
  • 次に[git commit]するには再び[git add]する必要がある。前回のrepositoryからの更新なので、書き直したファイルだけでいい。
  • subdirectoryで[git commit],[git checkout]してもtop directory以下のファイル,directory全てに対して行われる。
  • 他人も読むので内容がわかるcommentを書くように。でないと自分もそのうちわからなくなる・・・。

次のcommitで何が起こるかの確認

[git status]

前回の[git commit]から更新されているファイル、次回の[git commit]でrepositoryに更新される予定のファイル、変更を無視するファイルを確認できる。

次のcommitでおこる変更の詳細

[git diff HEAD] これで、既存repository先端のものと


repositoryから消す

[git rm --cached {filenames}]

trackingの対象から外す。

[git rm {filenames}]

  • trackingの対象から外すだけでなく{filenames}の本体も消される。
  • 消されたファイルを復活するには[git checkout -f {commitID}]、[git checkout {commitID}]では消されたファイルは戻らない。

commitの歴史を確認

[git log]

branchを作る

[git branch {branch_name}]

branchを消す

[git branch {branch_name} -d]

自分が今いるbranchは消せない。

repository間を移動

[git checkout {name}]

作業中のcommitしておかなかった内容は消えてしまう。gitは変更をminimumにしようとして変更しなかったファイルなどのmessageを出すのでmessageを見てそれで正しいのか判断すること。[git checkout -f ]を使うと強制的に戻すので安全。
  • {name}=branch_nameの時
古いbranchへのcheckoutはbranch間の移動になる。まだcheckoutされていない新しいbranchへの移動は単にbranch名が変わり、はじめのrepository=元のrepositoryになる。
branchの最新のcommit_ID(=HEAD)へ移動する。
  • {name}=commit_IDの時
commit_IDは区別できる程度の数文字書けばいい。
異なるbranchのcommit_IDは見えない。

subdirectoryで[git commit],[git checkout]してもtop directory以下のファイル,directory全てに対して行われる。

同じbranchの昔のcommitへ戻る場合は別branchへの移動となる

checkoutで同じbranchの昔のcommitへ戻ると別branchへの強制移動となる。移動先のbranch名はnonameになる。([git branch]で確認。)この状態で[git log]しても現状以外の履歴が見れない。 元のbranchに戻る場合はでbranchを指定して戻る。

branch名をつくるには[git checkout {commit_ID} -b {new_branch_name}]とするか、そのあと新しいbranch名をつくってそのbranchへ移動してcheckoutする。

エラーがでて移動できない場合は'-f'をつける。[git checkout {name} -f]


clone:repositoryのコピー

[git clone {source} {target_directory}]

  • directoryを全部コピーするのでなく、repositoryにあるファイルだけコピーする。コピーされるのは{source}のbranchだけ。
  • {source}はssh:,http:なども使える。{target_directory}は省略するとcurrent directory
  • .git/以下だけコピーするなら[git clone --bare {source} {target_directory}]とする。.git/に--bareの内容を入れて[git checkout -f]とするとファイルを再構成できる。
e.g.,
[git clone . ~/proj/lm-7.0betaK001]
[git clone ssh://host_name/home/myname/kit/GW/lm-7.0betaK001.090330 new-source]
[git clone --bare . ~/proj/lm-7.0betaK002/.git]

merge:修正の統合

[git pull {source} {target}]

{source}はdirectory,ssh,httpなど。{target}はcommitID,branch名。
e.g.,
[git pull /home/myname/proj/lm-7.0betaK001 master]

tar

[git archive --format=tar --prefix={target_directory}/ HEAD | gzip >{filename}.tar.gz]

  • HEADは現在のbranch名の最新のcommitiDを指す。他のbranch名、commitIDを指定してもかまわない。
  • {target_directory}/の/は重要。
  • {filename}に自分でversion numberなどつける。

useful links

[Gitを使いこなすための20のコマンド] がうまくまとまっているので読むことをお勧めする。

github

proxy

proxyを使ってwebが見えるならば、corkscrewを使ってgithubも利用可能。

corkscrewはhttp proxyを使ってssh通信を行う。

設定方法

  1. install corkscrew [[1]]
  2. edit ./ssh/config
Host github.com
  User git
  Hostname ssh.github.com
  Port 443
  ProxyCommand corkscrew httpproxyname httpproxyport %h %p

httpproxyname httpproxyportはweb browserの設定と同じ。 つながるとsshのpassphraseを聞かれる。

push:upload

githubのIDをもらい説明に従いサンプルを実行してみる。

現在はwebで登録するとそのまま使える。

webからgithubの方でcreate repositoryをしてprojectを作る。すると説明が表示される。

reposityの取かた

[download]でtar.gzが取れる。repositoryを取るには

$ git clone git://github.com/nim-hrkn/ecal.git

とするとecal/ directoryにファイルできる。[git clone git://github.com/nim-hrkn/ecal.git ecal2]とdirectory指定も可能。

(以下、小谷) public keyの登録がまず必要だった。 また、直接取るのは、どうもうまくいかない。 いったん自分のCloneを作ってからそれをとらないとできない。 まだ慣れてないので。。。

proxyをとおすとpublicのものをとれないことがある

そのときはあきらめて外部サーバー経由でおこなうことができる。 たとえば、僕の場合、まずpmt.sakura.ne.jpにログインし/home/pmt/KOTANIに 移って、git clone git://github.com/nim-hrkn/ecal.git でそこへおとした。 でもそれだけでは、master branchしかとってこれない。 (remote-tracking branchという概念があり、話をややこしくしてる git branch -a (または-r))。 それで

git checkout --track -b expr_paramake_delstra origin/expr_paramake_delstra

を続けてうつと、expr_paramake_delstraというbranchが実際にできる。

そのあとローカルのマシンの上で git clone ssh://pmt@pmt.sakura.ne.jp/home/pmt/KOTANI/ecal/.git とすると、自分のローカルにおとすことができた。

とにかく面倒な点がある。

http://www.tempus.org/n-miyo/git-course-trans-ja/svn.ja.html

http://www8.atwiki.jp/git_jp/pub/Documentation.ja/user-manual.html

http://blog.s21g.com/articles/928

  • 試したコマンド(メモ)
git fetch ssh://pmt@pmt.sakura.ne.jp/home/pmt/KOTANI/ecal/.git
gitk HEAD..FETCH_HEAD
gitkが便利
gitk HEAD...FETCH_HEAD
git commit -a -m' test:meaningless modification to Makefile'
git config --global color.diff auto 
git config --global color.status auto
git config --global color.branch auto
Personal tools