13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[小ネタ] 生成されたファイル類(package-lock.json など)がコンフリクトしたら真面目にマージしないで

13
Last updated at Posted at 2026-03-17

はじめに

パッケージロックファイル (例: package.json => package-lock.json) やOAS (OpenAPI Specification) の生成ソースコード (例: swagger.json => src/**.ts) などの生成系の巨大ファイルの変更がコンフリクトした場合、真面目にマージしようとしないでください。

代わりに自動生成しなおしてください。

毎年新人にこの手のアドバイスをしている気がするので記事として残しておきます。

具体例: package-lock.json のコンフリクト

たとえば、以下のようなケースを考えます。

  1. Aさんが feature-a ブランチで lodash を追加
  2. あなたが feature-b ブランチで axios を追加
  3. Aさんのブランチが先に main へマージされた
  4. あなたのブランチをマージしようとすると……
feature-b ブランチで main を取り込もうとするとCONFLICTと言われてしまった
$ git merge main
Auto-merging package-lock.json
CONFLICT (add/add): Merge conflict in package-lock.json
Auto-merging package.json
CONFLICT (content): Merge conflict in package.json
Automatic merge failed; fix conflicts and then commit the result.

package.jsonpackage-lock.json がコンフリクトしているようです。

「解消しなきゃ……!」

package.json のコンフリクトはシンプルです。両方の依存を残せばOK。

package.json のコンフリクト(これは簡単)
  "dependencies": {
<<<<<<< HEAD (自分: feature-b)
    "axios": "^1.13.6"
=======
    "lodash": "^4.17.23"
>>>>>>> main (Aさん側)
  }

問題は package-lock.json です。こちらは300行超のコンフリクトになります。

package-lock.json のコンフリクト(抜粋)
  "packages": {
    "": {
      "dependencies": {
<<<<<<< HEAD (自分: feature-b)
        "axios": "^1.13.6"
      }
    },
    "node_modules/asynckit": { ... },
    "node_modules/axios": { ... },
    "node_modules/combined-stream": { ... },
    "node_modules/follow-redirects": { ... },
    "node_modules/form-data": { ... },
    ... (axios の依存ツリーがさらに十数パッケージ続く)
=======
        "lodash": "^4.17.23"
      }
    },
    "node_modules/lodash": {
      "version": "4.17.23",
      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.23.tgz",
      ...
>>>>>>> main (Aさん側)

これを手作業で正しくマージするのは現実的ではありませんし、やるべきではありません

正しい解消方法

package-lock.json のような生成物は、いったん相手側をそのまま受け入れてから再生成します。1

コンフリクト解消の手順
# 1. package.json は両方の依存を残す形で手動マージ(簡単)

# 2. package-lock.json は相手側(main)をそのまま受け入れる
# (自分が後でマージする予定なので、相手側を優先)
git checkout --theirs package-lock.json

# 3. マージ済みの package.json から再生成
npm install

# 4. コミット
git add package.json package-lock.json
git commit

(補足) 実は npm 自身でコンフリクトマーカーを解消できる

実は npm 5.7.0 以降では、package-lock.json にコンフリクトマーカーが残ったままでも npm install を実行すれば自動的に解消されます。2

As of npm@5.7.0, these conflicts can be resolved by manually fixing any package.json conflicts, and then running npm install [--package-lock-only] again. npm will automatically resolve any conflicts for you and write a merged package lock that includes all the dependencies from both branches in a reasonable tree.

npm Docs: package-locks

npm に任せる場合の手順
# 1. package.json のコンフリクトを解消(これは必要)

# 2. package-lock.json はコンフリクトマーカーが残ったまま npm install
npm install
# → npm がコンフリクトマーカーを見てマージ済みの lockfile を生成してくれる

同様の機能を pnpm (v5.11+) や yarn (v1.0+) も持っているようなので、使ってみてもいいかもしれません。(本記事の趣旨とは異なりますが)

まとめ 〜 他の自動生成系ファイルも同じ

この考え方は package-lock.json に限らず、冒頭で述べた OAS (OpenAPI Specification) なども同じです。とにかく一生懸命マージしないで(AIにさせようとせず)、以下を行いましょう。

  • 自動生成されたファイルのコンフリクトを手動マージしようとしない
  • 生成元ファイル(package.json など)のコンフリクトを正しく解消する
  • 生成コマンド(npm install など)を再実行して派生ファイルを作り直す

生成元のソースについて適切にマージできているのであれば、派生物は生成しなおしたものを使いましょう。3

  1. 厳密にいえば、こちらが一旦確定させたパッケージロック結果と異なってしまうわけですが、マージ運用でそれで困るケースは極稀と言えます。そもそもパッケージの多少のバージョン違いで困るぐらいなら、精密なバージョン番号を package.json に書いておけという話です。

  2. 実際に npm 11.8.0 でコンフリクトマーカーが残った package-lock.json に対して npm install を実行したところ、エラーなく正常に解消されることを確認済。

  3. いわずもがな、派生物をそもそもチェックインすべきでないという議論はクリアした上での話とします。

13
3
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
13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?