Skip to content

Commit 2342925

Browse files
Copilothuangyiirene
andcommitted
Changes before error encountered
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
1 parent af69e30 commit 2342925

File tree

3 files changed

+126
-58
lines changed

3 files changed

+126
-58
lines changed

.gitattributes

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
1-
# Auto-resolve pnpm lockfile conflicts using a custom merge driver
2-
pnpm-lock.yaml merge=pnpm-merge-driver
1+
# Auto-resolve pnpm lockfile conflicts
2+
# Use 'union' merge strategy which combines both sides
3+
# Then run 'pnpm install' to regenerate the lockfile correctly
4+
pnpm-lock.yaml merge=union

docs/pnpm-lock-conflict-resolution.md

Lines changed: 89 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,19 @@ When multiple developers work on the same repository and modify dependencies in
66

77
## Solution
88

9-
This repository includes an **automated merge driver** for `pnpm-lock.yaml` that resolves conflicts automatically by regenerating the lockfile using `pnpm install`.
9+
This repository uses an **automated conflict resolution strategy** for `pnpm-lock.yaml`:
10+
11+
1. **Union Merge Strategy**: Git automatically combines both versions of the lockfile
12+
2. **Post-Merge Hook**: Automatically runs `pnpm install` after merges to regenerate a valid lockfile
13+
3. **Version Enforcement**: The repository requires `pnpm >= 10.0.0` to ensure consistency
1014

1115
## How It Works
1216

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
17+
The solution uses Git's built-in `union` merge strategy combined with a post-merge hook:
18+
19+
1. **`.gitattributes`**: Configures pnpm-lock.yaml to use union merge (combines both sides)
20+
2. **`.git/hooks/post-merge`**: Automatically runs `pnpm install` after any merge that touches pnpm-lock.yaml
21+
3. **`package.json`**: Enforces pnpm version consistency across all developers
1622

1723
## Setup Instructions
1824

@@ -24,68 +30,75 @@ After cloning this repository, run the setup script once:
2430
./scripts/setup-merge-driver.sh
2531
```
2632

27-
This will configure your local Git repository to use the automatic merge driver for `pnpm-lock.yaml`.
33+
This will:
34+
- Create a post-merge Git hook that auto-runs `pnpm install` after merges
35+
- Display helpful information about how the system works
2836

2937
### What Happens During a Merge?
3038

31-
When you merge a branch that has conflicting changes in `pnpm-lock.yaml`:
39+
When you merge a branch that has changes in `pnpm-lock.yaml`:
3240

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
41+
1. Git uses the `union` strategy to combine both versions of the lockfile
42+
2. The merge completes without stopping for manual conflict resolution
43+
3. The post-merge hook automatically runs `pnpm install --no-frozen-lockfile`
44+
4. pnpm regenerates a correct lockfile based on all package.json files
45+
5. You review the changes and commit if needed
3746

3847
### Example Workflow
3948

4049
```bash
4150
# Start merging a branch
4251
git merge feature-branch
4352

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
53+
# Git automatically:
54+
# 1. ✅ Combines both versions of pnpm-lock.yaml
55+
# 2. ✅ Completes the merge
56+
# 3. ✅ Runs pnpm install automatically (via post-merge hook)
4857

49-
# Verify the changes
50-
git diff --cached pnpm-lock.yaml
58+
# You see:
59+
# 📦 pnpm-lock.yaml was updated in merge, running pnpm install...
60+
# ✅ Dependencies synchronized
5161

52-
# Commit the merge
53-
git commit
62+
# Review the changes
63+
git status
64+
git diff pnpm-lock.yaml
65+
66+
# If pnpm-lock.yaml was modified by pnpm install, commit it
67+
git add pnpm-lock.yaml
68+
git commit -m "chore: update pnpm-lock.yaml after merge"
5469
```
5570

5671
### Important Notes
5772

5873
⚠️ **Prerequisites:**
5974
- You must have `pnpm` installed and available in your PATH
6075
- The repository enforces `pnpm >= 10.0.0` (see `package.json` engines field)
76+
- Run `./scripts/setup-merge-driver.sh` once after cloning
6177

6278
⚠️ **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
79+
- If there are conflicts in `package.json` files, you must resolve those manually **first**
80+
- After resolving package.json conflicts, run `pnpm install` manually
81+
- Then complete the merge
6582

6683
⚠️ **Review After Merge:**
6784
- Always review the regenerated `pnpm-lock.yaml` to ensure dependencies are correct
85+
- The post-merge hook will remind you to review and commit changes
6886
- Run tests after merging to verify everything works as expected
6987

7088
## Manual Resolution (Fallback)
7189

72-
If the automatic merge driver fails or if you prefer manual resolution:
90+
If you prefer manual resolution or if the automatic process fails:
7391

7492
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-
```
93+
2. Run `pnpm install` to regenerate the lockfile:
94+
```bash
95+
pnpm install --no-frozen-lockfile
96+
```
97+
3. Stage and commit the regenerated lockfile:
98+
```bash
99+
git add pnpm-lock.yaml
100+
git commit -m "chore: regenerate pnpm-lock.yaml"
101+
```
89102

90103
## Version Consistency
91104

