基本的な開発スタイルはHgでもGitでもそう変わらないと思うので、考え方を完全に持ち込む、というかHgに慣れたんだけどみんなGitHubにいるからGitも使わざるを得ないとかそういう人(というか私)のための備忘録として。単にどのVCSがどう違うかは大体知っているんだけど、いざやってみようとするとコケまくる人たちのために。。。
ソースはgittutorial(7)。
結論からいうとこの表を書きたかった。
やりたいこと | mercurial | git | |
レポジトリ作成 | hg init | (みんなでさわる場合)git init --bare --shared | |
レポジトリクローン | hg clone |
git clone |
|
変更内容のコミット | hg ci | git commit -a *1 | |
変更状態 | hg diff | git diff | |
revert | hg revert -all . | git reset --hard | |
ブランチ作成 | hg branch |
git branch |
|
ブランチ一覧 | hg branches | git branch | |
ブランチ移動 | hg up -C |
git checkout |
|
マージ | hg merge |
git merge |
|
ブランチ削除 | なんかあった気がする | git branch -d |
|
向こうのと同期 | hg pull -u | git pull -a |
注意点…pull/pushはちょっと挙動そのものが違うようだ。
ホントはこの本をちゃんと読んだ方がよいのだが、今手元にないのでメモ。
- 作者: 濱野純(Junio C Hamano)
- 出版社/メーカー: 秀和システム
- 発売日: 2009/09/19
- メディア: 単行本
- 購入: 28人 クリック: 653回
- この商品を含むブログ (144件) を見る
ユーザ情報の登録
Hgだと~/.hgrcに
[ui]
username = UENISHI Kota
なんて書いたりしますが、gitでは
$ git config --global user.name "Your Name Comes Here" $ git config --global user.email you@yourdomain.example.com
とやります。~/.gitconfigに
[user] name = UENISHI Kota emacsl = kuenishi+github@spam.com email = kuenishi+github@spam.com
なんて書くのでもいいみたいです。よく分からないけど不思議ですね。
新規プロジェクトのインポート
これは同じなので簡単。git initでOK。
ファイル追加と差分の反映
Hgだと一旦addしたファイルは勝手に管理してもらえるけど、gitだと変更するために差分をaddで登録しないといけない。Hgと同じやり方でコミットしたい場合は
$ git commit -a
とやると hg ci と同じ意味になる。hg ci -Aとは意味が違うので注意。-mオプションは同じなのでエディタを見たくない場合は-mをつける。
ブランチ
ブランチ作成は同じ。ブランチ一覧はmercurialだと hg branches になるけど
$ git branch
で十分。ブランチ削除のときは git branch -d branchnameで、ブランチ間を移動するときは、hgだと hg up -C branchnameなんだけど、
$ git checkout branchname
でできる。checkoutとか言葉が混乱してややこしいですね。
clone/push/pull
mercurialと同じ、などと思ってはいけない。そんなあなたは考えが甘い。mercurialと同じだと思って clone して、コードを修正して、 commit して、変更内容をpushしたいと考えるだろう。そして、必ず次のような警告が表示されることだろう。
shuna:hoge kuenishi$ git commit
[master a425236] refactor
1 files changed, 0 insertions(+), 5 deletions(-)
shuna:hoge kuenishi$ git push
Counting objects: 5, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 294 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
Unpacking objects: 100% (3/3), done.
warning: updating the current branch
warning: Updating the currently checked out branch may cause confusion,
warning: as the index and work tree do not reflect changes that are in HEAD.
warning: As a result, you may see the changes you just pushed into it
warning: reverted when you run 'git diff' over there, and you may want
warning: to run 'git reset --hard' before starting to work to recover.
warning:
warning: You can set 'receive.denyCurrentBranch' configuration variable to
warning: 'refuse' in the remote repository to forbid pushing into its
warning: current branch.
warning: To allow pushing into the current branch, you can set it to 'ignore';
warning: but this is not recommended unless you arranged to update its work
warning: tree to match what you pushed in some other way.
warning:
warning: To squelch this message, you can set it to 'warn'.
warning:
warning: Note that the default will change in a future version of git
warning: to refuse updating the current branch unless you have the
warning: configuration variable set to either 'ignore' or 'warn'.
To /Users/kuenishi/Dropbox/dev/hoge
2038374..a425236 master -> master
shuna:hoge kuenishi$
インデックスとかwork treeとかがHEADにある変更を反映していないと。refuseとかwarnとかをグローバルに?設定するのはとても気持ち悪いので、もうちょっと調べてみた。
で、なんのこっちゃらと思ったら、push先がbareになっていないのが悪いらしい。
If you're creating a repo that people are going to want to push to, then you should create it using git init --bare (and git init --bare --shared if several user accounts need access to it), or git clone --bare if you're creating it by cloning an existing repo.
つまり、みんなでpushするレポジトリがあったら、そいつをbareなものにしておけば、bareなものに対するpushにはこの気持ち悪い警告は出ない。gitの方がmercurialよりも複雑だなぁという印象*3。
また、書き上げた後に気づいたのだけども、gitとmercurialでpush/pullの挙動が違うところがもう一箇所ある。mercurialではpush/pullをすると、レポジトリの状態を全て同期してくれる。つまり、片方のchangesetが他方に全て渡されるのだ。なので当然、全てのブランチが同期できる。しかしgitでは、push/pullの際には、明示的または暗黙に特定のブランチが指定されることになってしまうらしく、何も指定しなければmasterらしい。他のブランチは何も同期されない。タグがどうなるかはよく分からない。
これは理由を考えたら当然かもしれなくて、Linux Kernelのようにブランチが雲霞の如く世界中に生まれてしまった場合に、push/pullで全部changesetを取り込んでいては、レポジトリ内のchangesetの増大が大きすぎるのだろう(と勝手に想像している)。
まとめ
やりたいこと | mercurial | git | |
レポジトリ作成 | hg init | (みんなでさわる場合)git init --bare --shared | |
レポジトリクローン | hg clone |
git clone |
|
変更内容のコミット | hg ci | git commit -a *4 | |
変更状態 | hg diff | git diff | |
revert | hg revert -all . | git reset --hard | |
ブランチ作成 | hg branch |
git branch |
|
ブランチ一覧 | hg branches | git branch | |
ブランチ移動 | hg up -C |
git checkout |
|
マージ | hg merge |
git merge |
|
ブランチ削除 | なんかあった気がする | git branch -d |
|
向こうのと同期 | hg pull -u | git pull -a |
だいたいこんな感じかなぁ。あとは衝突状態の解決方法が残ってるか。。。間違いがあったらご指摘いただきたいです。
- 作者: 藤原克則
- 出版社/メーカー: 秀和システム
- 発売日: 2009/01
- メディア: 単行本
- 購入: 10人 クリック: 179回
- この商品を含むブログ (56件) を見る