@pnpm/network.git-utils 1100.0.0 → 1100.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/lib/index.d.ts +7 -4
- package/lib/index.js +60 -9
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
# @pnpm/git-utils
|
|
1
|
+
# @pnpm/network.git-utils
|
|
2
2
|
|
|
3
3
|
> Utilities for git
|
|
4
4
|
|
|
5
5
|
<!--@shields('npm')-->
|
|
6
|
-
[](https://
|
|
6
|
+
[](https://npmx.dev/package/@pnpm/network.git-utils)
|
|
7
7
|
<!--/@-->
|
|
8
8
|
|
|
9
9
|
## Installation
|
|
10
10
|
|
|
11
11
|
```
|
|
12
|
-
pnpm add @pnpm/git-utils
|
|
12
|
+
pnpm add @pnpm/network.git-utils
|
|
13
13
|
```
|
|
14
14
|
|
|
15
15
|
## Usage
|
package/lib/index.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
export declare function
|
|
1
|
+
export interface GitCwdOptions {
|
|
2
|
+
cwd?: string;
|
|
3
|
+
}
|
|
4
|
+
export declare function isGitRepo(opts?: GitCwdOptions): Promise<boolean>;
|
|
5
|
+
export declare function getCurrentBranch(opts?: GitCwdOptions): Promise<string | null>;
|
|
6
|
+
export declare function isWorkingTreeClean(opts?: GitCwdOptions): Promise<boolean>;
|
|
7
|
+
export declare function isRemoteHistoryClean(opts?: GitCwdOptions): Promise<boolean>;
|
package/lib/index.js
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
1
3
|
import { safeExeca as execa } from 'execa';
|
|
2
|
-
|
|
3
|
-
export async function isGitRepo() {
|
|
4
|
+
export async function isGitRepo(opts = {}) {
|
|
4
5
|
try {
|
|
5
|
-
await execa('git', ['rev-parse', '--git-dir']);
|
|
6
|
+
await execa('git', ['rev-parse', '--git-dir'], { cwd: opts.cwd });
|
|
6
7
|
}
|
|
7
8
|
catch {
|
|
8
9
|
return false;
|
|
9
10
|
}
|
|
10
11
|
return true;
|
|
11
12
|
}
|
|
12
|
-
export async function getCurrentBranch() {
|
|
13
|
+
export async function getCurrentBranch(opts = {}) {
|
|
14
|
+
const branch = readBranchFromHeadFile(opts.cwd);
|
|
15
|
+
if (branch !== undefined)
|
|
16
|
+
return branch;
|
|
13
17
|
try {
|
|
14
|
-
const { stdout } = await execa('git', ['symbolic-ref', '--short', 'HEAD']);
|
|
18
|
+
const { stdout } = await execa('git', ['symbolic-ref', '--short', 'HEAD'], { cwd: opts.cwd });
|
|
15
19
|
return stdout;
|
|
16
20
|
}
|
|
17
21
|
catch {
|
|
@@ -19,9 +23,9 @@ export async function getCurrentBranch() {
|
|
|
19
23
|
return null;
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
|
-
export async function isWorkingTreeClean() {
|
|
26
|
+
export async function isWorkingTreeClean(opts = {}) {
|
|
23
27
|
try {
|
|
24
|
-
const { stdout: status } = await execa('git', ['status', '--porcelain']);
|
|
28
|
+
const { stdout: status } = await execa('git', ['status', '--porcelain'], { cwd: opts.cwd });
|
|
25
29
|
if (status !== '') {
|
|
26
30
|
return false;
|
|
27
31
|
}
|
|
@@ -31,10 +35,10 @@ export async function isWorkingTreeClean() {
|
|
|
31
35
|
return false;
|
|
32
36
|
}
|
|
33
37
|
}
|
|
34
|
-
export async function isRemoteHistoryClean() {
|
|
38
|
+
export async function isRemoteHistoryClean(opts = {}) {
|
|
35
39
|
let history;
|
|
36
40
|
try { // Gracefully handle no remote set up.
|
|
37
|
-
const { stdout } = await execa('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD']);
|
|
41
|
+
const { stdout } = await execa('git', ['rev-list', '--count', '--left-only', '@{u}...HEAD'], { cwd: opts.cwd });
|
|
38
42
|
history = stdout;
|
|
39
43
|
}
|
|
40
44
|
catch {
|
|
@@ -45,4 +49,51 @@ export async function isRemoteHistoryClean() {
|
|
|
45
49
|
}
|
|
46
50
|
return true;
|
|
47
51
|
}
|
|
52
|
+
/**
|
|
53
|
+
* Reads the current branch name from `.git/HEAD` without spawning a git subprocess.
|
|
54
|
+
*
|
|
55
|
+
* Returns:
|
|
56
|
+
* - `string` — the branch name extracted from `ref: refs/heads/<name>`
|
|
57
|
+
* - `null` — HEAD is detached (a raw commit SHA, not a symbolic ref)
|
|
58
|
+
* - `undefined` — `.git/HEAD` could not be read (not a git repo, worktree
|
|
59
|
+
* layout not recognized, permissions error, etc.); caller should fall
|
|
60
|
+
* back to `git symbolic-ref`.
|
|
61
|
+
*/
|
|
62
|
+
function readBranchFromHeadFile(cwd) {
|
|
63
|
+
const baseDir = cwd ?? process.cwd();
|
|
64
|
+
const dotGitPath = path.join(baseDir, '.git');
|
|
65
|
+
let gitDir;
|
|
66
|
+
try {
|
|
67
|
+
const stat = fs.statSync(dotGitPath);
|
|
68
|
+
if (stat.isDirectory()) {
|
|
69
|
+
gitDir = dotGitPath;
|
|
70
|
+
}
|
|
71
|
+
else if (stat.isFile()) {
|
|
72
|
+
// `.git` is a file — worktree or submodule. It contains `gitdir: <path>`.
|
|
73
|
+
const content = fs.readFileSync(dotGitPath, 'utf8').trim();
|
|
74
|
+
const match = content.match(/^gitdir:\s*(.+)/);
|
|
75
|
+
if (!match)
|
|
76
|
+
return undefined;
|
|
77
|
+
gitDir = path.isAbsolute(match[1]) ? match[1] : path.resolve(baseDir, match[1]);
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
// `.git` is neither a directory nor a regular file (e.g. a FIFO or
|
|
81
|
+
// device); don't read it. Fall back to `git symbolic-ref`.
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
catch {
|
|
86
|
+
return undefined;
|
|
87
|
+
}
|
|
88
|
+
try {
|
|
89
|
+
const head = fs.readFileSync(path.join(gitDir, 'HEAD'), 'utf8').trim();
|
|
90
|
+
const match = head.match(/^ref:\s*refs\/heads\/(.+)/);
|
|
91
|
+
if (match)
|
|
92
|
+
return match[1];
|
|
93
|
+
return null;
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
48
99
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pnpm/network.git-utils",
|
|
3
|
-
"version": "1100.0.
|
|
3
|
+
"version": "1100.0.2",
|
|
4
4
|
"description": "Utilities for git",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pnpm",
|
|
@@ -10,7 +10,10 @@
|
|
|
10
10
|
],
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"funding": "https://opencollective.com/pnpm",
|
|
13
|
-
"repository":
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/pnpm/pnpm/tree/main/network/git-utils"
|
|
16
|
+
},
|
|
14
17
|
"homepage": "https://github.com/pnpm/pnpm/tree/main/network/git-utils#readme",
|
|
15
18
|
"bugs": {
|
|
16
19
|
"url": "https://github.com/pnpm/pnpm/issues"
|
|
@@ -29,8 +32,9 @@
|
|
|
29
32
|
"execa": "npm:safe-execa@0.3.0"
|
|
30
33
|
},
|
|
31
34
|
"devDependencies": {
|
|
35
|
+
"@jest/globals": "30.4.1",
|
|
32
36
|
"tempy": "3.0.0",
|
|
33
|
-
"@pnpm/network.git-utils": "1100.0.
|
|
37
|
+
"@pnpm/network.git-utils": "1100.0.2"
|
|
34
38
|
},
|
|
35
39
|
"engines": {
|
|
36
40
|
"node": ">=22.13"
|