入門Git (Chapter5〜6)

Chapter 5 2か所で使う

% mkdir -p /path/to/repository/project.git
cd /path/to/repository/project.git
git init --bare
% cd /path/to/project
% git push /path/to/repository/project.git master
 → project.git に master をコピーします。
  • コピーが作られたかどうか確かめます。
% git clone /path/to/repository/project.git
    • 上記で作られたリポジトリでlogなどが残っていることを確認します。
親となるリポジトリ
  • これにより、今後は/path/to/repository/project.gitを親にして、そこからcloneすることによってそれぞれがプロジェクトを進めていくことが出来ます。
  • 今まではコミットして終わりでしたが、今後はコミットした後に親のリポジトリにpushする作業が必要になります。それを行ってくれるのが「git push」コマンドです。
  • 「git push」は「git push <プッシュ先リポジトリ> <プッシュするブランチ>」として実行するのですが、「git push」と省略して書くと、デフォルトでは「git push origin master」と実行したと同じ結果になり、originリポジトリにmasterブランチをプッシュするということになります。originとmasterについては、後で説明がありますが、ここではoriginは/path/to/repository/project.git、masterはcloneして作ったリポジトリにあるブランチになります。なので「git push」をすることで、親となるリポジトリにcloneしてきたリポジトリのブランチを反映することが可能になります。
  • これによって、親となるリポジトリがあって手元にはそれを複製したリポジトリがある状態になりました。親となるリポジトリに接続することが出来ない状況でも、手元にあるブランチにコミットしたり出来るのでバージョン管理を行いながら作業を進めることが出来るようになりました。手元で重ねた変更は後で親となるリポジトリに反映すればいいんですね。
  • ようやく分散型らしくなってきました。
並行開発
  • 今度は旅行先で作業がしたいということで、本では別のマシンで作業をしていましたが、用意するのも面倒なのでここでは、新たにgit cloneしてそれを使って並行開発したいと思います。
% git clone /path/to/repository/project.git project2
  → project2という名前でリポジトリをcloneします
  • これで、projectとproject2それぞれにリポジトリを作成したので、それぞれでコミットしてpushしてみます。すると二個目のディレクトリで下記のようなエラーが出ます。
% git push
To /path/to/repository/project.git
 ! [rejected]        master -> master (non-fast-forward)
error: failed to push some refs to '/path/to/repository/project.git'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.
  • それぞれで別々にコミットしているので変更をマージして再度pushしてやる必要があります。
% git pull
〜変更を手動でマージする〜
% git commit 〜
% git push
  • 今度はうまくいくと思います。
  • このように衝突が発生した場合は、「git pull」して親リポジトリから最新の状態を取得し、マージして再度コミットしてpushする必要があります。
タグを付ける
  • リリースなどの際に特別な区切りとして、タグを付けておくことが出来ます。
% git tag -a タグの名前
 →エディタが立ち上がるのでログを書きます。
% git tag -l -n
 →付けたタグの一覧が表示されます。(-nでコメントも出力)
  • 「git describe」
    • 指定されたコミットから一番近いタグを見つけそこから何番目のコミットかどうかを返します。使いどころがいまいちわからず。。
    • testタグを付けてコミットした後に実行した場合。
% git describe
test-1-g3ab506b
→testタグから1番目のコミットを指しています。
 このままコミットの名前として使うことも出来ます。
コミットを名前で呼ぶ
  • この辺りは理解しておかないと詰まってしまう部分だと思います。
    • HEAD
      • 現在チェックアウトしてあるコミット。(自分の手元にある最新のコミットみたいな感じでしょうか)
    • ブランチ名(masterなど)
      • 指定されたブランチの最新コミット。
    • 16進表記(53a45b8cなど)
      • 指定された16進表記から始まるコミットオブジェクト。
  • その他祖先の指定
    • 「^」(HEAD^)
      • 前のコミット。(HEAD^^)2つ前のコミット
    • 「~」(HEAD~)
      • n世代前のコミット?
      • こちらは数字で指定できます。HEAD~2

Chapter 6 グループで使う

  • かなり短い章ですが、グループで使う場合の注意点などが書かれた章になっています。
大まかな流れ
  • git cloneしてプロジェクトを取得します。
  • git pushして変更を送信、またはgit pullして他の人がした変更を自分の作業リポジトリに反映します。
準備
  • 複数人で同じリポジトリを使う場合には、やはりパーミッションが問題になります。
  • ここではその対策として下記の方法が紹介されています。
    • ユーザーを同じグループに所属させます。
    • ユーザーのumask値を「002」か「007」 にします。
    • リポジトリを「project.git」のように作成し、cdします。
    • 「git init --bare --shared」のようにリポジトリを作ります。
高度なグループ開発
  • Peer-to-Peerスタイル
    • みんなで共用するリポジトリの他に個人もそれぞれ公開リポジトリを持ちます。
    • これにより、共有するリポジトリにpushすることなく、個人用の公開リポジトリで他の人に確認を行ってもらうことが出来るようになります。
    • 共有リポジトリにpushすることが出来ない実験的な変更などを試して記録しておくことが出来ます。
    • 確かに、共有リポジトリの他に個人用のリポジトリを持つっていうのは気軽に色んなことを試せそうでいいなぁと思いました。(リポジトリを管理するためのコストは掛かってしまいますが。)
  • 階層的な共用リポジトリ
    • ここでは、マスタとなるリポジトリへpush出来る人は制限され、その他のユーザーはマスタ以外の共用リポジトリで作業を行いpushします。その後、共用リポジトリに記録されている変更をマスタにpush出来る権限を持っている人が確認し、問題なければそこからpullしてマスタにpushする流れになります。
    • チームがフラットではない場合に必要になる構成ですね。
まとめ
  • 今回は主に複数人(マシン)で使うための説明でした。pushとかpullとかはよくわからないまま行っていると、共用リポジトリを壊してしまう必要があるので、本に載っていること以外も勉強しておく必要があるかと思います。(自分もよくわかってない。。。)
  • そのあたりがもう少し詳しく書いてあると嬉しかったなぁと思います。
  • 次は、ブランチを使った開発になります。実際の開発でも必須だと思うのでしっかり理解したいです。Subversionでは全然うまく使えてなかったなぁ。。