Git 勉強会@万葉 #3 に行ってきた

最近勉強会レポートしか書いてないけど気にしない。
iwamatsu さんによるコンフリクト大会に参加してきました。

以下メモ晒し。

テーマ

あなたとコンフリクトしたい!

  • 分散リポジトリとコンフリクトとバージョン管理
  • チームを組んでコンフリクト大会
    • git pull / git rebase / git push

はじめのおやくそく

Git は「ぎっと」と読みます!!!

簡単なコンフリクトと修正

  • 各チームがそれぞれリポジトリを取ってきて、データを追加する
  • git commit
  • git checkout -b test
  • git pull #=> コンフリクト!
    • git fetch + git merge
    • ローカルブランチに pull 先の情報を上書きする
  • なぜコンフリクトしたのか?
    • 同じところにマージしようとしているから
  • コンフリクトを修正
  • git add FILE, git commit
  • git log で確認 #=> merge 分のログもはいっている。
    • 全員コミットログの順番が異なる。
    • コミットログは時間軸で表示される
    • git log --topo-order #=> コミット順で表示される
    • 次々と pull

やってみた結果・・・

  • 人によってファイルの内容が違う
    • 好き勝手に pull と編集をしたため
  • お互いに主導権を持って pull し合うと、バージョン管理できない!!
    • => 自分のものが常に最新になってしまう
    • 同じファイルにならなければ、「バージョン管理」ではない
  • 解決 (バージョン管理) するには?
    • どこかでまとめる
    • 管理者を決める

clone 先にまとめてみる

  • git push #=> reject!
    • push 先を誰かが更新していた
    • 間のコミットが抜けているため、整合性がとれない!
    • force オプションでコミットすると、間のコミットが消えてしまう・・・
  • force を効かないようにはできないの?
    • hook で「足りないオブジェクトがあったら push させない」ということはできる

push のエラーを修正しましょう

  • git remote update #=> リモートリポジトリのデータを取得する
    • git fetch と似てる
  • git rebase origin master
    • リモートの変更を元に、自分の変更を適用する
    • またコンフリクト!!
  • セクション別に修正する
  • git rebase --continue
    • 自分の変更を適用している最中にコンフリクトすると、 rebase が止まる
    • 自分のコミットを 1 つずつ適用しているから。
    • 再開するには --continue
    • 全部のパッチが適用されるまで、延々 git rebase --continue ...
    • rebase できた!
  • 相手の変更を尊重しましょう。
    • 自分の修正の内容はわかる。相手の修正に自分の修正を加える
    • git pull は自己中。複数のコミッタがいるならダメ絶対
    • git pull --rebase
    • git update remote & git rebase
      • merge: 自分が主体。自分のを元に相手の変更を適用する。
      • rebase: 相手が主体。相手のを元に自分の変更を適用する。
    • git merge した後に git rebase すると、 rebase した状態になる。

その他の方法

  • git pull してもらう
    • git request-pull
  • パッチで取り込んでもらう
    • git format-patch でパッチ作成、送信
    • 管理者が git am で適用

質疑応答

  • Q. マージは絶対ダメなの?
    • 運用にもよるが、立場によっては OK 。 master に近い立場 (取り込む側) はマージする。むしろ rebase しちゃダメ?
    • master を頂点とした階層構造の場合は、そういう感じのルールにしておくとよい。
  • Q. やっぱり大本のリポジトリは必要?
    • あった方が問題は少ない。
  • git cherry-pick pullするファイルを選択する
  • git clean #=> untrack なファイルを削除
  • git tag #=> 任意の blob, tree オブジェクトにリンクするタグを付けられる
  • 空ブランチ (git checkout '') とか


個人的には、Gitが分散であることの意味がすこし見えてきました。
各開発者がパッチを持ち寄って、マスターにがんがんと適用していくのを支援するため、
小回りの効くコマンド群で気持ちよく管理できる。
そんな意図が感じられます。


Subversionの機械くささも頼もしくていいですが、運用ルール次第で形を変えられる
Gitも融通が効いていいのではないでしょうか。


皆様おつかれさまでした!