git使って結構立ってるんですがいまだに仕組みがややこしく結構難しいなあと感じています。
基本的な使い方は以前紹介した「gitの紹介と基本的な使用法について」でいいと思います。
開発をやっていますと一人でやることは当然稀で、対外は複数人での開発になります。
PHPとかだと直接サーバーにアクセスして開発することがメインですが、Javaの場合、ローカルで開発し、それをコミットなどしている場合は、コミットがずれてしまうことが一般的です。
そのときの解決策について書かせていただきます。
コミットのずれるとき
例えば山田さんと鈴木さんで開発をしているとしましょう。
※アルファベットはコミットです。
Step1 山田さんがAをコミット→プッシュ
Step2 鈴木さんがプル後、Bをコミット→プッシュ
Step3 山田さんはBをプル
Step4 鈴木さんはD、Eをコミット→プッシュ
Step5 山田さんはプルせずにCをコミット
図で書きますと以下のような状態です。
山田さん
A→B→C
鈴木さん
A→B→D→E
リモート
A→B→D→E
上記のような状態の場合、山田さんがプッシュしてもそれまでの履歴が一緒でないため、一気にはコミットできません。
どうするかというと山田さんのCのコミットとすでにリモートに上がっている鈴木さんのD,Eのコミットを合わせます。
これをmerge(マージ)といいます。
IDEなどを使っていればpush時に自動的にアラートが上がるかと思いますが、コマンドラインで行う場合は
git pull
もしくは
1 2 |
git fetch git merge FETCH_HEAD |
を行います。
fetchとpullの違い
fetchというのは一度ローカルにリモートの履歴を取り込みますが、いきなりはマージしません。
fetchをしても取り込むだけで確認した後にマージをします。逆にpullは一気にマージを行います。
fetchのほうが安全といえるでしょう。
競合の発生
上記のコミットはずれていたとしても全く別々のファイルを編集していた場合にはすんなり行きます。
難しいのは同じファイルを編集してしまったときです。上の例でいうと
山田さんのCコミットでfoo.txtを編集
鈴木さんのD、Eコミットでhoge.txt,foo.txtを編集してしまった場合です。
この場合、hoge.txtはすんなりマージできますがfoo.txtの場合は機械的にマージできません。
これを競合といい、競合が起こった場合、手で直し、再度add/commitする必要がでてきます。
今回の山田さんのこのコミットをFとし、プッシュすると
この場合、最終的なコミットは
山田さん
A→B→C→F
鈴木さん
A→B→D→E
リモート
A→B→D→E→F
↓→C→↑
になります。
鈴木さんはこの後、プルすればOKです。
もう1つの方法はrebase
もう一つは山田さんの履歴自体を鈴木さんの後にしてしまう方法です。
上記の例でいうと、
山田さんのコミットであるCを鈴木さんのコミットの後にしてしまいます。
イメージでいうとコミットを下記のような感じにします。
A→B→E→F→C
このように履歴自体を変更することを、rebaseといいます。
git pull --rebase
または
1 2 |
git fetch git rebase FETCH_HEAD |
で行います。
あとは実践あるのみ!
自分で行うと簡単なことじゃん・・って思ったんですけど今までこの類の説明を読んで理解できたことはありませんでした(汗)
プログラミング同様、説明を読むことと合わせてあとはひたすら繰り返して体で覚えることが大切になってきます。