Skip to content

Commit af69e30

Browse files
Copilothuangyiirene
andcommitted
Add automated pnpm lock conflict resolution
- Create .gitattributes with custom merge driver - Add pnpm-merge-driver.sh script to auto-resolve conflicts - Add setup-merge-driver.sh for easy configuration - Add comprehensive documentation - Enforce pnpm version in package.json - Update README with setup instructions Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent 0683cdb commit af69e30

File tree

6 files changed

+256
-2
lines changed

6 files changed

+256
-2
lines changed

.gitattributes

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Auto-resolve pnpm lockfile conflicts using a custom merge driver
2+
pnpm-lock.yaml merge=pnpm-merge-driver

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,14 +45,23 @@ ObjectQL is organized as a Monorepo to ensure modularity and universal compatibi
4545

4646
## ⚡ Quick Start
4747

48-
### 1. Installation
48+
### 1. Setup Development Environment
49+
50+
```bash
51+
# For contributors: Setup automatic pnpm-lock.yaml merge conflict resolution
52+
./scripts/setup-merge-driver.sh
53+
```
54+
55+
📖 **Having issues with pnpm-lock.yaml merge conflicts?** See [pnpm Lock Conflict Resolution Guide](./docs/pnpm-lock-conflict-resolution.md)
56+
57+
### 2. Installation
4958

5059
```bash
5160
# Install core and a driver (e.g., Postgres or SQLite)
5261
npm install @objectql/core @objectql/driver-sql sqlite3
5362
```
5463

55-
### 2. The Universal Script
64+
### 3. The Universal Script
5665

