2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

GitAdvent Calendar 2019

Day 14

コンフリクト解決を少しだけ楽にする

Last updated at Posted at 2019-12-13

解決したい問題

マージやリベースでコンフリクトが発生したとき、簡単な競合であればできるだけ手で編集はしたくないですよね。

そこで使うのが git checkout--theirs--ours オプションですが、追加する変更同士のコンフリクトは、たまに両方を採用したい場合もあります。

こういうコンフリクトを

$ git diff
diff --cc test/test-foo.rb
index dfbf2cc,f42377c..0000000
--- a/test/test-foo.rb
+++ b/test/test-foo.rb
@@@ -8,7 -8,7 +8,11 @@@ class TestFoo < Test::Unit::TestCas

    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
++<<<<<<< HEAD
 +    assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
++=======
+     assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
++>>>>>>> develop2
    end

    def teardown

こうしたり

    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
      assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
      assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
    end

こうしたい

    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
      assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
      assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
    end

解決方法

VSCodeを使っていれば "Accept both changes" というオプション1があり、手で編集しなくても両方の変更を採用した状態にできます。Atomをつかっていると、さらに "Resolve as Theirs then Ours" というオプション2もあって、theirs -> ours の順に両方をマージした状態にできるようです。
ところがコマンドラインでgitを使っていると、そういう手段は提供されていないように思います。

そこで、これを解決するだけの拡張を作りました。リポジトリはこちらです。

中身はコンフリクトのマーク <<<<<<< ======= >>>>>>>sed で見つけて置換しているだけです。
下のように使います。

$ git accept ours-then-theirs test/test-foo.rb  # ours-then-theirs の順にマージ
$ git diff
diff --cc test/test-foo.rb
index dfbf2cc,f42377c..0000000
--- a/test/test-foo.rb
+++ b/test/test-foo.rb
@@@ -8,7 -8,7 +8,8 @@@ class TestFoo < Test::Unit::TestCas
  
    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
 +    assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
+     assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
    end
  
    def teardown
$
$ git accept cancel test/test-foo.rb  # cancel で 3-way merge の状態をチェックアウト
$ git diff
diff --cc test/test-foo.rb
index dfbf2cc,f42377c..0000000
--- a/test/test-foo.rb
+++ b/test/test-foo.rb
@@@ -8,7 -8,7 +8,11 @@@ class TestFoo < Test::Unit::TestCas
  
    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
++<<<<<<< ours
 +    assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
++=======
+     assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
++>>>>>>> theirs
    end
  
    def teardown
$
$ git accept theirs-then-ours test/test-foo.rb  # theirs-then-ours で逆順にマージ
$ git diff
diff --cc test/test-foo.rb
index dfbf2cc,f42377c..0000000
--- a/test/test-foo.rb
+++ b/test/test-foo.rb
@@@ -8,7 -8,7 +8,8 @@@ class TestFoo < Test::Unit::TestCas
  
    def test_bar
      assert_equal(0, @foo.bar(0), "bar(0) should have been perfomed correctly")
+     assert_equal('qux', @foo.bar('qux'), "bar('qux') should have been perfomed correctly")
 +    assert_equal('baz', @foo.bar('baz'), "bar('baz') should have been perfomed correctly")
    end
  
    def teardown

あとは add して merge --continue するだけです。

これを使ってちょっとだけ手数が減らせる?んじゃないかと思っています。
簡単ですが以上です。

  1. https://code.visualstudio.com/docs/editor/versioncontrol#_merge-conflicts

  2. https://atom.io/packages/merge-conflicts

2
1
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
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?