Skip to content

Commit e10cb75

Browse files
authored
Fixes merge conflict resolution always querying the network (#5504)
**What's the problem this PR addresses?** I broke part of the automatic conflict resolution in #5102 - a code supposed to make Yarn update the lockfile metadata when merging incompatible lockfile versions was incorrectly causing Yarn to do that for each merge conflict resolution. It can be very frustrating when the project includes some dependencies that cannot be easily pulled from the registry (for example when they are a npm git repo which doesn't build anymore due to ERESOLVE 😄). **How did you fix it?** Fix the code to remove the `0` from `Math.min(0, ...)` which was obviously causing the version to always be `0`. **Checklist** <!--- Don't worry if you miss something, chores are automatically tested. --> <!--- This checklist exists to help you remember doing the chores when you submit a PR. --> <!--- Put an `x` in all the boxes that apply. --> - [x] I have read the [Contributing Guide](https://yarnpkg.com/advanced/contributing). <!-- See https://yarnpkg.com/advanced/contributing#preparing-your-pr-to-be-released for more details. --> <!-- Check with `yarn version check` and fix with `yarn version check -i` --> - [x] I have set the packages that need to be released for my changes to be effective. <!-- The "Testing chores" workflow validates that your PR follows our guidelines. --> <!-- If it doesn't pass, click on it to see details as to what your PR might be missing. --> - [x] I will check that all automated PR checks pass before the PR gets reviewed.
1 parent 16b0ca7 commit e10cb75

File tree

4 files changed

+123
-6
lines changed

4 files changed

+123
-6
lines changed

.yarn/versions/2c3690ed.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
releases:
2+
"@yarnpkg/cli": patch
3+
"@yarnpkg/plugin-essentials": patch
4+
5+
declined:
6+
- "@yarnpkg/plugin-compat"
7+
- "@yarnpkg/plugin-constraints"
8+
- "@yarnpkg/plugin-dlx"
9+
- "@yarnpkg/plugin-init"
10+
- "@yarnpkg/plugin-interactive-tools"
11+
- "@yarnpkg/plugin-nm"
12+
- "@yarnpkg/plugin-npm-cli"
13+
- "@yarnpkg/plugin-pack"
14+
- "@yarnpkg/plugin-patch"
15+
- "@yarnpkg/plugin-pnp"
16+
- "@yarnpkg/plugin-pnpm"
17+
- "@yarnpkg/plugin-stage"
18+
- "@yarnpkg/plugin-typescript"
19+
- "@yarnpkg/plugin-version"
20+
- "@yarnpkg/plugin-workspace-tools"
21+
- "@yarnpkg/builder"
22+
- "@yarnpkg/core"
23+
- "@yarnpkg/doctor"