5766
ObjectQL can run in a single file without complex configuration.
5867

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# pnpm Lock File Merge Conflict Resolution
2+
3+
## Problem
4+
5+
When multiple developers work on the same repository and modify dependencies in parallel, merging branches often results in conflicts in the `pnpm-lock.yaml` file. These conflicts can be tedious to resolve manually.
6+
7+
## Solution
8+
9+
This repository includes an **automated merge driver** for `pnpm-lock.yaml` that resolves conflicts automatically by regenerating the lockfile using `pnpm install`.
10+
11+
## How It Works
12+
13+
1. **`.gitattributes`**: Configures Git to use a custom merge driver for `pnpm-lock.yaml`
14+
2. **`scripts/pnpm-merge-driver.sh`**: The merge driver script that automatically runs `pnpm install --lockfile-only` to regenerate the lockfile when conflicts occur
15+
3. **Git configuration**: Local git config that points to the merge driver script
16+
17+
## Setup Instructions
18+
19+
### For Developers
20+
21+
After cloning this repository, run the setup script once:
22+
23+
```bash
24+
./scripts/setup-merge-driver.sh
25+
```
26+
27+
This will configure your local Git repository to use the automatic merge driver for `pnpm-lock.yaml`.
28+
29+
### What Happens During a Merge?
30+
31+
When you merge a branch that has conflicting changes in `pnpm-lock.yaml`:
32+
33+
1. Git detects the conflict and invokes the custom merge driver
34+
2. The merge driver runs `pnpm install --lockfile-only` to regenerate the lockfile
35+
3. The newly generated lockfile incorporates dependencies from both branches
36+
4. The merge completes automatically without manual intervention
37+
38+
### Example Workflow
39+
40+
```bash
41+
# Start merging a branch
42+
git merge feature-branch
43+
44+
# If there's a pnpm-lock.yaml conflict:
45+
# ✅ The merge driver automatically resolves it
46+
# ✅ pnpm install is run to regenerate the lockfile
47+
# ✅ The merge completes successfully
48+
49+
# Verify the changes
50+
git diff --cached pnpm-lock.yaml
51+
52+
# Commit the merge
53+
git commit
54+
```
55+
56+
### Important Notes
57+
58+
⚠️ **Prerequisites:**
59+
- You must have `pnpm` installed and available in your PATH
60+
- The repository enforces `pnpm >= 10.0.0` (see `package.json` engines field)
61+
62+
⚠️ **Package.json Conflicts:**
63+
- If there are conflicts in `package.json` files, you must resolve those manually **before** the merge driver can successfully regenerate `pnpm-lock.yaml`
64+
- The merge driver will fail if `pnpm install` fails due to invalid `package.json` files
65+
66+
⚠️ **Review After Merge:**
67+
- Always review the regenerated `pnpm-lock.yaml` to ensure dependencies are correct
68+
- Run tests after merging to verify everything works as expected
69+
70+
## Manual Resolution (Fallback)
71+
72+
If the automatic merge driver fails or if you prefer manual resolution:
73+
74+
1. Resolve any `package.json` conflicts first
75+
2. Accept either version of `pnpm-lock.yaml` (doesn't matter which)
76+
3. Run `pnpm install` to regenerate the lockfile
77+
4. Stage and commit the regenerated lockfile:
78+
79+
```bash
80+
# After resolving package.json conflicts
81+
pnpm install
82+
83+
# Stage the regenerated lockfile
84+
git add pnpm-lock.yaml
85+
86+
# Complete the merge
87+
git commit
88+
```
89+
90+
## Version Consistency
91+
92+
To prevent lockfile conflicts caused by different pnpm versions, this repository:
93+
94+
- Specifies `packageManager: "pnpm@10.0.0"` in `package.json`
95+
- Requires `pnpm >= 10.0.0` in the `engines` field
96+
- Uses `pnpm@10` in GitHub Actions CI
97+
98+
All developers should use the same major version of pnpm. Consider using [Corepack](https://nodejs.org/api/corepack.html) to automatically use the correct pnpm version:
99+
100+
```bash
101+
corepack enable
102+
corepack prepare pnpm@10.0.0 --activate
103+
```
104+
105+
## Troubleshooting
106+
107+
### "pnpm is not installed"
108+
109+
Install pnpm globally:
110+
111+
```bash
112+
npm install -g pnpm@10
113+
```
114+
115+
Or use Corepack:
116+
117+
```bash
118+
corepack enable
119+
corepack prepare pnpm@10.0.0 --activate
120+
```
121+
122+
### Merge driver not being invoked
123+
124+
1. Verify the merge driver is configured:
125+
```bash
126+
git config --local merge.pnpm-merge-driver.driver
127+
```
128+
129+
2. Re-run the setup script:
130+
```bash
131+
./scripts/setup-merge-driver.sh
132+
```
133+
134+
3. Check that `.gitattributes` exists and contains the merge driver configuration:
135+
```bash
136+
cat .gitattributes
137+
```
138+
139+
### Merge driver fails
140+
141+
1. Check that you have no `package.json` conflicts remaining
142+
2. Try running `pnpm install` manually to see the error
143+
3. Resolve any dependency issues
144+
4. Continue the merge manually (see "Manual Resolution" above)
145+
146+
## CI/CD Integration
147+
148+
The GitHub Actions workflows in this repository already use pnpm@10 consistently. No additional CI configuration is needed.
149+
150+
## References
151+
152+
- [pnpm - Working with Git](https://pnpm.io/git)
153+
- [Git Attributes - Custom Merge Drivers](https://git-scm.com/docs/gitattributes#_defining_a_custom_merge_driver)
154+
- [Automating Lockfile Merge Conflicts](https://blog.aspect.build/easier-merges-on-lockfiles)

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
{
22
"name": "objectql-monorepo",
33
"private": true,
4+
"packageManager": "pnpm@10.0.0",
5+
"engines": {
6+
"node": ">=18.0.0",
7+
"pnpm": ">=10.0.0"
8+
},
49
"scripts": {
510
"build": "tsc -b && pnpm -r run build",
611
"check-versions": "node scripts/check-versions.js",

scripts/pnpm-merge-driver.sh

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/bash
2+
# Git merge driver for pnpm-lock.yaml
3+
# This script automatically resolves merge conflicts in pnpm-lock.yaml
4+
# by regenerating the lockfile using pnpm install
5+
#
6+
# Usage: This script is called automatically by git when a merge conflict
7+
# occurs in pnpm-lock.yaml (configured via .gitattributes)
8+
#
9+
# Arguments (provided by git):
10+
# $1 - %O - ancestor's version
11+
# $2 - %A - current version
12+
# $3 - %B - other branches' version
13+
# $4 - %L - conflict marker size (optional)
14+
# $5 - %P - pathname in which the merged result will be stored
15+
16+
set -e
17+
18+
ANCESTOR=$1
19+
CURRENT=$2
20+
OTHER=$3
21+
PATHNAME=$5
22+
23+
echo "🔄 Resolving pnpm-lock.yaml merge conflict..."
24+
25+
# Check if pnpm is available
26+
if ! command -v pnpm &> /dev/null; then
27+
echo "❌ Error: pnpm is not installed or not in PATH"
28+
echo "Please install pnpm: npm install -g pnpm"
29+
exit 1
30+
fi
31+
32+
# Get the repository root directory
33+
REPO_ROOT=$(git rev-parse --show-toplevel)
34+
35+
# Change to repository root
36+
cd "$REPO_ROOT"
37+
38+
# First, accept the current version (ours) to resolve the git conflict state
39+
cp "$CURRENT" "$PATHNAME"
40+
41+
echo "📦 Regenerating pnpm-lock.yaml by running pnpm install..."
42+
43+
# Run pnpm install to regenerate the lockfile
44+
# This will merge dependencies from both branches correctly
45+
if pnpm install --lockfile-only --no-frozen-lockfile 2>&1; then
46+
echo "✅ Successfully regenerated pnpm-lock.yaml"
47+
48+
# Copy the regenerated lockfile to the output location
49+
if [ -f "$REPO_ROOT/pnpm-lock.yaml" ]; then
50+
cp "$REPO_ROOT/pnpm-lock.yaml" "$PATHNAME"
51+
echo "✅ Merge conflict resolved successfully"
52+
exit 0
53+
else
54+
echo "❌ Error: pnpm-lock.yaml not found after regeneration"
55+
exit 1
56+
fi
57+
else
58+
echo "❌ Error: pnpm install failed"
59+
echo "Please resolve package.json conflicts first, then run: pnpm install"
60+
exit 1
61+
fi

scripts/setup-merge-driver.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/bash
2+
# Setup script to configure pnpm-lock.yaml merge driver for this repository
3+
# Run this script once after cloning the repository
4+
5+
set -e
6+
7+
echo "🔧 Setting up pnpm-lock.yaml merge driver..."
8+
9+
# Get the repository root directory
10+
REPO_ROOT=$(git rev-parse --show-toplevel)
11+
cd "$REPO_ROOT"
12+
13+
# Configure the merge driver in git config (local to this repository)
14+
git config merge.pnpm-merge-driver.name "Automatic merge driver for pnpm-lock.yaml"
15+
git config merge.pnpm-merge-driver.driver "$REPO_ROOT/scripts/pnpm-merge-driver.sh %O %A %B %L %P"
16+
git config merge.pnpm-merge-driver.recursive binary
17+
18+
echo "✅ pnpm-lock.yaml merge driver configured successfully!"
19+
echo ""
20+
echo "ℹ️ From now on, merge conflicts in pnpm-lock.yaml will be resolved automatically."
21+
echo "ℹ️ The merge driver will run 'pnpm install --lockfile-only' to regenerate the lockfile."
22+
echo ""
23+
echo "⚠️ Note: Make sure to resolve any package.json conflicts manually before merging."

0 commit comments

Comments
 (0)