Skip to content

Commit 9d26c2b

Browse files
committed
fix(worktree): improve symlink copy handling
- Introduced isSubPath utility to determine if a path is a subpath of another. - Enhanced copySymbolicLink function to handle symbolic links more accurately based on subpath checks, ensuring correct link resolution.
1 parent 72455d4 commit 9d26c2b

File tree

2 files changed

+18
-5
lines changed

2 files changed

+18
-5
lines changed

src/core/util/copyWorktreeFiles.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { createReadStream, createWriteStream } from 'fs';
88
import { Config } from '@/core/config/setting';
99
import { actionProgressWrapper } from '@/core/ui/progress';
1010
import { withResolvers } from '@/core/util/promise';
11+
import { isSubPath } from '@/core/util/folder';
1112

1213
async function copyFile(source: string, target: string, stat: Stats, signal: AbortSignal) {
1314
if (stat.isDirectory()) {
@@ -35,14 +36,17 @@ async function copySymbolicLink(source: string, target: string) {
3536
const realTargetPath = await fs.realpath(source);
3637
const linkStat = await fs.stat(realTargetPath);
3738

38-
// Calculate the new link path relative to the target directory
39-
const relativePath = path.relative(sourceDir, realTargetPath);
40-
const linkTarget = path.resolve(targetDir, relativePath);
41-
4239
// Determine link type based on target type
4340
const linkType: 'file' | 'dir' | 'junction' = linkStat.isDirectory() ? 'dir' : 'file';
4441

45-
await fs.symlink(linkTarget, target, linkType);
42+
// Calculate the new link path relative to the target directory
43+
if (isSubPath(sourceDir, realTargetPath)) {
44+
const relativePath = path.relative(sourceDir, realTargetPath);
45+
const linkTarget = path.resolve(targetDir, relativePath);
46+
await fs.symlink(linkTarget, target, linkType);
47+
} else {
48+
await fs.symlink(realTargetPath, target, linkType);
49+
}
4650
}
4751

4852
/**

src/core/util/folder.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,12 @@ export const getBaseBundleDir = (baseDir: string) => `${baseDir}.repoBackup`;
7373
export const findPrefixPath = (fsPath: string, strList: string[]) => {
7474
return strList.find((str) => fsPath.startsWith(str));
7575
};
76+
77+
// check if child is a subpath of parent
78+
export const isSubPath = (parent: string, child: string) => {
79+
const parentReal = path.resolve(parent);
80+
const childReal = path.resolve(child);
81+
if (parentReal === childReal) return false;
82+
const relative = path.relative(parentReal, childReal);
83+
return !relative.startsWith(`..${path.sep}`) && relative !== '..';
84+
};

0 commit comments

Comments
 (0)