skillup

技術ブログ

Git

gitのfetch/merge/rebaseについて

投稿日:

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
もしくは
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
または
git fetch
git rebase FETCH_HEAD
で行います。

あとは実践あるのみ!

自分で行うと簡単なことじゃん・・って思ったんですけど今までこの類の説明を読んで理解できたことはありませんでした(汗)

プログラミング同様、説明を読むことと合わせてあとはひたすら繰り返して体で覚えることが大切になってきます。

-Git
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

gitの紹介と基本的な使用法について

Contents1 旧来のソース管理方法2 バージョン管理ツール2.1 バージョン管理とは?2.2 有名なバージョン管理ソフト3 Gitの基本的な使用法3.1 初期化(git init)3.2 基本的 …

no image

Gitで統合 merge関連

本日はずっとブランチ間の統合を行っておりました。 たとえばhogeブランチとfooブランチの統合をする場合、差分を最初に確認すると思いますが、 [crayon-5ba62359488194497236 …

no image

Gitでのbranch 新ブランチの作成&リモート反映&別環境反映

gitを使っているとわけのわからないことは多いのですが(爆)、その中の1つがbranch(ブランチ)でしょう。 これも説明をきいてもわからないのですが、自分でそのケースを学習してみればすぐにわかると思 …

no image

Gitのブランチについて

ちょっといろいろと触っているGitに関して。 前回は作業ディレクトリ、インデックス、コミットについて説明したのですが、今回はブランチについて行います。 Contents1 ブランチとは?2 ブランチに …

no image

追跡ブランチからローカルブランチを作る方法~ (svn→gitの移行など)

SVNで運用されていたプロジェクトをgitに移行する機会があったのでその時のメモなどを。 思ってたよりは楽だったかな・・・ Contents1 準備2 実際の移行(git svn clone)3 gi …