Skip to content

Commit

Permalink
perf: 过滤有远程分支的worktree
Browse files Browse the repository at this point in the history
Signed-off-by: jackhuang <[email protected]>
  • Loading branch information
jackiotyu committed Oct 23, 2023
1 parent 1ce86ed commit 273a01b
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 29 deletions.
57 changes: 38 additions & 19 deletions src/lib/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,8 @@ export const addWorkTreeCmd = async () => {
});
};

const removeWorkTreeCmd = async (item: WorkTreeItem) => {
const removeWorkTreeCmd = async (item?: WorkTreeItem) => {
if (!item) return;
try {
const confirm = await confirmModal(
localize('msg.modal.title.deleteWorkTree'),
Expand All @@ -152,7 +153,8 @@ const removeWorkTreeCmd = async (item: WorkTreeItem) => {
updateTreeDataEvent.fire();
};

const addWorkTreeFromBranchCmd = async (item: WorkTreeItem) => {
const addWorkTreeFromBranchCmd = async (item?: WorkTreeItem) => {
if (!item) return;
let uriList = await vscode.window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
Expand All @@ -173,7 +175,8 @@ const addWorkTreeFromBranchCmd = async (item: WorkTreeItem) => {
});
};

const revealInSystemExplorerCmd = async (item: WorkTreeItem | GitFolderItem) => {
const revealInSystemExplorerCmd = async (item?: WorkTreeItem | GitFolderItem) => {
if (!item) return;
if (!(await checkFolderExist(item.path))) {
return;
}
Expand Down Expand Up @@ -205,19 +208,23 @@ const commonWorkTreeCmd = async (path: string, cmd: Commands, cwd?: string) => {
updateTreeDataEvent.fire();
};

const repairWorkTreeCmd = (item: WorkTreeItem) => {
const repairWorkTreeCmd = (item?: WorkTreeItem) => {
if (!item) return;
commonWorkTreeCmd(item.path, Commands.repairWorkTree, item.parent?.path);
};

const lockWorkTreeCmd = (item: WorkTreeItem) => {
const lockWorkTreeCmd = (item?: WorkTreeItem) => {
if (!item) return;
commonWorkTreeCmd(item.path, Commands.lockWorkTree, item.parent?.path);
};

const unlockWorkTreeCmd = (item: WorkTreeItem) => {
const unlockWorkTreeCmd = (item?: WorkTreeItem) => {
if (!item) return;
commonWorkTreeCmd(item.path, Commands.unlockWorkTree, item.parent?.path);
};

const moveWorkTreeCmd = async (item: WorkTreeItem) => {
const moveWorkTreeCmd = async (item?: WorkTreeItem) => {
if (!item) return;
try {
let uriList = await vscode.window.showOpenDialog({
canSelectFiles: false,
Expand All @@ -240,7 +247,8 @@ const moveWorkTreeCmd = async (item: WorkTreeItem) => {
updateTreeDataEvent.fire();
};

const switchToSelectFolderCmd = async (item: WorkTreeItem) => {
const switchToSelectFolderCmd = async (item?: WorkTreeItem) => {
if (!item) return;
try {
await vscode.commands.executeCommand('vscode.openFolder', vscode.Uri.file(item.path), {
forceNewWindow: false,
Expand Down Expand Up @@ -373,7 +381,8 @@ const refreshGitFolderCmd = () => {
updateFolderEvent.fire();
};

const pickFolderConfig = (item: GitFolderItem) => {
const pickFolderConfig = (item?: GitFolderItem) => {
if (!item) return;
return getFolderConfig().find((row) => row.path === item.path);
};

Expand All @@ -395,7 +404,8 @@ const removeGitFolderCmd = async (item: GitFolderItem) => {
Alert.showInformationMessage(localize('msg.success.remove'));
};

const renameGitFolderCmd = async (item: GitFolderItem) => {
const renameGitFolderCmd = async (item?: GitFolderItem) => {
if (!item) return;
let folder = pickFolderConfig(item);
if (!folder) {
return;
Expand Down Expand Up @@ -432,7 +442,8 @@ const openWalkthroughsCmd = () => {
);
};

const openTerminalCmd = async (item: WorkTreeItem | GitFolderItem | FolderItem) => {
const openTerminalCmd = async (item?: WorkTreeItem | GitFolderItem | FolderItem) => {
if (!item) return;
if (!(await checkFolderExist(item.path))) {
return;
}
Expand Down Expand Up @@ -481,7 +492,8 @@ const openTerminalCmd = async (item: WorkTreeItem | GitFolderItem | FolderItem)
cmdText && terminal.sendText(cmdText, true);
};

const openExternalTerminalCmd = async (item: WorkTreeItem | GitFolderItem | FolderItem) => {
const openExternalTerminalCmd = async (item?: WorkTreeItem | GitFolderItem | FolderItem) => {
if (!item) return;
if (!(await checkFolderExist(item.path))) {
return;
}
Expand All @@ -499,7 +511,8 @@ const addToWorkspaceCmd = async (item: WorkTreeItem | FolderItem) => {
return addToWorkspace(item.path);
};

const copyFilePathCmd = (item: WorkTreeItem | GitFolderItem | FolderItem) => {
const copyFilePathCmd = (item?: WorkTreeItem | GitFolderItem | FolderItem) => {
if (!item) return;
vscode.env.clipboard.writeText(item.path).then(() => {
Alert.showInformationMessage(localize('msg.success.copy', item.path));
});
Expand All @@ -513,11 +526,13 @@ const openRecentCmd = () => {
return vscode.commands.executeCommand('workbench.action.openRecent');
};

const addToGitFolderCmd = (item: FolderItem) => {
const addToGitFolderCmd = (item?: FolderItem) => {
if (!item) return;
return addToGitFolder(item.path);
};

const checkoutBranchCmd = async (item: WorkTreeItem) => {
const checkoutBranchCmd = async (item?: WorkTreeItem) => {
if (!item) return;
let branchItem = await pickBranch(
localize('msg.info.checkoutBranch', `${item.name} ⇄ ...${item.path.slice(-24)}`),
localize('msg.placeholder.checkoutBranch'),
Expand All @@ -537,7 +552,8 @@ const toggleGitFolderViewAs = (asTree: boolean) => {
toggleGitFolderViewAsEvent.fire(asTree);
};

const toggleGitFolderOpenCmd = async (item: GitFolderItem) => {
const toggleGitFolderOpenCmd = async (item?: GitFolderItem) => {
if (!item) return;
item.defaultOpen = !item.defaultOpen;
await updateFolderItem({
name: item.name,
Expand All @@ -550,15 +566,18 @@ const searchAllWorktreeCmd = () => {
pickWorktree();
};

const pushWorkTreeCmd = (item: WorkTreeItem) => {
const pushWorkTreeCmd = (item?: WorkTreeItem) => {
if (!item) return;
pullOrPushAction('push', item.name, item.path);
};

const pullWorkTreeCmd = (item: WorkTreeItem) => {
const pullWorkTreeCmd = (item?: WorkTreeItem) => {
if (!item) return;
pullOrPushAction('pull', item.name, item.path);
};

const loadAllTreeDataCmd = (item: ILoadMoreItem) => {
const loadAllTreeDataCmd = (item?: ILoadMoreItem) => {
if (!item) return;
loadAllTreeDataEvent.fire(item.viewId);
};

Expand Down
1 change: 1 addition & 0 deletions src/lib/quickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const pickBranch = async (
});
quickPick.show();
quickPick.busy = true;
// TODO 使用 git for-each-ref 获取所有分支和tag
const [branchList, remoteBranchList, tagList] = await Promise.all([
getBranchList(['refname:short', 'objectname:short', 'worktreepath', 'authordate', 'HEAD'], cwd),
getRemoteBranchList(['refname:short', 'objectname:short'], cwd),
Expand Down
39 changes: 29 additions & 10 deletions src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const WORK_TREE = 'worktree';

const executeGitCommandBase = (cwd: string, args?: string[], token?: vscode.CancellationToken): Promise<string> => {
return new Promise((resolve, reject) => {
// console.log('[executeGitCommand] ', ['git'].concat(args || []).join(' '));
logger.log(`'Running in' ${cwd}`);
logger.log('> ' + ['git'].concat(args || []).join(' '));
const proc = cp.spawn('git', args, {
Expand All @@ -31,12 +30,10 @@ const executeGitCommandBase = (cwd: string, args?: string[], token?: vscode.Canc
let err: Buffer = Buffer.from('', 'utf-8');

proc.stdout.on('data', (chunk) => {
// console.log('[exec stdout] ', chunk.toString());
out = Buffer.concat([out, chunk]);
logger.trace(chunk.toString());
});
proc.stderr.on('data', (chunk) => {
// console.log('[exec stderr] ', chunk.toString());
err = Buffer.concat([err, chunk]);
logger.error(chunk.toString());
});
Expand All @@ -46,11 +43,9 @@ const executeGitCommandBase = (cwd: string, args?: string[], token?: vscode.Canc
treeKill(proc.pid, 'SIGTERM');
}
});
proc.on('error', reject);
proc.on('close', (code, signal) => {
proc.once('error', reject);
proc.once('close', (code, signal) => {
logger.trace('[exec close] ', code, signal);
// console.log('[exec stdout] ', out.toString());
// console.log('[exec stderr] ', err.toString());
if (signal === 'SIGTERM') {
return resolve('');
}
Expand Down Expand Up @@ -100,14 +95,18 @@ export function getNameRev(cwd: string) {
export async function getWorkTreeList(root?: string, skipRemote?: boolean): Promise<IWorkTreeDetail[]> {
let cwd = root || folderRoot.uri?.fsPath || '';
try {
const [output, mainFolderFull, remoteBranchOutput] = await Promise.all([
const [output, mainFolderFull, remoteBranchOutput, branchList] = await Promise.all([
executeGitCommandBase(cwd, ['worktree', 'list', '--porcelain']),
executeGitCommandBase(cwd, ['rev-parse', '--path-format=absolute', '--git-common-dir']),
skipRemote ? Promise.resolve('') : executeGitCommandBase(cwd, ['remote']),
skipRemote ? Promise.resolve([]) : getAllRefList(['refname']),
]);

const mainFolder = mainFolderFull.replace('/.git', '');
const [remoteName] = remoteBranchOutput.split('\n');
const remoteBranchMap = new Map(
branchList.filter((item) => item.refname.startsWith('refs/remotes/')).map((item) => [item.refname, true]),
);
let list = output
.split('\n')
.reduce<string[][]>(
Expand Down Expand Up @@ -135,8 +134,15 @@ export async function getWorkTreeList(root?: string, skipRemote?: boolean): Prom
(list as unknown as IWorkTreeOutputItem[]).map(async (item) => {
const branchName = item.branch?.replace('refs/heads/', '') || '';
const [aheadBehind, nameRev] = await Promise.all([
!skipRemote && branchName && remoteName
? getAheadBehindCommitCount(branchName, `refs/remotes/${remoteName}/${branchName}`, item.worktree)
!skipRemote &&
branchName &&
remoteName &&
remoteBranchMap.has(`refs/remotes/${remoteName}/${branchName}`)
? getAheadBehindCommitCount(
branchName,
`refs/remotes/${remoteName}/${branchName}`,
item.worktree,
)
: Promise.resolve(void 0),
!branchName ? getNameRev(item.worktree) : Promise.resolve(''),
]);
Expand Down Expand Up @@ -234,6 +240,19 @@ export async function getTagList<T extends string>(keys: T[], cwd?: string) {
}
}

export async function getAllRefList<T extends string>(keys: T[], cwd?: string) {
try {
let output = await executeGitCommandAuto(cwd, [
'for-each-ref',
`--format=${formatQuery(keys)}`,
'--sort=-committerdate',
]);
return parseOutput(output, keys);
} catch {
return [];
}
}

export async function getRemoteList(cwd: string) {
try {
let output = await executeGitCommandAuto(cwd, ['remote', '-v']);
Expand Down

0 comments on commit 273a01b

Please sign in to comment.