MCPcopy Create free account
hub / github.com/Fibi66/FeiControl / getRepoStatus

Function getRepoStatus

src/app/api/git/route.ts:35–115  ·  view source on GitHub ↗
(repoPath: string)

Source from the content-addressed store, hash-verified

33}
34
35async function getRepoStatus(repoPath: string): Promise<RepoStatus> {
36 const name = repoPath.split('/').pop() || repoPath;
37
38 try {
39 // Get branch
40 const { stdout: branch } = await execAsync(`cd "${repoPath}" && git rev-parse --abbrev-ref HEAD 2>/dev/null`).catch(() => ({ stdout: 'unknown' }));
41
42 // Get ahead/behind
43 let ahead = 0, behind = 0;
44 try {
45 const { stdout: abStr } = await execAsync(`cd "${repoPath}" && git rev-list --left-right --count HEAD...@{upstream} 2>/dev/null`).catch(() => ({ stdout: '0\t0' }));
46 const parts = abStr.trim().split('\t');
47 ahead = parseInt(parts[0]) || 0;
48 behind = parseInt(parts[1]) || 0;
49 } catch {}
50
51 // Get status
52 const { stdout: statusOut } = await execAsync(`cd "${repoPath}" && git status --porcelain 2>/dev/null`).catch(() => ({ stdout: '' }));
53 const lines = statusOut.trim().split('\n').filter(Boolean);
54
55 const staged: string[] = [];
56 const unstaged: string[] = [];
57 const untracked: string[] = [];
58
59 for (const line of lines) {
60 const xy = line.slice(0, 2);
61 const file = line.slice(3);
62 const x = xy[0]; // staged
63 const y = xy[1]; // unstaged
64
65 if (x !== ' ' && x !== '?') staged.push(file);
66 if (y !== ' ' && y !== '?') unstaged.push(file);
67 if (xy === '??') untracked.push(file);
68 }
69
70 // Last commit
71 let lastCommit = null;
72 try {
73 const { stdout: commitOut } = await execAsync(`cd "${repoPath}" && git log -1 --format="%H|%s|%an|%ar" 2>/dev/null`);
74 const parts = commitOut.trim().split('|');
75 if (parts.length >= 4) {
76 lastCommit = { hash: parts[0].slice(0, 8), message: parts[1], author: parts[2], date: parts[3] };
77 }
78 } catch {}
79
80 // Remote URL
81 let remoteUrl = '';
82 try {
83 const { stdout: remote } = await execAsync(`cd "${repoPath}" && git remote get-url origin 2>/dev/null`);
84 remoteUrl = remote.trim();
85 } catch {}
86
87 return {
88 name,
89 path: repoPath,
90 branch: branch.trim(),
91 ahead,
92 behind,

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected