vscode-git插件代码研究
vscode-git插件代码研究
- 所有的git命令都是通过stream方法调用,用于记录所有git操作相关的命令记录,以及时间消耗
1 2 3 4 5 6 7 8 9 10 11 12 13
stream(cwd: string, args: string[], options: SpawnOptions = {}): cp.ChildProcess { options = assign({ cwd }, options || {}); const child = this.spawn(args, options); if (options.log !== false) { const startTime = Date.now(); child.on('exit', (_) => { this.log(`> git ${args.join(' ')} [${Date.now() - startTime}ms]${child.killed ? ' (cancelled)' : ''}\n`); }); } return child; }
- 日志输出通过eventEmitter,在内部打印日志,在最上层输出日志
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
// 最上层 const onOutput = (str: string) => { const lines = str.split(/\r?\n/mg); while (/^\s*$/.test(lines[lines.length - 1])) { lines.pop(); } logger.appendLine(lines.join('\n')); }; git.onOutput.addListener('log', onOutput); disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput))); // 内部定义output private _onOutput = new EventEmitter(); get onOutput(): EventEmitter { return this._onOutput; } // 内部使用log private log(output: string): void { this._onOutput.emit('log', output); } this.log(`> git ${args.join(' ')} [${Date.now() - startTime}ms]${child.killed ? ' (cancelled)' : ''}\n`);
- 在执行git相关命令后,返回的结果中必定包含GitErrorCode,建立错误码机制,以了解到底是因为什么导致Git错误
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
function getGitErrorCode(stderr: string): string | undefined { if (/Another git process seems to be running in this repository|If no other git process is currently running/.test(stderr)) { return GitErrorCodes.RepositoryIsLocked; } else if (/Authentication failed/i.test(stderr)) { return GitErrorCodes.AuthenticationFailed; } else if (/Not a git repository/i.test(stderr)) { return GitErrorCodes.NotAGitRepository; } else if (/bad config file/.test(stderr)) { return GitErrorCodes.BadConfigFile; } else if (/cannot make pipe for command substitution|cannot create standard input pipe/.test(stderr)) { return GitErrorCodes.CantCreatePipe; } else if (/Repository not found/.test(stderr)) { return GitErrorCodes.RepositoryNotFound; } else if (/unable to access/.test(stderr)) { return GitErrorCodes.CantAccessRemote; } else if (/branch '.+' is not fully merged/.test(stderr)) { return GitErrorCodes.BranchNotFullyMerged; } else if (/Couldn\'t find remote ref/.test(stderr)) { return GitErrorCodes.NoRemoteReference; } else if (/A branch named '.+' already exists/.test(stderr)) { return GitErrorCodes.BranchAlreadyExists; } else if (/'.+' is not a valid branch name/.test(stderr)) { return GitErrorCodes.InvalidBranchName; } else if (/Please,? commit your changes or stash them/.test(stderr)) { return GitErrorCodes.DirtyWorkTree; } return undefined; }
- assign函数,合并多个对象的值,如:
1 2 3 4 5 6 7 8 9 10 11 12 13
export function assign<T>(destination: T, ...sources: any[]): T { for (const source of sources) { Object.keys(source).forEach(key => (destination as any)[key] = source[key]); } return destination; } options.env = assign({}, process.env, this.env, options.env || {}, { VSCODE_GIT_COMMAND: args[0], LC_ALL: 'en_US.UTF-8', LANG: 'en_US.UTF-8', GIT_PAGER: 'cat' });
- 净化windows路径,将开头的大小变为小写 ```typescript function sanitizePath(path: string): string { return path.replace(/^([a-z]):\/i, (_, letter) =>
${letter.toUpperCase()}:\\);
} ```
本文由作者按照 CC BY 4.0 进行授权