-
Notifications
You must be signed in to change notification settings - Fork 49
SubversionとGit
svnしか使えない老害なので違う点が難しい
- 修正したファイルはすべてaddして明示的にコミット宣言する必要がある
- Subversionは変更ファイルは問答無用でコミットされる
- ブランチの概念が両者でかなり違う
- Subversionのブランチは、バージョン番号と一致するレベルの大きい単位(個人単位でブランチを切ることはあまり無い)
- Gitのブランチは、各自の数時間の作業レベルを意味する「ひとしごと」の単位(個人単位でブランチを切るのが普通)
- しかしそうなるとブランチ名をどう決めればいいのかよく分からぬ、機械的にYYYYMMDDhhmms_(nickname)とかでいいんじゃないか
- リポジトリへの反映が一手間増える
- Subversionはsvn commit一発
- Gitはまずcommitしてそれをpushする、という2アクションが必要。ただしその分、気軽にcommitできるという利点でもある(ようだ)
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という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
コマンド(というかfetch
とmerge
コマンド)
svnの場合はリポジトリとしては全体で共通の1個しかないので、「みんなに見せるにはまだ早いけど、作業が失われるのが怖いのでとりあえずコミットしておきたい」というときに困る。 gitの場合はキリのいいところでとりあえずコミットして、間違ってたらローカルでコミットを捨てるとか、とりあえず実験用のブランチを作ってそこで作業して、うまくいけてると分かったら外部にpushする、とかできる。つまり、バージョン管理(commit)と公開(push)は別の操作になってる。
自分でローカルのリポジトリを1つ管理している、という認識が大事だと思う。 svnの場合は共通のリポジトリなので、ブランチ作成とかはプロジェクトのリーダー的な人一人がやることが多いと思う。 それに対してgitはそれぞれが1つリポジトリを持っているので、ブランチ作成とかは個人の判断で好きなようにやる。
いかにもLinuxカーネルの開発から生まれた、という感じの仕組みだと思う。