@@ -119,36 +132,65 @@ corepack enable
119132
corepack prepare pnpm@10.0.0 --activate
120133
```
121134

122-
### Merge driver not being invoked
135+
### Post-merge hook not running
123136

124-
1. Verify the merge driver is configured:
137+
1. Verify the hook is installed and executable:
125138
```bash
126-
git config --local merge.pnpm-merge-driver.driver
139+
ls -la .git/hooks/post-merge
127140
```
128141

129142
2. Re-run the setup script:
130143
```bash
131144
./scripts/setup-merge-driver.sh
132145
```
133146

134-
3. Check that `.gitattributes` exists and contains the merge driver configuration:
147+
3. Make sure you're using `git merge` (hooks don't run with some Git GUI tools)
148+
149+
### pnpm install fails after merge
150+
151+
1. Check that you have no `package.json` conflicts remaining:
152+
```bash
153+
git status
154+
```
155+
156+
2. Resolve any package.json conflicts manually
157+
158+
3. Run `pnpm install` manually:
159+
```bash
160+
pnpm install --no-frozen-lockfile
161+
```
162+
163+
4. Complete the merge:
135164
```bash
136-
cat .gitattributes
165+
git add pnpm-lock.yaml
166+
git commit
137167
```
138168

139-
### Merge driver fails
169+
### Want to disable automatic pnpm install?
170+
171+
If you prefer to run `pnpm install` manually after merges:
140172

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)
173+
```bash
174+
rm .git/hooks/post-merge
175+
```
176+
177+
The union merge strategy will still work, you'll just need to run `pnpm install` yourself.
145178

146179
## CI/CD Integration
147180

148181
The GitHub Actions workflows in this repository already use pnpm@10 consistently. No additional CI configuration is needed.
149182

183+
## How This Compares to Other Solutions
184+
185+
| Approach | Pros | Cons |
186+
|----------|------|------|
187+
| **Union merge + hook** (This repo) | ✅ Simple<br>✅ Reliable<br>✅ No custom code<br>✅ Works with all Git tools | ⚠️ Requires one-time setup<br>⚠️ May need manual commit |
188+
| **Custom merge driver** | ✅ Fully automatic | ❌ Complex<br>❌ Hard to debug<br>❌ May fail silently |
189+
| **Manual resolution** | ✅ Full control | ❌ Tedious<br>❌ Error-prone<br>❌ Slows down workflow |
190+
| **Always use ours/theirs** | ✅ Never blocks | ❌ Loses changes<br>❌ Must always regenerate |
191+
150192
## References
151193

152194
- [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)
195+
- [Git Attributes - Merge Strategies](https://git-scm.com/docs/gitattributes#_built_in_merge_drivers)
196+
- [Git Hooks - post-merge](https://git-scm.com/docs/githooks#_post_merge)

scripts/setup-merge-driver.sh

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,47 @@
11
#!/bin/bash
2-
# Setup script to configure pnpm-lock.yaml merge driver for this repository
2+
# Setup script for automatic pnpm-lock.yaml conflict resolution
33
# Run this script once after cloning the repository
44

55
set -e
66

7-
echo "🔧 Setting up pnpm-lock.yaml merge driver..."
7+
echo "🔧 Setting up automatic pnpm-lock.yaml conflict resolution..."
88

99
# Get the repository root directory
1010
REPO_ROOT=$(git rev-parse --show-toplevel)
1111
cd "$REPO_ROOT"
1212

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
13+
# Create git hooks directory if it doesn't exist
14+
mkdir -p .git/hooks
1715

18-
echo "✅ pnpm-lock.yaml merge driver configured successfully!"
16+
# Create post-merge hook to auto-run pnpm install after merges
17+
cat > .git/hooks/post-merge << 'HOOK_EOF'
18+
#!/bin/bash
19+
# Auto-run pnpm install after merge if pnpm-lock.yaml was updated
20+
21+
# Check if pnpm-lock.yaml was modified in the merge
22+
if git diff --name-only HEAD@{1} HEAD 2>/dev/null | grep -q "pnpm-lock.yaml"; then
23+
echo "📦 pnpm-lock.yaml was updated in merge, running pnpm install..."
24+
if command -v pnpm &> /dev/null; then
25+
pnpm install --no-frozen-lockfile
26+
echo "✅ Dependencies synchronized"
27+
echo "⚠️ Please review pnpm-lock.yaml and commit if needed"
28+
else
29+
echo "⚠️ pnpm not found, please run: pnpm install"
30+
fi
31+
fi
32+
HOOK_EOF
33+
34+
chmod +x .git/hooks/post-merge
35+
36+
echo "✅ Setup complete!"
37+
echo ""
38+
echo "ℹ️ Configuration applied:"
39+
echo " - pnpm-lock.yaml uses 'union' merge strategy (combines both sides)"
40+
echo " - post-merge hook will auto-run 'pnpm install' after merges"
1941
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."
42+
echo "ℹ️ How it works:"
43+
echo " 1. When merging, git combines both versions of pnpm-lock.yaml"
44+
echo " 2. After merge completes, pnpm install runs automatically to fix any issues"
45+
echo " 3. Review and commit the updated lockfile"
2246
echo ""
2347
echo "⚠️ Note: Make sure to resolve any package.json conflicts manually before merging."

0 commit comments

Comments
 (0)