/
raiden
/
obsidian-git-encrypt
Обзор
Документация
Войти
/
raiden
/
obsidian-git-encrypt
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/git/gitProcess.ts
113 строк
3 KB
Robert Kuzhin
feat: add manual encrypted source control
09 авг 2026, 20:57
09 авг 2026, 20:57
3c8fa38
Код
Авторство
О чём код?
import { spawn } from "node:child_process"; import { GitAdapterError } from "./errors.js"; const DEFAULT_TIMEOUT_MS = 5 * 60 * 1000; const MAX_OUTPUT_BYTES = 64 * 1024 * 1024; const REPOSITORY_REDIRECTION_VARIABLES = [ "GIT_ALTERNATE_OBJECT_DIRECTORIES", "GIT_COMMON_DIR", "GIT_CEILING_DIRECTORIES", "GIT_CONFIG", "GIT_CONFIG_COUNT", "GIT_CONFIG_GLOBAL", "GIT_CONFIG_NOSYSTEM", "GIT_CONFIG_PARAMETERS", "GIT_CONFIG_SYSTEM", "GIT_DIR", "GIT_DISCOVERY_ACROSS_FILESYSTEM", "GIT_EXEC_PATH", "GIT_GRAFT_FILE", "GIT_INDEX_FILE", "GIT_NAMESPACE", "GIT_OBJECT_DIRECTORY", "GIT_PREFIX", "GIT_QUARANTINE_PATH", "GIT_SHALLOW_FILE", "GIT_TEMPLATE_DIR", "GIT_WORK_TREE", ] as const; export interface GitProcessResult { readonly exitCode: number | null; readonly stdout: Buffer; readonly stderr: Buffer; } export function runGitProcess( cwd: string, args: readonly string[], timeoutMs = DEFAULT_TIMEOUT_MS, stdin?: Uint8Array, ): Promise<GitProcessResult> { return new Promise((resolve, reject) => { const child = spawn("git", [...args], { cwd, shell: false, stdio: [stdin === undefined ? "ignore" : "pipe", "pipe", "pipe"], env: createGitEnvironment(process.env), }); const stdout: Buffer[] = []; const stderr: Buffer[] = []; let outputBytes = 0; let settled = false; const timeout = setTimeout(() => { child.kill("SIGKILL"); if (!settled) { settled = true; reject(new GitAdapterError("Git command timed out")); } }, timeoutMs); const collect = (target: Buffer[], chunk: Buffer): void => { outputBytes += chunk.length; if (outputBytes > MAX_OUTPUT_BYTES) { child.kill("SIGKILL"); if (!settled) { settled = true; clearTimeout(timeout); reject(new GitAdapterError("Git command exceeded its output limit")); } return; } target.push(chunk); }; child.stdout!.on("data", (chunk: Buffer) => collect(stdout, chunk)); child.stderr!.on("data", (chunk: Buffer) => collect(stderr, chunk)); if (stdin !== undefined && child.stdin !== null) { child.stdin.end(Buffer.from(stdin)); } child.on("error", (error) => { if (!settled) { settled = true; clearTimeout(timeout); reject(new GitAdapterError("Unable to start Git", { cause: error })); } }); child.on("close", (exitCode) => { if (!settled) { settled = true; clearTimeout(timeout); resolve({ exitCode, stdout: Buffer.concat(stdout), stderr: Buffer.concat(stderr) }); } }); }); } export function createGitEnvironment(input: NodeJS.ProcessEnv): NodeJS.ProcessEnv { const environment = { ...input }; for (const name of REPOSITORY_REDIRECTION_VARIABLES) delete environment[name]; for (const name of Object.keys(environment)) { if ( /^GIT_CONFIG_(?:KEY|VALUE)_\d+$/u.test(name) || /^GIT_TRACE(?:2|_)/u.test(name) || name === "GIT_TRACE" ) { delete environment[name]; } } environment.GIT_NO_REPLACE_OBJECTS = "1"; environment.GIT_TERMINAL_PROMPT = "0"; environment.LC_ALL = "C"; return environment; }