Skip to content
This repository has been archived by the owner on Jun 5, 2023. It is now read-only.

SubversionとGit

mollifier edited this page Jul 11, 2014 · 3 revisions

Subversionと違う点のまとめ

svnしか使えない老害なので違う点が難しい

  • 修正したファイルはすべてaddして明示的にコミット宣言する必要がある
    • Subversionは変更ファイルは問答無用でコミットされる
  • ブランチの概念が両者でかなり違う
    • Subversionのブランチは、バージョン番号と一致するレベルの大きい単位(個人単位でブランチを切ることはあまり無い)
    • Gitのブランチは、各自の数時間の作業レベルを意味する「ひとしごと」の単位(個人単位でブランチを切るのが普通)
      • しかしそうなるとブランチ名をどう決めればいいのかよく分からぬ、機械的にYYYYMMDDhhmms_(nickname)とかでいいんじゃないか
  • リポジトリへの反映が一手間増える
    • Subversionはsvn commit一発
    • Gitはまずcommitしてそれをpushする、という2アクションが必要。ただしその分、気軽にcommitできるという利点でもある(ようだ)

三宅コメント

addについて

addについては、svnは「作業コピー」と「リポジトリ」と2つ領域があるが、gitはその間にさらに「ステージング領域」というのがある。

  • 作業コピー
  • ステージング領域
  • リポジトリ

addは作業コピーからステージング領域に移動させるコマンド、commitはステージング領域からリポジトリに移動させるコマンドと考えれば良い。 addコマンドでコミットしたいものをステージング領域に集めて、commitコマンドでステージング領域にあるもの全部をコミットする、という感じ。 作業コピーの中からちゃんと選んで1つのコミットを意味のある単位にしろという意図のようだ。

ブランチ名について

ブランチ名は連番もあり。例えば先にIssueを作ってからそのIssueを解決するために修正作業をする、というような運用をやってる場合は feature/{Issue番号} みたいなブランチ名でもよい。 そのブランチで何やってるかはIssue見ればいいだろ、っていう発想。

ただし、Issueを作らずにブランチを切ってPull Requestって場合はこれは使えない(Issueがない状態でブランチを作らないといけないから)。 そういうときは add-newspage とか簡単な説明をブランチ名に入れることが多いようだ。

ブランチ名に日付を入れるのはあんまり見たことがないかな。たぶん、git logでいつコミットしたかが分かるからだと思う。

どっちにしろ、こういう小さいブランチは寿命が長くないし、詳細はコミットメッセージとかPull Requestのページを見れば分かるのでそんなに神経質になる必要はないと思う。 後から「あの作業やってたブランチってどれだったかな」ってときに分かればOK。

commitしてpush について

「commitしてpushという2アクションが必要」というのはちょっと認識が違うと思う。

まずgitは分散リポジトリと言うぐらいで、複数のリポジトリが存在することが前提になってる。 オープンソースのプロジェクトで、開発者が世界中にいるような様子をイメージすると良いと思う。 自分のローカルマシンにあるのも1つのリポジトリ、GitHubにあるのも1つのリポジトリ、同僚のマシンの中にあるのも1つのリポジトリ。 Gitはどのリポジトリも特別扱いしない。 GitHubにあるものがなんとなく共通のリポジトリっぽいが、それは運用ルールでみんながそう思ってるだけで、技術的にはGitHubのリポジトリも特別なものではない。

それで、commitというのは自分の今いるリポジトリに対して1つコミットを進めるコマンド。リモートのリポジトリに対して直接commitはできない。 そうやってcommitして自分のリポジトリが進んでいって、進んだ分を他のリポジトリに送るのがpushコマンド。 git push origin master というコマンドのoriginがpush先リポジトリを表してる。 普通にGitHubからリポジトリを作ったらoriginはGitHubのリポジトリを指してるので、このコマンドでGitHub上に修正を公開することになる。 それ以外にアクセスできるところにリポジトリがあったとしたら git push ssh://xxx@hostname/yyy/zzz master みたいなコマンドでそこにpushすることもできる。

逆に外部のリポジトリからの差分を取ってくるのがpullコマンド(というかfetchmergeコマンド)

svnの場合はリポジトリとしては全体で共通の1個しかないので、「みんなに見せるにはまだ早いけど、作業が失われるのが怖いのでとりあえずコミットしておきたい」というときに困る。 gitの場合はキリのいいところでとりあえずコミットして、間違ってたらローカルでコミットを捨てるとか、とりあえず実験用のブランチを作ってそこで作業して、うまくいけてると分かったら外部にpushする、とかできる。つまり、バージョン管理(commit)と公開(push)は別の操作になってる。

自分でローカルのリポジトリを1つ管理している、という認識が大事だと思う。 svnの場合は共通のリポジトリなので、ブランチ作成とかはプロジェクトのリーダー的な人一人がやることが多いと思う。 それに対してgitはそれぞれが1つリポジトリを持っているので、ブランチ作成とかは個人の判断で好きなようにやる。

いかにもLinuxカーネルの開発から生まれた、という感じの仕組みだと思う。