Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Subversion to Git

monzou
December 22, 2012

Subversion to Git

社内勉強会で使用した資料から一部社外に公開出来ないものを取り除いたものです。
間違い等あるかもしれません。

monzou

December 22, 2012
Tweet

More Decks by monzou

Other Decks in Programming

Transcript

  1. Eclipse の Git プラグイン。 最近では Git の基本機能をほぼ利用出来るようになっている。 開発が活発。 EGit GitHub

    が提供している Windows 向けクライアント。 (特に GitHub に限定したツールではありません) Git の機能を「簡単に」使えるような UI を備えている。 Git の Shell も付属するため、EGit で出来ない操作はコチラを使う。 GitHub for Windows 以下のツールを使います。
  2. 最初に:某さんの疑問 どう生産性が上がるのか? → 履歴の参照や比較, マージが高速に動作するので待ち時間が減少する → ローカルリポジトリが使えるので作業単位が気軽に記録できる → 気軽にブランチが作成出来るのでリファクタリングの敷居が下がる どうプロジェクト運営が楽になるのか?

    → 楽になるというよりも運用方法が大きく変わると思います → チームによって運用方法は変わってくると思いますが, 一例をあとで紹介します どう品質向上に役立つのか? → コミット単位が整理され, 履歴がシンプルになる → チームで Pull Request を活用すれば, コードで会話出来る → GitHub を使えば意味のあるコードが共有出来るのでチーム全体のレベルアップに
  3. merge Local → Local に merge するなら Fast-Forward でも OK

    の Remote → Local に pull するときは rebase して履歴をシンプルに Local → Remote に push するときは rebase してから merge Remote → Remote に merge するときは Non Fast-Forward つかいかた の
  4. merge Local → Local に merge するなら Fast-Forward でも OK

    の Remote → Local に pull するときは rebase して履歴をシンプルに Local → Remote に push するときは rebase してから merge Remote → Remote に merge するときは Non Fast-Forward つかいかた の ※ トラッキング用のブランチを作るなら rebase する必要は無いですけどね。 ※ rebase は便利だけど落とし穴も・・・ 機能単位で commit を整理したいだけなら merge + squash だけで良いかもしれません。 色々な流派が あるので一概には 決められません
  5. $ touch sugoi.rb $ git checkout -b sugoi-feature スゴイ機能開発用のブランチをつくってチェックアウト $

    git add . スゴイ機能用のファイルをステージする $ git commit -m ‘とりあえずスゴイ機能のベースを追加 ’ スゴイ機能用のファイルを一旦ローカルリポジトリにコミット
  6. $ touch sugoi.rb $ vi sugoi.rb $ git checkout -b

    sugoi-feature スゴイ機能開発用のブランチをつくってチェックアウト $ git add . スゴイ機能用のファイルをステージする $ git commit -m ‘とりあえずスゴイ機能のベースを追加 ’ スゴイ機能用のファイルを一旦ローカルリポジトリにコミット
  7. $ touch sugoi.rb $ vi sugoi.rb $ git add -u

    $ git checkout -b sugoi-feature スゴイ機能開発用のブランチをつくってチェックアウト $ git add . スゴイ機能用のファイルをステージする $ git commit -m ‘とりあえずスゴイ機能のベースを追加 ’ スゴイ機能用のファイルを一旦ローカルリポジトリにコミット
  8. $ touch sugoi.rb $ vi sugoi.rb $ git add -u

    $ git checkout -b sugoi-feature スゴイ機能開発用のブランチをつくってチェックアウト $ git add . スゴイ機能用のファイルをステージする $ git commit -m ‘とりあえずスゴイ機能のベースを追加 ’ スゴイ機能用のファイルを一旦ローカルリポジトリにコミット $ git commit -m ‘added sugoi-feature’ 編集してから再コミット
  9. $ git fetch origin origin と同期して…… $ git checkout -b

    topic origin/master マージ用のブランチを作って……
  10. $ git fetch origin origin と同期して…… $ git checkout -b

    topic origin/master マージ用のブランチを作って…… $ git merge --squash sugoi-feature $ git commit -m ‘added sugoi-feature’ sugoi-feature を merge して……
  11. $ git fetch origin origin と同期して…… $ git checkout -b

    topic origin/master マージ用のブランチを作って…… $ git push origin topic push ! $ git merge --squash sugoi-feature $ git commit -m ‘added sugoi-feature’ sugoi-feature を merge して……
  12. $ git fetch origin origin と同期して…… $ git checkout -b

    topic origin/master マージ用のブランチを作って…… $ git push origin topic push ! ※ squash でマージする場合です。 運用次第ですがチームで開発するときはこれじゃ駄目だと思いマス…… きちんとルールを決めて運用しましょう。 $ git merge --squash sugoi-feature $ git commit -m ‘added sugoi-feature’ sugoi-feature を merge して……
  13. $ git fetch origin origin と同期して…… $ git checkout -b

    topic origin/master マージ用のブランチを作って…… $ git push origin topic push ! ※ squash でマージする場合です。 運用次第ですがチームで開発するときはこれじゃ駄目だと思いマス…… きちんとルールを決めて運用しましょう。 $ git merge --squash sugoi-feature $ git commit -m ‘added sugoi-feature’ sugoi-feature を merge して…… 普通は master で remote を tracking しつつ、 branch を master で rebase する人が多いと思いマス
  14. $ git add sugoi-spec.rb 漏れていたファイルをステージして…… $ git commit --amend 前回のコミットを訂正!

    やったね! ただし・・・既に公開している コミットを訂正してはいけません!
  15. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき
  16. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ……
  17. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して……
  18. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して…… $ git commit --amend 前回のコミットを訂正!
  19. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して…… $ git commit --amend 前回のコミットを訂正! ワークツリーはそのまま なので……
  20. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して…… $ git commit --amend 前回のコミットを訂正! ワークツリーはそのまま なので…… $ git add sugoi-spec.rb 手元の sugoi-spec.rb を再度ステージして
  21. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して…… $ git commit --amend 前回のコミットを訂正! ワークツリーはそのまま なので…… $ git add sugoi-spec.rb 手元の sugoi-spec.rb を再度ステージして $ git commit -m ‘added sugoi-spec’ コミット!
  22. $ git add . $ git commit -m ‘added sugoi-feature’

    例えば sugoi-feature.rb と sugoi-spec.rb がコミットされたとき spec は別のコミットに したいなぁ…… $ git reset HEAD^ sugoi-spec.rb インデックスの spec を HEAD のひとつ前の状態に戻して…… $ git commit --amend 前回のコミットを訂正! ワークツリーはそのまま なので…… $ git add sugoi-spec.rb 手元の sugoi-spec.rb を再度ステージして $ git commit -m ‘added sugoi-spec’ コミット! コミットが 分離出来たね!
  23. $ git checkout -b bug-1 bug-1 の修正中に・・・別のバグ修正を緊急で頼まれた! でも手元には 修正中のコードが ・・・

    $ git stash save こんなときは現在の作業状態を一時待避! $ git checkout -b bug-2 別のブランチで bug-2 の対応を開始
  24. $ git checkout -b bug-1 bug-1 の修正中に・・・別のバグ修正を緊急で頼まれた! でも手元には 修正中のコードが ・・・

    $ git stash save こんなときは現在の作業状態を一時待避! 緊急対応中・・・(少々お待ちください) $ git checkout -b bug-2 別のブランチで bug-2 の対応を開始
  25. $ git checkout -b bug-1 bug-1 の修正中に・・・別のバグ修正を緊急で頼まれた! でも手元には 修正中のコードが ・・・

    $ git stash save こんなときは現在の作業状態を一時待避! $ git checkout bug-1 元のブランチに戻って・・・ 緊急対応中・・・(少々お待ちください) $ git checkout -b bug-2 別のブランチで bug-2 の対応を開始
  26. $ git checkout -b bug-1 bug-1 の修正中に・・・別のバグ修正を緊急で頼まれた! でも手元には 修正中のコードが ・・・

    $ git stash save こんなときは現在の作業状態を一時待避! $ git checkout bug-1 元のブランチに戻って・・・ $ git stash pop 一時待避していた作業内容を復帰させて bug-1 の対応を続行! 緊急対応中・・・(少々お待ちください) $ git checkout -b bug-2 別のブランチで bug-2 の対応を開始
  27. $ git checkout -b bug-1 bug-1 の修正中に・・・別のバグ修正を緊急で頼まれた! でも手元には 修正中のコードが ・・・

    $ git stash save こんなときは現在の作業状態を一時待避! $ git checkout bug-1 元のブランチに戻って・・・ $ git stash pop 一時待避していた作業内容を復帰させて bug-1 の対応を続行! 緊急対応中・・・(少々お待ちください) 並行作業が しやすいね $ git checkout -b bug-2 別のブランチで bug-2 の対応を開始
  28. ココまでまとめるとこんな感じ Subversion Git コードの共有 中央リポジトリを介する リポジトリ間で自由 履歴の参照 遅い 速い コミット先

    中央リポジトリ ローカルリポジトリ コミットの整理 不可 可 コミットの公開 commit = 公開 push して初めて公開 ブランチの作成 リモートで作成するしかない ローカルで幾つでも作れる マージ 遅い 速い 作業内容の待避 不可 可 ファイルのロック 可 不可 操作 単純 複雑
  29. ココまでまとめるとこんな感じ Subversion Git コードの共有 中央リポジトリを介する リポジトリ間で自由 履歴の参照 遅い 速い コミット先

    中央リポジトリ ローカルリポジトリ コミットの整理 不可 可 コミットの公開 commit = 公開 push して初めて公開 ブランチの作成 リモートで作成するしかない ローカルで幾つでも作れる マージ 遅い 速い 作業内容の待避 不可 可 ファイルのロック 可 不可 操作 単純 複雑 ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
  30. GitHub の代表的な機能 ② ・ダッシュボード  ・News Feed  ・Notifications  ・etc, etc ...

    ・ユーザーページ  ・Activities  ・Repositories  ・etc, etc ... ・その他  ・Gist, GItHub Pages etc ...
  31. GitHub Stash リポジトリブラウザ ˕ ◦ Issue ◦ ˕ (JIRA と連携)

    Wiki ◦ ◦ 可視化 ˕ (Watch, Star, Network, Graphs) △ Fork ◦ ◦ Pull Request ◦ ◦ News Feed ◦ ◦ Notifications ˕ ◦ ユーザーページ ˕ ◦ スニペットの共有 ˕(Gist) × ホスティング ˕(GitHub Pages) × 参照権限の管理 ? ◦ API ˕ ◦ 色々と細かいところのユーザビリティも含めると 全体的に GItHub の方が常に進んでいるのは否めない・・・
  32. GitHub Stash リポジトリブラウザ ˕ ◦ Issue ◦ ˕ (JIRA と連携)

    Wiki ◦ ◦ 可視化 ˕ (Watch, Star, Network, Graphs) △ Fork ◦ ◦ Pull Request ◦ ◦ News Feed ◦ ◦ Notifications ˕ ◦ ユーザーページ ˕ ◦ スニペットの共有 ˕(Gist) × ホスティング ˕(GitHub Pages) × 参照権限の管理 ? ◦ API ˕ ◦ 色々と細かいところのユーザビリティも含めると 全体的に GItHub の方が常に進んでいるのは否めない・・・ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓
  33. GitHub Stash リポジトリブラウザ ˕ ◦ Issue ◦ ˕ (JIRA と連携)

    Wiki ◦ ◦ 可視化 ˕ (Watch, Star, Network, Graphs) △ Fork ◦ ◦ Pull Request ◦ ◦ News Feed ◦ ◦ Notifications ˕ ◦ ユーザーページ ˕ ◦ スニペットの共有 ˕(Gist) × ホスティング ˕(GitHub Pages) × 参照権限の管理 ? ◦ API ˕ ◦ 色々と細かいところのユーザビリティも含めると 全体的に GItHub の方が常に進んでいるのは否めない・・・ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ✓ ͱ͸͍͑4UBTIͰ΋ ࠷௿ݶඞཁͳػೳ͸ଗͬͯ·͢
  34. 基本は A successful git branching model を踏襲 ・中央リポジトリの master はマージ専用

    ・中央リポジトリの develop で開発 ・各開発者が中央リポジトリの develop を fork して開発 ・fork → upstream(中央リポジトリ)に Pull Request ・担当者が Pull Request をレビューして Non Fast-Forward でマージ ・リリースしたら master に Non Fast-Forward でマージ
  35. fork ベースでの開発フロー company/product master develop monzou/product topic upstream として参照 自分の

    fork から 本体の develop に Pull Request monzou/product:develop は company/product:develop と同期し, topic は develop で rebase してから push する
  36. #1. Stash / GitHub で company/product を fork #2. fork

    したリポジトリをローカルに clone $ git clone git://company.com/company/product.git 開発者の作業フロー ①
  37. #1. Stash / GitHub で company/product を fork #2. fork

    したリポジトリをローカルに clone $ git clone git://company.com/company/product.git 開発者の作業フロー ① #3. 開発用のトピックブランチを作成 $ git checkout -b topic develop
  38. #1. Stash / GitHub で company/product を fork #2. fork

    したリポジトリをローカルに clone $ git clone git://company.com/company/product.git 開発者の作業フロー ① #3. 開発用のトピックブランチを作成 $ git checkout -b topic develop #4. トピックブランチで開発・テスト $ git add . $ git commit -m ‘added topic’
  39. 開発者の作業フロー ② #5. fork したリポジトリの develop を fork 元リポジトリと同期 $

    git checkout develop $ git pull upstream develop $ git push origin develop
  40. #6. トピックブランチを develop で rebase $ git checkout topic $

    git rebase develop 開発者の作業フロー ② #5. fork したリポジトリの develop を fork 元リポジトリと同期 $ git checkout develop $ git pull upstream develop $ git push origin develop
  41. #6. トピックブランチを develop で rebase $ git checkout topic $

    git rebase develop 開発者の作業フロー ② #7. コミットを整理する(必要であれば) $ git rebase -i #5. fork したリポジトリの develop を fork 元リポジトリと同期 $ git checkout develop $ git pull upstream develop $ git push origin develop
  42. #6. トピックブランチを develop で rebase $ git checkout topic $

    git rebase develop 開発者の作業フロー ② #7. コミットを整理する(必要であれば) $ git rebase -i #8. トピックブランチをリモートに push する $ git push origin topic #5. fork したリポジトリの develop を fork 元リポジトリと同期 $ git checkout develop $ git pull upstream develop $ git push origin develop
  43. 開発者の作業フロー ③ #9. Stash で Pull Request を送る monzou/product:topic →

    company/product:develop に Pull Request #9b. Pull Request が却下されたら修正して再 push #9c. Pull Request が放置されていたら mention を書いてコメント @leader この Pull Request を確認してください
  44. 開発者の作業フロー ③ #9. Stash で Pull Request を送る monzou/product:topic →

    company/product:develop に Pull Request #9b. Pull Request が却下されたら修正して再 push #9c. Pull Request が放置されていたら mention を書いてコメント @leader この Pull Request を確認してください Stash も GitHub も コメント欄で @mention を 飛ばすことが出来るよ
  45. 開発者が Pull Request を送ったら・・・ #1. レビュー担当者が Pull Request マージして内容を確認 $

    git remote add monzou git://company.com/monzou/product.git $ git fetch monzou $ git checkout develop $ git merge --no-ff monzou/topic -m ‘Merged in topic (pull request #1)’
  46. 開発者が Pull Request を送ったら・・・ #1. レビュー担当者が Pull Request マージして内容を確認 $

    git remote add monzou git://company.com/monzou/product.git $ git fetch monzou $ git checkout develop $ git merge --no-ff monzou/topic -m ‘Merged in topic (pull request #1)’ #2. レビュー担当者がリモートにマージ結果を push $ git push origin develop
  47. 開発者が Pull Request を送ったら・・・ #1. レビュー担当者が Pull Request マージして内容を確認 $

    git remote add monzou git://company.com/monzou/product.git $ git fetch monzou $ git checkout develop $ git merge --no-ff monzou/topic -m ‘Merged in topic (pull request #1)’ #2. レビュー担当者がリモートにマージ結果を push $ git push origin develop #3. Jenkins がマージされた develop ブランチをビルド
  48. 予想される問題 レビュー待ちの Pull Request が滞留する ・Pull Request が滞留するとコンフリクトがどんどん増える ・レビュー担当者を分散する ・mention

    を有効活用して早めに担当者に通知する ・細かい修正は最悪 Pull Request せずに直接開発者がマージしてしまう
  49. 予想される問題 レビュー待ちの Pull Request が滞留する ・Pull Request が滞留するとコンフリクトがどんどん増える ・レビュー担当者を分散する ・mention

    を有効活用して早めに担当者に通知する ・細かい修正は最悪 Pull Request せずに直接開発者がマージしてしまう Pull Request 送信時に検出されない不具合が増える ・Pull Request 送信時のブランチを事前にビルドしないと分からない ・でも Pull Request 毎に Jenkins にビルドさせるのは難しい・・・ ・こまめに対応するしかない
  50. まとめ ローカルリポジトリ → 個人の生産性向上 Stash + Pull Request→ チームの生産性・品質向上 Stash

    で「ヒト」にフォーカス → エンジニアの交流活性化 Stash でコード共有の活性化 → 開発効率の向上