Composer & composer.lock in GIT and merge conflicts
Stefan Bogdanescu
Founder & Senior Architect · 2026-06-29
Mastering Dependencies: Composer, Git, and Navigating Merge Conflicts in Multi-Project Environments
As senior developers working with complex dependency trees, managing the interplay between package management tools like Composer and version control systems like Git is a daily challenge. When you introduce shared components—like your private Core package—the necessity for a robust workflow becomes paramount. The situation you've described, involving memory constraints during updates and subsequent merge conflicts on composer.lock, is incredibly common when scaling dependency management across multiple projects.
This post will break down why these conflicts occur and establish a definitive, clean workflow for managing Composer dependencies with Git, ensuring stability for your Laravel applications.
The Composer Paradox: Why update vs. install Matters
The core of your dilemma lies in the difference between composer update and composer install. Understanding this distinction is the first step to solving your performance and conflict issues.
composer update: This command reads your composer.json, resolves all dependencies (including transitive ones), fetches the latest compatible versions, and rewrites the composer.lock file to reflect these new resolutions. This process involves significant computation and I/O, which is why it can be memory-intensive on constrained environments like your staging server.
composer install: This command reads the existing composer.lock file and installs exactly those versions specified within it. It is a deterministic operation. When running this via git pull, you are simply ensuring that the environment matches the state committed in the repository. As you noted, it is less memory-demanding because it avoids the heavy resolution step.
While avoiding memory issues with composer install is a practical win for deployment, the challenge shifts to managing the file integrity when developers are actively working on local changes.
Deconstructing the Git/Composer Conflict
Your workflow attempts to balance the need for up-to-date dependencies (from the Core package) and version control integrity. The conflicts arise because both processes are trying to modify the same file (composer.lock) concurrently:
- Local Development: A developer runs
composer updatelocally, which generates a new, desired state forcomposer.lock. They commit this change. - Remote Pull (Server): Another developer pulls these changes. If they then