前回はプルリクエストについてお話ししました。メンバーへあなたが行った実験的な変更の成果を受け入れてもらいました。
しかし、実際にはこのようにすんなりいくことは少ないでしょう。というのも、あなたが実験を行っている間にも業務は止まりません。あるいは公開しているので他にやらなければならないことが発生することも多々あります。
今回はそうしたバージョン管理におけるトラブルを回避する方法についてみていきたいと思います。
トラブルを避けてうまく改善していくには
さて、前回まではGitBucket上でマージを行いましたよね。それでは手元のリポジトリを最新にしておきます。現在はtest1ブランチになっていると思います。そこで、おさらいを兼ねてまずはmasterブランチへ切り替えましょう。
git checkout master
これでmasterリポジトリへ戻ってこれたでしょうか?次に中央のデータベースで行われたマージを手元に取り込んでおきましょう。アップロードの反対、ダウンロードに加えてマージも行ってくれる「pull」を使ってみたいと思います。
git pull origin master
今回はすんなり手元が最新になっているはずです。現在の状態を視覚的に見てみることにしましょう。次のコマンドを実行すると少し視覚的に見ることができます。
git log --oneline --graph
すると、次のような形で出力されると思います。
* ed1a810 Merge pull request #1 from nalulabo/test1
|\
| * 3209516 this is exprerimental commit.
|/* 1f1d90e first commit.
* b4cca8a Initial commit
絵で描くと次のような形になっていることがお分かりでしょうか?
実験との競合
さて、ではあなたが実験をするために「test2」というブランチをつくるとします。
git branch test2 master
そして、「second.html」について変更を加えたとします。変更を加えた結果、test2ブランチはこのような結果になりました。
diff --git a/second.html b/second.html
index 19b5939..dafc5ea 100644
--- a/second.html
+++ b/second.html@@ -1,5 +1,5 @@
<!doctype html>
<html lang="ja">
<head><title>second</title></head>
-<body><h1>this is Experiment!</h1></body>
+<body><h1>this is not experiment !!</h1></body>
</html>
\ No newline at end of file
そしてコミットまでしておきましょう。
一方、前回ユーザーを追加しましたアギトさんはこのhtmlについて修正を行っていました。「公開してるHTMLで実験ってなんだよ…」ということになったから、とでも思っておいてください。アギトさんは「hotfix20160307」というブランチをmasterの同じ時点から作成し、次のような更新をしました。
diff --git a/second.html b/second.html
index 19b5939..3dd9a59 100644
--- a/second.html
+++ b/second.html@@ -1,5 +1,8 @@
<!doctype html>
<html lang="ja">
<head><title>second</title></head>
-<body><h1>this is Experiment!</h1></body>
+<body>
+<h1>my html is awesome !</h1>
+<h2>this is not experimental !</h2>
+</body>
</html>
\ No newline at end of file
なんと、ほぼ同じ個所を更新したわけです。そしてもちろんコミットしてこのブランチをプッシュもしました。現時点ではアギトさんの変更はそのまま自動的にマージできる状態です。ということで「test2」ブランチと「hotfix20160307」ブランチとの差異はこのようになりました。
これは自動的にはマージすることができません。アギトさんと協議して、どの変更をどこまで残すかなどを話し合うことになります。
競合を解消しよう
さて、全く同じ個所を変更してしまったので、アギトさんとどこをどう残すかについて話し合いをおこなったとしましょう。その結果、アギトさんの修正は「これは実験ではない」ということを表明するためのものだったこと、そして実験ではないことを主張したいこともあって見出し1の部分はtest2ブランチを、それ以外はhotfix20160307ブランチの変更を使用してはどうか、ということに落ち着きそうです。
ということで、流れとしてはtest2へhotfix20160307をマージしたうえで、test2ブランチをmasterブランチへマージするということになりそうです。ではその流れを実際にやっていきたいと思います。
あなたは手元にhotfix20160307ブランチを持ってくる必要がありますね。これを一度にやってしまうには次のコマンドを実行します。
git checkout -b hotfix20160307 origin/hotfix20160307
これはローカルに「hotfix20160307」ブランチを新規に作成しつつ、リモートから「hotfix20160307」をダウンロードしてきてブランチを切り替えるということをしてくれます。ということで、現在はhotfix20160307ブランチになっているはずです。「git branch」してみてください。
* hotfix20160307
master
test1
test2
なっていますね。それではマージしてみることにしましょう。hotfix20160307のほうがブランチとしては先に世に出ているので、こちらをベースにマージするべきでしょう。よってtest2ブランチへhotfix20160307からマージしてみたいと思います。再度「git checkout test2」としてtest2ブランチへ移動したあと、マージをコマンドから行ってみます。
git merge hotfix20160307
そうすると、何やらエラーメッセージが表示されます。
Auto-merging second.html
CONFLICT (content): Merge conflict in second.html
Automatic merge failed; fix conflicts and then commit the result.
ではどうなったか、「second.html」をテキストエディタ等で開いてみてください。
<!doctype html>
<html lang="ja">
<head><title>second</title></head>
<<<<<<< HEAD<body><h1>this is not experiment !!</h1></body>
=======
<body>
<h1>my html is awesome !</h1>
<h2>this is not experimental !</h2>
</body>
>>>>>>> hotfix20160307
</html>
なにやら自動的に追記されているのがおわかりかと思います。
「<<<<<<< HEAD」から「=======」までが現在のブランチの最新状態、そこから下側から「>>>>>>> hotfix20160307」がマージ元、今回はhotfix20160307ブランチの内容になります。こうしてアナログですがさきほど話し合った結果を踏まえて手作業で競合を解消していくようになります。
先ほどの話し合った結果では、見出し1はtest2ブランチを、それ以外はhotfix20160307ブランチの内容を利用しよう、ということでしたよね。ではそのように修正していきます。修正すると、以下のような結果になると思います。
<!doctype html>
<html lang="ja">
<head><title>second</title></head>
<body><h1>this is not experiment !!</h1>
<h2>this is not experimental !</h2>
</body>
</html>
大事なことなので2回言いました、というような内容ですね…では変更をコミットしてマージを完了させましょう。
git commit -a -m "resolved the conflict with hotfix20160307"
「-a」オプションは舞台に上がっていないものもすべてコミットに含める「git add」の代わりをするものです。今回は変更したものが「second.html」だけでしたのでこのようにしています。コミットが完了したら、「git log」で履歴を見てみましょう。
commit 47bf31282e5b55585e785953b0c5ab4f6c8b3fb8
Merge: 9e2ce4c f2f9d32
Author: m0t0k1 <motoki8791@gmail.com>
Date: Mon Mar 7 13:16:06 2016 +0900resolved the conflict with hotfix20160307
「Merge」と入っていますね。マージされました。それではtest2をGitBucketへアップロードしましょう。
git push origin test2
ここまでくれば、あとは前回と同様にGitBucketからプルリクエストしてmasterへ自動マージしましょう。
以下のような感じで自動マージできたでしょうか?
最後に
変更した内容が被ってる、しかもちょっとずつ違うということはメンバーが共同で作業していると発生しやすいものです。こうした場合にも変更内容を協調しながらマージしていくことで、バージョンを適切にマネジメントしていくことができます。
次回は適切なバージョン管理ということで関連する事項をいくつかお話ししていきたいと思います。
0コメント