LoginSignup
46
46

More than 5 years have passed since last update.

コンフリクトした xib ファイルを上手にマージする

Last updated at Posted at 2013-06-10

本稿では、 Git でブランチをマージした際にコンフリクトした xib ファイルの衝突解決手順を解説する。

追記: Xcode 5 から導入された新しい xib フォーマットではコンフリクトが起こりにくくなっている。また、コンフリクトした場合に手作業で xib ファイルを編集することも、以前のフォーマットと比べれば容易になっている。本稿では以前のフォーマットを使っていることを前提に話を進める。

ステップ0:コンフリクトの解決をあきらめる

Xib ファイルをテキストエディタで編集してコンフリクトを解決しようなどと考えてはいけない(変更がごく小規模な場合を除く)。コンフリクトした xib ファイルは捨てて素直に作り直すのがよい。ただし、記憶を頼りに変更を再現する必要はない。 Xib ファイルの要素は コピー&ペーストできる ので、変更点の移植は比較的簡単にできる。

ステップ1:ベースにする xib ファイルをチェックアウトする

以下、 base ブランチに other ブランチをマージし、 Foo.xib がコンフリクトしたと想定する:

git checkout base
git merge --no-ff other
# Foo.xib がコンフリクト

まずはどちらかのブランチから Foo.xib をチェックアウトする。ここでチェックアウトしたファイルをベースにして他方のファイルの変更を取り込むため、共通の祖先から見て 変更量が多いほう を選ぶとよい:

git checkout base -- Foo.xib
# または
git checkout other -- Foo.xib

ステップ2:他方の xib ファイルをプロジェクトに追加する

他方のブランチから xib ファイルを Foo_.xib に書き出す:

# ステップ1で base をベースにしたなら
git show other:Foo.xib > Foo_.xib

# other をベースにしたなら
git show base:Foo.xib > Foo_.xib

そして Foo_.xib をプロジェクトに追加する。

ステップ3:ベースとなる xib ファイルに他方の要素を取り込む

Foo_.xib を開き、取り込みたい Foo_.xib の要素を選択してコピーする。 Foo.xib を開き、コピーした要素をペーストする。

step3.png

コピー&ペーストでは Identifier や Tag、 Editable といった属性もコピーされる。ただし、アウトレットと Cocoa Binding の設定は コピーされない ので、コピー後に改めて設定する。また、要素の Object ID も変化していることに注意。

要素のコピーと設定を終えたら Foo_.xib をプロジェクトから削除する。

ステップ4(オプション): strings ファイルを編集する

ローカライズに使う strings ファイルが存在する場合、コピー後の要素に合わせて Object ID を書き換える:

Foo.strings
/* Class = "NSButtonCell"; title = "Button"; ObjectID = "42"; */ // ←ここと
"42.title" = "ボタン";                                            // ←ここの ID

ステップ5(オプション): ibtool で xib をローカライズする

ibtool コマンドで差分ローカライズを実践しているなら、コンフリクトした2つの xib ファイルの 共通の祖先 を差分のベースにするとよい。

git show `git merge-base base other`:Foo.xib > Foo_common_ancestor.xib
ibtool --localize-incremental \
       --previous-file    Foo_common_ancestor.xib \
       --incremental-file Foo_localized.xib \
       --strings-file     Foo.strings \
       --write            Foo_localized.xib \
       Foo.xib
rm Foo_common_ancestor.xib

Git Tips

マージ中の2つのブランチの、元々チェックアウトされていたほうは HEAD で参照できる。他方(git merge の引数にしたほう)は MERGE_HEAD になる。つまりステップ1とステップ2は次のようにも実行できる:

git checkout HEAD -- Foo.xib
git show MERGE_HEAD:Foo.xib > Foo_.xib

また、 git checkout には --ours--theirs オプションもある:

# 同じ
git checkout HEAD -- Foo.xib
git checkout --ours -- Foo.xib

# 同じ
git checkout MERGE_HEAD -- Foo.xib
git checkout --theirs -- Foo.xib
46
46
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
46
46