Git勉強会

2008年10月4日 14:00 - 17:00 キャンパスイノベーションセンター東京 609号室
Gitメンテナ Junio C Hamano氏を迎えてのGit勉強会


オープンソースカンファレンス2008 Tokyo/Fall 勉強会大集合の裏番組。
なお、Gitはギットと読む。


コマンドの説明や、Gitの操作デモ、データの構造とかの話があったけど、
そのあたりは他を見てもらうとして、ここでは私の心に響いたシーンを。


Gitのコマンドがいっぱいある

  • Gitのコマンドは120くらいあるよ。
  • 実際に使うのは20くらいだよ。
  • あるコマンドを実現するのに必要なコマンドを実装して、それらを組み合わせて機能を実現しているから、コマンドが多くなっているよ。

データ構造

  • 変更データは、過去の履歴データへのリンクを持っている。

個人で使う場合の、典型的なワークフロー

1. レポジトリからファイルを持ってくる。コマンド中のmy-gitは出力先。

git clone ssh://taku-o@taku-o.net/var/git/xxx my-git

2. commit時に、更新対象ファイルに含めたいファイルをgit addで追加する。

cd my-git
edit README
git add README

3. git add-pをつけると、変更したファイルのうち、次の更新に含めたいファイルをプロンプトで選択できる。
yが変更ファイルに加える。
nが変更ファイルに加えない。

edit README
git add -p


4. どれくらい変更されているか確認する

git diff

5. 次の変更に入れると宣言したもの(addしたもの)とのdiffを表示する

git diff --cached

6. 変更宣言したファイルをローカルのレポジトリに登録する

git commit .

ローカルのレポジトリにコミットできる

Gitだとローカルのレポジトリで完璧な状態になるまで作業してから、セントラルなレポジトリにチェックインできる。
だから、一見、ミスを全くしない完璧人間のように振る舞える。
ローカルのレポジトリにコミットして保存できるから、万が一の時も少し安心。

色つきdiff

カラフルなdiffを表示。

git diff --color-words

git stash

git stashを使うと、作業中の状態を一時的に逃がせる。
この機能は「ボスが来た。今進めてる作業より、こっち先にやれ。」って時に役に立つ。


1. 一時的に逃がす。逃がした上で、クリーンな状態を作り出す。

git stash

2. 先ほど逃がした作業状況を再現する。逃がしている最中に発生した編集も取り込みます。

git stash apply

3. 次の変更に入れると宣言したもの(addしたファイル)だけ元に戻す。他の変更は捨てる。
git stash applyで、捨てたものもリカバリできる。

git stash save --keep-index

git rebase

歴史を捏造して、他人には、美しい歴史だけを見せる。醜い歴史は見せない。
CVSSubversionではできない。


例えば、次のように実行すると、エディタに4つの履歴が表示されるから、それを書き換える。

git rebase -i HEAD~4
pick 5836283932 B
pick 58afa83932 C
pick 58afaxeee1 D
pick 4489axeee1 Typofix

↓ 例えば、こんなふうに書き換えてしまうと、履歴が変更される。

pick 5836283932 B
squash 4489axeee1 Typofix
pick 58afa83932 C
pick 4489axeee1

複数人で使う場合のGitワークフロー(その1)

中心となるレポジトリを決めて、そこで一括管理する方法。

1. ファイルを中央のレポジトリから取得

git clone ssh://taku-o@taku-o.net/var/git/xxx my-git

2. 変更したり、コミットしたり、テストしたりでファイルを編集する。
3. git pullで中央レポジトリから、更新を取得。

git pull

4. git pullの後、セントラルの更新分と、ローカルの更新分をマージして、git pushで中央レポジトリに更新を登録。

git push

複数人で使う場合のGitワークフロー(その2)

責任者を何人か用意して、その人に、更新分を取込んでもらい、
確認後、セントラルレポジトリにgit pushしてもらう。

1. 途中までの作業ワークフローは何も変わらない。
2. 編集終了後、どこかの公開レポジトリにgit pushするか、責任者にgit pullしてもらう。
ワンクッション置くことで、アップされるコードに対して、チェックを入れられる。

gitk

履歴を表示できるGUI
なお、履歴つなぐ線の色に深い意味は無い。

git bisect

デバッグ用。問題追跡用。
あるバグがある場合に、作業の履歴を確認し、中央の履歴を特定する。
そこで既に問題が入り込んでいたら、それより前の履歴を、
まだ問題が入り込む前だったら、それよりの後の履歴を見る。

真ん中でどうなっているか、次にそこと端との真ん中はどうなっているか、
と順々に見ていくと、最も早く問題の発生した箇所を特定できる。
そんな話。

git bisect run

テストケースが作成されている場合は、
git bisect runで簡単に問題の発生した箇所を特定できる。

git bisect run ./runscript

git blame

コードのそれぞれの行が、誰が、いつ作業したものかであるかを、表示する。
git blameは、ファイル名を変更しても追跡できる。

git blame test.txt

gitのレポジトリは、どの接続プロトコルを選ぶべきか

データ転送の無駄が無いとかの理由で、gitプロトコル推奨。
(私は気にせず、ssh使うけど。)




プロジェクトを管理する側からGitを見ると、

  • ソースが失われた時のために、バージョン管理システムにソースをこまめにチェックインしてほしい。
  • しかし、不完全なソースをチェックインされると他の人が迷惑するので、完全な状態にしてから、ソースをチェックインしてほしい。

という困った状態がCVSSubversionにはあったが、
このGitではローカルのレポジトリでチェックインできて、万が一の時に引き出せるし、
完成してからセントラルのレポジトリに放り込めるので、ソース管理上、とても助かるツールである。


しかし、コードが完成してから、まとめてセントラルレポジトリにチェックインするので、
これまでより、規模の大きなコンフリクトが発生しやすくなりはするだろう。
プロジェクトのメンバーが何人か居たとして、その全てのメンバーがマージ処理をきちんと行えるとは、あまり思えない。
(結局上手いことやるしかないけどさ。)




結構、Git気に入ってしまったんだが、
私がプロジェクトにGitを導入するなら、もう少し良いGUIツールが必要かなぁ。
でも、まだ、Gitはできてから、あまり時間経ってないしね。
その辺はすぐ、なんとかなりそうな気がするよ。