packages/acceptance-tests/pkg-tests-specs/sources/features/__snapshots__/mergeConflictResolution.test.js.snap

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,52 @@ exports[`Features Merge Conflict Resolution it should support fixing rebase conf
195195
",
196196
}
197197
`;
198+
199+
exports[`Features Merge Conflict Resolution it shouldn't re-fetch the lockfile metadata when performing simple merge conflict resolutions 1`] = `
200+
"# This file is generated by running "yarn install" inside your project.
201+
# Manual changes might be lost - proceed with caution!
202+
203+
__metadata:
204+
version: 7
205+
cacheKey: 0
206+
207+
"no-deps@npm:*":
208+
<<<<<<< HEAD
209+
version: 1.0.0
210+
resolution: "no-deps@npm:1.0.0"
211+
checksum: <checksum stripped>
212+
=======
213+
version: 2.0.0
214+
resolution: "no-deps@npm:2.0.0"
215+
checksum: <checksum stripped>
216+
>>>>>>> 2.0.0
217+
languageName: node
218+
linkType: hard
219+
220+
"root-workspace-0b6124@workspace:.":
221+
version: 0.0.0-use.local
222+
resolution: "root-workspace-0b6124@workspace:."
223+
dependencies:
224+
no-deps: "npm:*"
225+
languageName: unknown
226+
linkType: soft
227+
"
228+
`;
229+
230+
exports[`Features Merge Conflict Resolution it shouldn't re-fetch the lockfile metadata when performing simple merge conflict resolutions 2`] = `
231+
{
232+
"code": 0,
233+
"stderr": "",
234+
"stdout": "➤ YN0048: Automatically fixed merge conflicts 👍
235+
236+
YN0000: ┌ Resolution step
237+
YN0000: └ Completed
238+
YN0000: ┌ Fetch step
239+
YN0019: │ no-deps-npm-2.0.0-8c4f3f8395-9c77ddf9a6.zip appears to be unused - removing
240+
YN0000: └ Completed
241+
YN0000: ┌ Link step
242+
YN0000: └ Completed
243+
YN0000: Done
244+
",
245+
}
246+
`;

packages/acceptance-tests/pkg-tests-specs/sources/features/mergeConflictResolution.test.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,5 +194,50 @@ describe(`Features`, () => {
194194
},
195195
),
196196
);
197+
198+
test(
199+
`it shouldn't re-fetch the lockfile metadata when performing simple merge conflict resolutions`,
200+
makeTemporaryEnv(
201+
{},
202+
async ({path, run, source}) => {
203+
await execFile(`git`, [`init`], {cwd: path});
204+
await execFile(`git`, [`config`, `user.email`, `[email protected]`], {cwd: path});
205+
await execFile(`git`, [`config`, `user.name`, `Your Name`], {cwd: path});
206+
await execFile(`git`, [`config`, `commit.gpgSign`, `false`], {cwd: path});
207+
208+
await run(`install`);
209+
await xfs.writeJsonPromise(`${path}/package.json`, {dependencies: {[`no-deps`]: `*`}});
210+
211+
await execFile(`git`, [`add`, `-A`], {cwd: path});
212+
await execFile(`git`, [`commit`, `-a`, `-m`, `my-commit`], {cwd: path});
213+
214+
await execFile(`git`, [`checkout`, `master`], {cwd: path});
215+
await execFile(`git`, [`checkout`, `-b`, `1.0.0`], {cwd: path});
216+
await run(`set`, `resolution`, `no-deps@npm:*`, `npm:1.0.0`);
217+
await execFile(`git`, [`add`, `-A`], {cwd: path});
218+
await execFile(`git`, [`commit`, `-a`, `-m`, `commit-1.0.0`], {cwd: path});
219+
220+
await execFile(`git`, [`checkout`, `master`], {cwd: path});
221+
await execFile(`git`, [`checkout`, `-b`, `2.0.0`], {cwd: path});
222+
await run(`set`, `resolution`, `no-deps@npm:*`, `npm:2.0.0`);
223+
await execFile(`git`, [`add`, `-A`], {cwd: path});
224+
await execFile(`git`, [`commit`, `-a`, `-m`, `commit-2.0.0`], {cwd: path});
225+
226+
await execFile(`git`, [`checkout`, `master`], {cwd: path});
227+
await execFile(`git`, [`merge`, `1.0.0`], {cwd: path});
228+
229+
await expect(execFile(`git`, [`merge`, `2.0.0`], {cwd: path, env: {LC_ALL: `C`}})).rejects.toThrow(/CONFLICT/);
230+
231+
let lockfile = await xfs.readFilePromise(`${path}/yarn.lock`, `utf8`);
232+
lockfile = lockfile.replace(/(checksum: ).*/g, `$1<checksum stripped>`);
233+
234+
expect(lockfile).toMatchSnapshot();
235+
236+
await expect(run(`install`, {
237+
enableNetwork: false,
238+
})).resolves.toMatchSnapshot();
239+
},
240+
),
241+
);
197242
});
198243
});

packages/plugin-essentials/sources/commands/install.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -435,13 +435,13 @@ async function autofixMergeConflicts(configuration: Configuration, immutable: bo
435435

436436
// We must keep the lockfile version as small as necessary to force Yarn to
437437
// refresh the merged-in lockfile metadata that may be missing.
438-
merged.__metadata.version = Math.min(0, ...variants.map(variant => {
439-
return variant.__metadata.version ?? Infinity;
440-
}));
438+
merged.__metadata.version = `${Math.min(...variants.map(variant => {
439+
return parseInt(variant.__metadata.version ?? 0);
440+
}))}`;
441441

442-
merged.__metadata.cacheKey = Math.min(0, ...variants.map(variant => {
443-
return variant.__metadata.cacheKey ?? 0;
444-
}));
442+
merged.__metadata.cacheKey = `${Math.min(...variants.map(variant => {
443+
return parseInt(variant.__metadata.cacheKey ?? 0);
444+
}))}`;
445445

446446
// parse as valid YAML except that the objects become strings. We can use
447447
// that to detect them. Damn, it's really ugly though.

0 commit comments

Comments
 (0)