Skip to content

Commit 4df44cf

Browse files
authored
Git - create worktree improvements (#278194)
1 parent 65a9d0b commit 4df44cf

File tree

1 file changed

+30
-23
lines changed

1 file changed

+30
-23
lines changed

extensions/git/src/repository.ts

Lines changed: 30 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,42 +1801,48 @@ export class Repository implements Disposable {
18011801

18021802
async createWorktree(options?: { path?: string; commitish?: string; branch?: string }): Promise<string> {
18031803
const defaultWorktreeRoot = this.globalState.get<string>(`${Repository.WORKTREE_ROOT_STORAGE_KEY}:${this.root}`);
1804-
let { path: worktreePath, commitish, branch } = options || {};
1805-
let worktreeName: string | undefined;
1804+
const config = workspace.getConfiguration('git', Uri.file(this.root));
1805+
const branchPrefix = config.get<string>('branchPrefix', '');
18061806

18071807
return await this.run(Operation.Worktree, async () => {
1808-
// Generate branch name if not provided
1809-
if (branch === undefined) {
1810-
const config = workspace.getConfiguration('git', Uri.file(this.root));
1811-
const branchPrefix = config.get<string>('branchPrefix', '');
1808+
let worktreeName: string | undefined;
1809+
let { path: worktreePath, commitish, branch } = options || {};
18121810

1813-
let worktreeName = await this.getRandomBranchName();
1811+
if (branch === undefined) {
1812+
// Generate branch name if not provided
1813+
worktreeName = await this.getRandomBranchName();
18141814
if (!worktreeName) {
18151815
// Fallback to timestamp-based name if random generation fails
18161816
const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
18171817
worktreeName = `worktree-${timestamp}`;
18181818
}
1819-
18201819
branch = `${branchPrefix}${worktreeName}`;
1820+
1821+
// Append worktree name to provided path
1822+
if (worktreePath !== undefined) {
1823+
worktreePath = path.join(worktreePath, worktreeName);
1824+
}
1825+
} else {
1826+
// Extract worktree name from branch
1827+
worktreeName = branch.startsWith(branchPrefix)
1828+
? branch.substring(branchPrefix.length).replace(/\//g, '-')
1829+
: branch.replace(/\//g, '-');
18211830
}
18221831

1823-
// Generate path if not provided
18241832
if (worktreePath === undefined) {
18251833
worktreePath = defaultWorktreeRoot
1826-
? path.join(defaultWorktreeRoot, worktreeName!)
1827-
: path.join(path.dirname(this.root), `${path.basename(this.root)}.worktrees`, worktreeName!);
1828-
1829-
// Ensure that the worktree path is unique
1830-
if (this.worktrees.some(worktree => pathEquals(path.normalize(worktree.path), path.normalize(worktreePath!)))) {
1831-
let counter = 1;
1832-
let uniqueWorktreePath = `${worktreePath}-${counter}`;
1833-
while (this.worktrees.some(wt => pathEquals(path.normalize(wt.path), path.normalize(uniqueWorktreePath)))) {
1834-
counter++;
1835-
uniqueWorktreePath = `${worktreePath}-${counter}`;
1836-
}
1834+
? path.join(defaultWorktreeRoot, worktreeName)
1835+
: path.join(path.dirname(this.root), `${path.basename(this.root)}.worktrees`, worktreeName);
1836+
}
18371837

1838-
worktreePath = uniqueWorktreePath;
1839-
}
1838+
// Ensure that the worktree path is unique
1839+
if (this.worktrees.some(worktree => pathEquals(path.normalize(worktree.path), path.normalize(worktreePath!)))) {
1840+
let counter = 0, uniqueWorktreePath: string;
1841+
do {
1842+
uniqueWorktreePath = `${worktreePath}-${++counter}`;
1843+
} while (this.worktrees.some(wt => pathEquals(path.normalize(wt.path), path.normalize(uniqueWorktreePath))));
1844+
1845+
worktreePath = uniqueWorktreePath;
18401846
}
18411847

18421848
// Create the worktree
@@ -3047,6 +3053,7 @@ export class Repository implements Disposable {
30473053
}
30483054

30493055
const dictionaries: string[][] = [];
3056+
const branchPrefix = config.get<string>('branchPrefix', '');
30503057
const branchWhitespaceChar = config.get<string>('branchWhitespaceChar', '-');
30513058
const branchRandomNameDictionary = config.get<string[]>('branchRandomName.dictionary', ['adjectives', 'animals']);
30523059

@@ -3075,7 +3082,7 @@ export class Repository implements Disposable {
30753082
});
30763083

30773084
// Check for local ref conflict
3078-
const refs = await this.getRefs({ pattern: `refs/heads/${randomName}` });
3085+
const refs = await this.getRefs({ pattern: `refs/heads/${branchPrefix}${randomName}` });
30793086
if (refs.length === 0) {
30803087
return randomName;
30813088
}

0 commit comments

Comments
 (0)