Skip to content

Commit fe295eb

Browse files
committed
Properly handle Git worktrees
1 parent 480e743 commit fe295eb

9 files changed

Lines changed: 106 additions & 82 deletions

File tree

apps/rush-lib/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
"@yarnpkg/lockfile": "~1.0.2",
3131
"builtins": "~1.0.3",
3232
"colors": "~1.2.1",
33-
"git-repo-info": "~1.1.4",
33+
"git-repo-info": "~2.1.0",
3434
"glob": "~7.0.5",
3535
"glob-escape": "~0.0.1",
3636
"https-proxy-agent": "~2.2.1",

apps/rush-lib/src/api/ChangeFile.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
// See LICENSE in the project root for license information.
33

44
import * as path from 'path';
5-
import gitInfo = require('git-repo-info');
65

76
import { JsonFile } from '@microsoft/node-core-library';
87

@@ -11,6 +10,7 @@ import {
1110
IChangeFile,
1211
IChangeInfo
1312
} from './ChangeManagement';
13+
import { Git } from '../logic/Git';
1414

1515
/**
1616
* This class represents a single change file.
@@ -81,7 +81,7 @@ export class ChangeFile {
8181
public generatePath(): string {
8282
let branch: string | undefined = undefined;
8383
try {
84-
branch = gitInfo().branch;
84+
branch = Git.getGitInfo()!.branch;
8585
} catch (error) {
8686
console.log('Could not automatically detect git branch name, using timestamp instead.');
8787
}

apps/rush-lib/src/logic/Git.ts

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import gitInfo = require('git-repo-info');
55
import * as os from 'os';
6+
import * as path from 'path';
67
import { Executable } from '@microsoft/node-core-library';
78

89
import { Utilities } from '../utilities/Utilities';
@@ -18,6 +19,8 @@ interface IResultOrError<TResult> {
1819
export class Git {
1920
private static _checkedGitPath: boolean = false;
2021
private static _gitPath: string | undefined;
22+
private static _checkedGitInfo: boolean = false;
23+
private static _gitInfo: gitInfo.GitRepoInfo | undefined;
2124

2225
private static _gitEmailResult: IResultOrError<string> | undefined = undefined;
2326

@@ -42,11 +45,16 @@ export class Git {
4245

4346
/**
4447
* Returns true if the Git binary was found and the current path is under a Git working tree.
48+
* @param repoInfo - If provided, do the check based on this Git repo info. If not provided,
49+
* the result of `Git.getGitInfo()` is used.
4550
*/
46-
public static isPathUnderGitWorkingTree(): boolean {
51+
public static isPathUnderGitWorkingTree(repoInfo?: gitInfo.GitRepoInfo): boolean {
4752
if (Git.isGitPresent()) { // Do we even have a Git binary?
4853
try {
49-
return !!gitInfo().sha;
54+
if (!repoInfo) {
55+
repoInfo = Git.getGitInfo();
56+
}
57+
return !!repoInfo!.sha;
5058
} catch (e) {
5159
return false; // Unexpected, but possible if the .git directory is corrupted.
5260
}
@@ -104,6 +112,37 @@ export class Git {
104112
return emailResult.result;
105113
}
106114

115+
/**
116+
* Get the folder where Git hooks should go for the current working tree.
117+
* Returns undefined if the current path is not under a Git working tree.
118+
*/
119+
public static getHooksFolder(): string | undefined {
120+
const repoInfo: gitInfo.GitRepoInfo | undefined = Git.getGitInfo();
121+
if (repoInfo && repoInfo.worktreeGitDir) {
122+
return path.join(repoInfo.worktreeGitDir, 'hooks');
123+
}
124+
return undefined;
125+
}
126+
127+
/**
128+
* Get information about the current Git working tree.
129+
* Returns undefined if the current path is not under a Git working tree.
130+
*/
131+
public static getGitInfo(): Readonly<gitInfo.GitRepoInfo> | undefined {
132+
if (!Git._checkedGitInfo) {
133+
try {
134+
const repoInfo: gitInfo.GitRepoInfo = gitInfo();
135+
if (Git.isPathUnderGitWorkingTree(repoInfo)) {
136+
Git._gitInfo = repoInfo;
137+
}
138+
} catch (ex) {
139+
// ignore
140+
}
141+
Git._checkedGitInfo = true;
142+
}
143+
return Git._gitInfo;
144+
}
145+
107146
private static _tryGetGitEmail(): IResultOrError<string> {
108147
if (Git._gitEmailResult === undefined) {
109148
if (!Git.isGitPresent()) {

apps/rush-lib/src/logic/InstallManager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import {
2020
FileSystem,
2121
FileConstants,
2222
Sort,
23-
FolderConstants,
2423
PosixModeBits
2524
} from '@microsoft/node-core-library';
2625

@@ -30,6 +29,7 @@ import { BaseLinkManager } from '../logic/base/BaseLinkManager';
3029
import { BaseShrinkwrapFile } from '../logic/base/BaseShrinkwrapFile';
3130
import { PolicyValidator } from '../logic/policy/PolicyValidator';
3231
import { IRushTempPackageJson } from '../logic/base/BasePackage';
32+
import { Git } from '../logic/Git';
3333
import { LastInstallFlag } from '../api/LastInstallFlag';
3434
import { LinkManagerFactory } from '../logic/LinkManagerFactory';
3535
import { PurgeManager } from './PurgeManager';
@@ -272,9 +272,9 @@ export class InstallManager {
272272

273273
// Git hooks are only installed if the repo opts in by including files in /common/git-hooks
274274
const hookSource: string = path.join(this._rushConfiguration.commonFolder, 'git-hooks');
275-
const hookDestination: string = path.join(this._rushConfiguration.rushJsonFolder, FolderConstants.Git, 'hooks');
275+
const hookDestination: string | undefined = Git.getHooksFolder();
276276

277-
if (FileSystem.exists(hookSource)) {
277+
if (FileSystem.exists(hookSource) && hookDestination) {
278278
const hookFilenames: Array<string> = FileSystem.readFolder(hookSource);
279279
if (hookFilenames.length > 0) {
280280
console.log(os.EOL + colors.bold('Found files in the "common/git-hooks" folder.'));

apps/rush-lib/typings/git-repo-info/git-repo-info.d.ts

Lines changed: 0 additions & 27 deletions
This file was deleted.

apps/rush-lib/typings/tsd.d.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
22
// See LICENSE in the project root for license information.
33

4-
/// <reference path="git-repo-info/git-repo-info.d.ts" />
54
/// <reference path="builtins/builtins.d.ts" />
65
/// <reference path="glob-escape/glob-escape.d.ts" />
76
/// <reference path="npm-package-arg/npm-package-arg.d.ts" />

build-tests/api-extractor-test-05/etc/api-extractor-test-05.api.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"metadata": {
33
"toolPackage": "@microsoft/api-extractor",
4-
"toolVersion": "7.0.3",
4+
"toolVersion": "7.0.4",
55
"schemaVersion": 1000
66
},
77
"kind": "Package",
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"changes": [
3+
{
4+
"comment": "Properly handle Git worktrees",
5+
"packageName": "@microsoft/rush",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@microsoft/rush",
10+
"email": "ecraig12345@users.noreply.github.com"
11+
}

0 commit comments

Comments
 (0)