by sscreations
git は使っているけれど、ただログを重ねるだけ。他人とコミットのやり取りはしたことがない。そんな孤高のプログラマに、git でチームと連携するためのコマンドをそっと教えましょう。
なお、説明を簡単にするため、github のように個々人がリポジトリを持つのではなく、中央リポジトリ origin にみんなで push/pull していくものとします。
branch
まずはブランチの確認から。-a
オプションで、リモートリポジトリにどんなブランチがあるか確認しましょう。
$ git branch -a * master remotes/origin/HEAD -> origin/master remotes/origin/maint remotes/origin/master remotes/origin/next remotes/origin/pu remotes/origin/todo
-v
ではリモートと比べた位置がでます。下の例では自分の master ブランチは [ahead 1]、コミット1つ進んでいることになります。
$ git branch -av * master b732fd6 [ahead 1] My commit remotes/origin/HEAD -> origin/master remotes/origin/maint 19534ee Update draft release notes to 1.8.2.1 remotes/origin/master 8d994db Update draft release notes to 1.8.3 remotes/origin/next ff26027 Merge branch 'master' into next remotes/origin/pu 203ba97 Merge branch 'mg/texinfo-5' into pu remotes/origin/todo 5f3c2ea What's cooking (2013/04 #01)
もうひとつつけて -vv
とすると、追跡しているブランチ名も出ます。
$ git branch -avv * master b732fd6 [origin/master: ahead 1] My commit remotes/origin/HEAD -> origin/master remotes/origin/maint 19534ee Update draft release notes to 1.8.2.1 remotes/origin/master 8d994db Update draft release notes to 1.8.3 remotes/origin/next ff26027 Merge branch 'master' into next remotes/origin/pu 203ba97 Merge branch 'mg/texinfo-5' into pu remotes/origin/todo 5f3c2ea What's cooking (2013/04 #01)
checkout
自分が作業すべきブランチがわかったら移動しましょう。使うのは checkout [ブランチ名]
です。
今回は todo ブランチの更新を任されました。
$ git checkout todo Branch todo set up to track remote branch todo from origin. Switched to a new branch 'todo' $ git status # On branch todo nothing to commit, working directory clean
リモートと同じブランチを作る場合 checkout
ひとつで以下の3つが完了します。
- ローカルにブランチ todo を作る
- origin/todo を追跡ブランチ(upstream)として設定する
- ブランチ todo へ移動する
あとはコミットを重ね、 push しましょう。追跡ブランチが設定されているので、ブランチ名を指定する必要はありません。
でもその前に、重要な設定があります。
config push.default
引数なしの git push ではすべてのブランチを push しようとします。つまり、他のブランチへの変更も問答無用で origin に送信されてしまいます。これを防ぐために push.default
を設定しましょう。
- matching すべてのブランチを push する。現時点でのデフォルト。
- upstream カレントブランチに追跡ブランチあれば push する。
- simple upstream と似ているが、リモートとブランチ名が同じ場合のみ push する。2.0以降ではデフォルトになる予定。
- current カレントブランチのみ push する。リモートになければ同名のブランチを作る。
ヘルプによれば、もっとも安全で初心者へおすすめなのは simple だそうです。もちろん、プロジェクトにルールがあればそれに従ってください。
ちなみにバージョン1.8以降で初めて引数なしの push を行うと警告が出るようになりました。
$ git push
warning: push.default is unset; its implicit value is changing in
Git 2.0 from 'matching' to 'simple'. To squelch this message
and maintain the current behavior after the default changes, use:
:
:
fetch
同僚が origin に送信した変更を見て欲しいと言っているけど、まだ pull できる状態ではない…。そんなときに更新情報だけを取得できるのが fetch
です。
$ git fetch
remote: Counting objects: 382, done.
remote: Compressing objects: 100% (170/170), done.
remote: Total 345 (delta 161), reused 322 (delta 144)
Receiving objects: 100% (345/345), 40.43 KiB | 27 KiB/s, done.
Resolving deltas: 100% (161/161), completed with 19 local objects.
From git://github.com/vim-ruby/vim-ruby
735b918..5943faa master -> origin/master
From git://github.com/vim-ruby/vim-ruby
* [new tag] stable-20130114 -> stable-20130114
$ git log --oneline ..origin/master
(コミットログ)
..origin/master
で、origin/master のコミットのうち、カレントブランチにない新しいものだけが出てきます。目当てのコミットが見つかったら、 git show [コミットハッシュ]
で中身を確認しましょう。
pull –rebase
push しようとしたら origin の方が進んでいてリジェクトされた。そんなときに呪文のように「pullしてpush」と唱える人がいますが、それでは人間関係がうまくいかなくなる可能性があります。
origin にコミット a と b 、ローカルに x と y があるとします。
git pull と git push では、実は origin に既にあったコミットを自分にマージして、それから送信します。そのため、結合点でマージコミットが発生します。
これでは自分が持っていたコミットの方が正統としているようなものです。origin へ push したのは a と b の方が先なのに…。しかも push がかち合うたびにログがマージコミットだらけになってしまいます。
そこで便利なのが git pull --rebase
です。これはマージではなく、a と b の後に自分の x と y が続くように流れを作り直します。この動作を rebase といいます。
origin が一本道になりました。
このオプションをデフォルトにするには2つの方法があります。
$ git config branch.develop.rebase true # 特定のブランチ (この場合は develop) のみに働く
$ git config --global branch.autosetuprebase always # 今後、branch または checkout で作ったブランチすべてに働く
rebase
新機能のために新しくブランチを作って開発をしていると、なかなか合流できずに派生元とどんどん差が広がってしまうことがあります。
あるいは、派生元のブランチから存在していたバグがあり、元のブランチでは修正されているから早く取り込みたいとき。
そんなときには rebase [ブランチ名]
しましょう。
$ git checkout feature-a $ git rebase develop
派生元ブランチから分岐する地点を、最新のコミットまで移動させます。「元のブランチにあるコミットの後に自分のコミットを続ける」というのが rebase
と覚えておきましょう。
まとめ
これでさみしくありませんね。でもコンフリクトが発生したら?テストに通らないコードを push する人が出てきたら?
第二弾「初めて部下を持ったチームリーダーが知りたい git 運用方法」。お楽しみに。