Non-Fast-Forward Push の解決
他の開発者とともに同じリモートリポジトリ (depot リポジトリ) を利用していれば、しばしば発生するのが Non-Fast-Forward Push 問題です。
Non-Fast-Forward とは何かということを説明するために、そもそも Fast-Forward とは何かということを説明します。
Fast Forward とは?
ある時点で master ブランチからブランチ A ができたとします。その後、ブランチ A にてコミットします。
その間、master ブランチでは全くコミットが行われていないとします。
この状態ではブランチ A はブランチ master に安全にマージ可能ですよね。ブランチ A に対して行ったコミットを master にも行えば良いだけですから。
ただ、実際に Fast Forward マージは同じ変更をせっせと再生するのではなく、単に master ブランチをブランチ A と同じコミットをポイントするように変更するだけです。
これが Fast Forward マージです。
Non Fast Forward とは?
Non Fast Forward というのは、Fast Forward と違う、ということなのですが・・・ (笑)
ブランチ A を作ってそこでコミットを行う、そして同時に master ブランチでもコミットを行った場合です。このときは明らかに master のポインタを差し替えるだけではマージ作業は解決できません。
ブランチ A の内容と master の内容を活かしつつ、それらをマージして新たな合流地点を作る、そうした作業が Non Fast Forward のマージです。
もちろん、どちらかの変更を完全に破棄してしまうことも可能ですし、そこをどのように処理するかはあなた次第です。
Non Fast Forward Push を解決する典型的な手順
リモートリポジトリに push を試みたとき、 もしもより新しいコミットがあり Fast Forward で解決出来ない場合は次のようなエラーになります。
$ git push To git://iskrdevq/project1.git ! [rejected] master -> master (non-fast-forward) error: failed to push some refs to 'git://iskrdevq/project1.git' To prevent ... See the 'Note about fast-forwards' section of 'git push --help' for details.
こうなったときの典型的な手順は次のとおりです。
まず、ローカルの origin/master に origin をフェッチします。
$ git fetch remote: Counting objects: 5, done. remote: Total 3 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (3/3), done. From git://iskrdevq/project1 5af725a..0d567b6 master -> origin/master
master に origin/master をマージします。
$ git merge origin/master Auto-merging hello.py CONFLICT (content): Merge conflict in hello.py Automatic merge failed; fix conflicts and then commit the result.
もちろんこのままでは、コンフリクトですよね。マージツールを起動してマージします。
$ git mergetool merge tool candidates: meld opendiff kdiff3 tkdiff xxdiff tortoisemerge gvimdiff diffuse ecmerge p4merge araxis emerge vimdiff Merging the files: hello.py Normal merge conflict for 'hello.py': {local}: modified {remote}: modified Hit return to start merge resolution tool (meld):
ここでは Meld が設定してあるので Meld が起動しました。
マージを行い保存します。
変更をコミットして、プッシュを行います。
$ git commit -m "Fixed conflict" [master d6fb4e2] Fixed conflict $ git push Counting objects: 8, done. Delta compression using up to 4 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (4/4), 413 bytes, done. Total 4 (delta 1), reused 0 (delta 0) To git://iskrdevq/project1.git 79d7dc2..d6fb4e2 master -> master
以上でマージが完了でき、その結果を origin/master に push もできました。