Skip to content

Commit dcdd34f

Browse files
committed
Add git root directory support to Git functions
Introduce getGitRootDir function to consistently determine the Git root directory for executing Git commands. This change modifies existing Git utility functions to use the -C flag with the root directory, ensuring that all operations execute in the correct repository context, which enhances reliability when scripts are run from subdirectories. Release-Note: Add support for executing Git commands from any subdirectory within a repository Signed-off-by: Ian Skelskey <[email protected]>
1 parent a7d6a26 commit dcdd34f

File tree

1 file changed

+36
-14
lines changed

1 file changed

+36
-14
lines changed

src/util/git.ts

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ export enum GitFileStatus {
1414
'!' = 'Ignored',
1515
}
1616

17+
export function getGitRootDir(): string {
18+
try {
19+
return execSync('git rev-parse --show-toplevel', { encoding: 'utf-8' }).trim();
20+
} catch (error) {
21+
throw new Error('Unable to determine git repository root directory.');
22+
}
23+
}
24+
1725
export function isInGitRepo(): boolean {
1826
try {
1927
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
@@ -25,7 +33,8 @@ export function isInGitRepo(): boolean {
2533

2634
export function pushChanges(): void {
2735
try {
28-
execSync('git push');
36+
const gitRoot = getGitRootDir();
37+
execSync(`git -C "${gitRoot}" push`);
2938
} catch (error: any) {
3039
if (error.message.includes('fatal: The current branch')) {
3140
throw new Error('The current branch has no upstream branch.');
@@ -43,35 +52,42 @@ export function setUserEmail(email: string): void {
4352

4453
export function setupUpstreamBranch(): void {
4554
const branchName = getCurrentBranchName();
46-
execSync(`git push --set-upstream origin ${branchName}`);
55+
const gitRoot = getGitRootDir();
56+
execSync(`git -C "${gitRoot}" push --set-upstream origin ${branchName}`);
4757
}
4858

4959
export function stageAllFiles(): void {
50-
execSync('git add .');
60+
const gitRoot = getGitRootDir();
61+
execSync(`git -C "${gitRoot}" add .`);
5162
}
5263

5364
export function stageFile(filePath: string): void {
54-
execSync(`git add ${filePath}`);
65+
const gitRoot = getGitRootDir();
66+
execSync(`git -C "${gitRoot}" add "${filePath}"`);
5567
}
5668

5769
export function unstageFile(filePath: string): void {
58-
execSync(`git restore --staged ${filePath}`);
70+
const gitRoot = getGitRootDir();
71+
execSync(`git -C "${gitRoot}" restore --staged "${filePath}"`);
5972
}
6073

6174
export function unstageAllFiles(): void {
62-
execSync('git restore --staged .');
75+
const gitRoot = getGitRootDir();
76+
execSync(`git -C "${gitRoot}" restore --staged .`);
6377
}
6478

6579
export function listChangedFiles(): string[] {
66-
const statusOutput = execSync('git status --porcelain').toString().trim();
80+
const gitRoot = getGitRootDir();
81+
const statusOutput = execSync(`git -C "${gitRoot}" status --porcelain`).toString().trim();
6782
return statusOutput
6883
.split('\n')
6984
.map((line) => line.trim().slice(2))
7085
.filter(Boolean);
7186
}
7287

7388
export function getStatusForFile(filePath: string): GitFileStatus {
74-
const status = execSync(`git status --porcelain "${filePath}"`).toString().trim();
89+
const gitRoot = getGitRootDir();
90+
const status = execSync(`git -C "${gitRoot}" status --porcelain "${filePath}"`).toString().trim();
7591
if (!status) {
7692
return GitFileStatus['!'];
7793
}
@@ -81,7 +97,8 @@ export function getStatusForFile(filePath: string): GitFileStatus {
8197
export function getDiffForStagedFiles(): string {
8298
const maxBufferSize = 10 * 1024 * 1024; // 10 MB buffer
8399
try {
84-
let diff: string = execSync('git diff --staged', { maxBuffer: maxBufferSize }).toString();
100+
const gitRoot = getGitRootDir();
101+
let diff: string = execSync(`git -C "${gitRoot}" diff --staged`, { maxBuffer: maxBufferSize }).toString();
85102
diff = removeDiffForFile(diff, 'package-lock.json');
86103
return diff;
87104
} catch (error: any) {
@@ -102,7 +119,8 @@ function removeDiffForFile(diff: string, filePath: string): string {
102119

103120
export function getCurrentBranchName(): string {
104121
try {
105-
const branchName = execSync('git rev-parse --abbrev-ref HEAD', {
122+
const gitRoot = getGitRootDir();
123+
const branchName = execSync(`git -C "${gitRoot}" rev-parse --abbrev-ref HEAD`, {
106124
encoding: 'utf-8',
107125
}).trim();
108126

@@ -113,7 +131,8 @@ export function getCurrentBranchName(): string {
113131
}
114132

115133
export function hasGitChanges(): boolean {
116-
const status = execSync('git status --porcelain').toString().trim();
134+
const gitRoot = getGitRootDir();
135+
const status = execSync(`git -C "${gitRoot}" status --porcelain`).toString().trim();
117136
return status.length > 0;
118137
}
119138

@@ -126,11 +145,12 @@ export function getEmail(): string {
126145
}
127146

128147
export function commitWithMessage(message: string): void {
148+
const gitRoot = getGitRootDir();
129149
const sanitizedMessage = sanitizeCommitMessage(message);
130150
const tempFilePath = path.join(os.tmpdir(), 'commit-message.txt');
131151

132152
fs.writeFileSync(tempFilePath, sanitizedMessage);
133-
execSync(`git commit -F "${tempFilePath}"`);
153+
execSync(`git -C "${gitRoot}" commit -F "${tempFilePath}"`);
134154
fs.unlinkSync(tempFilePath); // Clean up the temporary file
135155
}
136156

@@ -139,12 +159,14 @@ function sanitizeCommitMessage(message: string): string {
139159
}
140160

141161
export function checkForRemote(remoteUrl: string): boolean {
142-
const remoteUrls = execSync('git remote -v').toString();
162+
const gitRoot = getGitRootDir();
163+
const remoteUrls = execSync(`git -C "${gitRoot}" remote -v`).toString();
143164
return remoteUrls.includes(remoteUrl);
144165
}
145166

146167
export function getRemoteName(remoteUrl: string): string {
147-
const remoteUrls = execSync('git remote -v').toString();
168+
const gitRoot = getGitRootDir();
169+
const remoteUrls = execSync(`git -C "${gitRoot}" remote -v`).toString();
148170
const remoteName = remoteUrls.split('\n').find((line: string) => line.includes(remoteUrl));
149171
return remoteName ? remoteName.split('\t')[0] : '';
150172
}

0 commit comments

Comments
 (0)