@teambit/ci 1.0.485 → 1.0.487
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/ci.docs.mdx +344 -83
- package/commands/sync.cmd.ts +77 -0
- package/dist/ci.docs.mdx +344 -83
- package/dist/ci.main.runtime.d.ts +67 -6
- package/dist/ci.main.runtime.js +152 -25
- package/dist/ci.main.runtime.js.map +1 -1
- package/dist/commands/sync.cmd.d.ts +34 -0
- package/dist/commands/sync.cmd.js +57 -0
- package/dist/commands/sync.cmd.js.map +1 -0
- package/dist/git.d.ts +11 -1
- package/dist/git.js +11 -1
- package/dist/git.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.js +26 -1
- package/dist/index.js.map +1 -1
- package/dist/{preview-1785858957533.js → preview-1785883495880.js} +1 -1
- package/dist/sync/git-host-provider.d.ts +47 -0
- package/dist/sync/git-host-provider.js +54 -0
- package/dist/sync/git-host-provider.js.map +1 -0
- package/dist/sync/git-host-provider.spec.d.ts +1 -0
- package/dist/sync/git-host-provider.spec.js +171 -0
- package/dist/sync/git-host-provider.spec.js.map +1 -0
- package/dist/sync/git-ops.d.ts +171 -0
- package/dist/sync/git-ops.js +354 -0
- package/dist/sync/git-ops.js.map +1 -0
- package/dist/sync/git-ops.spec.d.ts +1 -0
- package/dist/sync/git-ops.spec.js +476 -0
- package/dist/sync/git-ops.spec.js.map +1 -0
- package/dist/sync/github-client.d.ts +79 -0
- package/dist/sync/github-client.js +198 -0
- package/dist/sync/github-client.js.map +1 -0
- package/dist/sync/github-client.spec.d.ts +1 -0
- package/dist/sync/github-client.spec.js +205 -0
- package/dist/sync/github-client.spec.js.map +1 -0
- package/dist/sync/init-scaffold.d.ts +40 -0
- package/dist/sync/init-scaffold.js +326 -0
- package/dist/sync/init-scaffold.js.map +1 -0
- package/dist/sync/init-scaffold.spec.d.ts +1 -0
- package/dist/sync/init-scaffold.spec.js +169 -0
- package/dist/sync/init-scaffold.spec.js.map +1 -0
- package/dist/sync/lane-sync-executor.d.ts +256 -0
- package/dist/sync/lane-sync-executor.js +1249 -0
- package/dist/sync/lane-sync-executor.js.map +1 -0
- package/dist/sync/lane-sync-executor.spec.d.ts +1 -0
- package/dist/sync/lane-sync-executor.spec.js +416 -0
- package/dist/sync/lane-sync-executor.spec.js.map +1 -0
- package/dist/sync/main-sync-executor.d.ts +62 -0
- package/dist/sync/main-sync-executor.js +305 -0
- package/dist/sync/main-sync-executor.js.map +1 -0
- package/dist/sync/sync-config.d.ts +83 -0
- package/dist/sync/sync-config.js +187 -0
- package/dist/sync/sync-config.js.map +1 -0
- package/dist/sync/sync-config.spec.d.ts +1 -0
- package/dist/sync/sync-config.spec.js +254 -0
- package/dist/sync/sync-config.spec.js.map +1 -0
- package/dist/sync/sync-orchestrator.d.ts +76 -0
- package/dist/sync/sync-orchestrator.js +396 -0
- package/dist/sync/sync-orchestrator.js.map +1 -0
- package/dist/sync/sync-orchestrator.spec.d.ts +1 -0
- package/dist/sync/sync-orchestrator.spec.js +155 -0
- package/dist/sync/sync-orchestrator.spec.js.map +1 -0
- package/dist/sync/sync-planner.d.ts +60 -0
- package/dist/sync/sync-planner.js +114 -0
- package/dist/sync/sync-planner.js.map +1 -0
- package/dist/sync/sync-planner.spec.d.ts +1 -0
- package/dist/sync/sync-planner.spec.js +210 -0
- package/dist/sync/sync-planner.spec.js.map +1 -0
- package/dist/sync/sync-state.d.ts +94 -0
- package/dist/sync/sync-state.js +178 -0
- package/dist/sync/sync-state.js.map +1 -0
- package/dist/sync/sync-state.spec.d.ts +1 -0
- package/dist/sync/sync-state.spec.js +271 -0
- package/dist/sync/sync-state.spec.js.map +1 -0
- package/dist/sync/workspace-lane.d.ts +13 -0
- package/dist/sync/workspace-lane.js +27 -0
- package/dist/sync/workspace-lane.js.map +1 -0
- package/package.json +20 -15
- package/sync/git-host-provider.spec.ts +197 -0
- package/sync/git-host-provider.ts +89 -0
- package/sync/git-ops.spec.ts +506 -0
- package/sync/git-ops.ts +334 -0
- package/sync/github-client.spec.ts +174 -0
- package/sync/github-client.ts +209 -0
- package/sync/init-scaffold.spec.ts +142 -0
- package/sync/init-scaffold.ts +340 -0
- package/sync/lane-sync-executor.spec.ts +389 -0
- package/sync/lane-sync-executor.ts +1363 -0
- package/sync/main-sync-executor.ts +321 -0
- package/sync/sync-config.spec.ts +283 -0
- package/sync/sync-config.ts +214 -0
- package/sync/sync-orchestrator.spec.ts +120 -0
- package/sync/sync-orchestrator.ts +386 -0
- package/sync/sync-planner.spec.ts +126 -0
- package/sync/sync-planner.ts +99 -0
- package/sync/sync-state.spec.ts +263 -0
- package/sync/sync-state.ts +176 -0
- package/sync/workspace-lane.ts +20 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Git primitives shared by the lane and main sync executors; each encodes a decision that must stay
|
|
3
|
+
* identical on both paths.
|
|
4
|
+
*/
|
|
5
|
+
/** paths the sync executors never treat as workspace content — see `cleanUntrackedScoped` */
|
|
6
|
+
export declare const SYNC_EXCLUDED_PATHS: string[];
|
|
7
|
+
/**
|
|
8
|
+
* How a raw git invocation is run, injectable so a helper whose whole content is its argv can be unit
|
|
9
|
+
* tested without a repository. Production always uses {@link realGitRaw}.
|
|
10
|
+
*/
|
|
11
|
+
export type GitArgsRunner = (args: string[]) => Promise<unknown>;
|
|
12
|
+
export declare const realGitRaw: GitArgsRunner;
|
|
13
|
+
/**
|
|
14
|
+
* Remove untracked files, leaving the local bit scope and installed packages alone. No `-x` (ignored
|
|
15
|
+
* files stay), and `.bit` / `node_modules` are excluded explicitly — without that, the clean deletes
|
|
16
|
+
* the local scope in a workspace whose `.gitignore` lacks Bit's block.
|
|
17
|
+
*/
|
|
18
|
+
export declare function cleanUntrackedScoped(run?: GitArgsRunner): Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* Refuse a branch name git would read as an option or reject as a ref. Not every branch reaching the
|
|
21
|
+
* checkout comes from validated config: the default branch is derived from the remote
|
|
22
|
+
* (`getDefaultBranchName`), so the primitive that builds the argv is where the guard belongs — every
|
|
23
|
+
* caller inherits it.
|
|
24
|
+
*/
|
|
25
|
+
export declare function assertCheckoutableBranch(branch: string): void;
|
|
26
|
+
/**
|
|
27
|
+
* Put the working tree on `branch` holding nothing but that commit's content, then make the workspace
|
|
28
|
+
* re-read the checked-out `.bitmap`. Order matters: `checkout -f` (leftover tracked changes must not
|
|
29
|
+
* abort the target), then the scoped clean (a forced checkout leaves untracked files in place, and
|
|
30
|
+
* every commit path stages with `-A`), then the reload so it reads the pristine tree. With
|
|
31
|
+
* `startPoint`, `-B` creates-or-resets the branch — refused when the local branch holds commits no
|
|
32
|
+
* remote contains, because moving it would orphan unpushed work; the predicate is remote containment,
|
|
33
|
+
* not start-point ancestry (a fully pushed tip loses nothing in either legitimate reset shape).
|
|
34
|
+
*/
|
|
35
|
+
export declare function checkoutPristine(branch: string, startPoint: string | undefined, reload: () => Promise<void>, run?: GitArgsRunner): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the branch exists locally. Judged by output, never by whether the call threw: simple-git's
|
|
38
|
+
* `raw` resolves with empty output on some non-zero exits instead of rejecting.
|
|
39
|
+
*/
|
|
40
|
+
export declare function localBranchExists(branch: string, run?: GitArgsRunner): Promise<boolean>;
|
|
41
|
+
/**
|
|
42
|
+
* `checkoutPristine` for the restore paths: a start point only when the branch is absent locally
|
|
43
|
+
* (detached-HEAD/single-branch checkouts) — passing `origin/<branch>` when it exists would `-B`-reset
|
|
44
|
+
* the developer's default branch and discard their unpushed commits.
|
|
45
|
+
*/
|
|
46
|
+
export declare function checkoutPristineRestore(branch: string, reload: () => Promise<void>, run?: GitArgsRunner): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Stage every change except `.bit` / `node_modules` (a bare `add -A` would commit the local scope when
|
|
49
|
+
* `.gitignore` lacks Bit's block). The `:(exclude)` pathspecs make git skip those trees instead of
|
|
50
|
+
* staging them for a reset to undo; `git add` refuses them when a named path IS ignored — the case where
|
|
51
|
+
* the traversal is already cheap — so the add-then-reset pair is the fallback. Both leave the same index,
|
|
52
|
+
* and `git reset -- <paths>` is a no-op for paths absent from it, so neither fallback command can fail.
|
|
53
|
+
*/
|
|
54
|
+
export declare function addAllExceptScopeAndModules(run?: GitArgsRunner): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Whether a `git status` path is one the sync executors never treat as workspace content. Applied
|
|
57
|
+
* everywhere a status is interpreted — otherwise `.bit`/`node_modules` files count as drift when
|
|
58
|
+
* `.gitignore` lacks Bit's block.
|
|
59
|
+
*/
|
|
60
|
+
export declare function isNonContentPath(path: string): boolean;
|
|
61
|
+
/**
|
|
62
|
+
* The refspec every sync fetch passes **explicitly**, overriding whatever `remote.origin.fetch` this
|
|
63
|
+
* checkout was configured with.
|
|
64
|
+
*/
|
|
65
|
+
export declare const ALL_HEADS_REFSPEC = "+refs/heads/*:refs/remotes/origin/*";
|
|
66
|
+
/**
|
|
67
|
+
* Fetch `origin` so every branch it has is available as `refs/remotes/origin/<branch>`. A bare fetch
|
|
68
|
+
* honours the checkout's configured `remote.origin.fetch`, which in a single-branch clone updates
|
|
69
|
+
* exactly one ref while enumeration (`ls-remote`) sees every branch; an explicit refspec overrides the
|
|
70
|
+
* config. Does not make shallow clones work — depth is a different axis.
|
|
71
|
+
*/
|
|
72
|
+
export declare function fetchRemoteHeads(run?: GitArgsRunner): Promise<void>;
|
|
73
|
+
/** Refspec that updates exactly one remote-tracking ref — a mid-run re-read of a single branch. */
|
|
74
|
+
export declare function singleHeadRefspec(branch: string): string;
|
|
75
|
+
/**
|
|
76
|
+
* `origin/<branch>`'s tip as the remote has it NOW: every other ref a run reads comes from one fetch at
|
|
77
|
+
* its start. Undefined when the branch is gone or unreadable — never a stale sha, because the answer
|
|
78
|
+
* decides whether a branch deletion is still safe.
|
|
79
|
+
*/
|
|
80
|
+
export declare function refetchBranchTip(branch: string, run?: GitArgsRunner): Promise<string | undefined>;
|
|
81
|
+
/**
|
|
82
|
+
* `git push` argv that deletes a remote branch only while its tip is still `expectedTipSha`. Full
|
|
83
|
+
* `:refs/heads/<b>` refspec so the branch name can never be read as an option; the lease makes the server
|
|
84
|
+
* itself refuse a racing update rather than lose it.
|
|
85
|
+
*/
|
|
86
|
+
export declare function deleteBranchArgs(branch: string, expectedTipSha: string): string[];
|
|
87
|
+
/**
|
|
88
|
+
* Whether a failed push was the lease refusing. The wording varies by git version and transport:
|
|
89
|
+
* "stale info" (client-side check), "is at X but expected Y" (receive-pack), and "incorrect old value
|
|
90
|
+
* provided" (the local/file transport, which is what CI's e2e remotes use). Over-matching is the safe
|
|
91
|
+
* direction — the only consequence is reporting a branch as kept rather than as a failed delete.
|
|
92
|
+
*/
|
|
93
|
+
export declare function isStaleLeaseRejection(message: string): boolean;
|
|
94
|
+
/** Whether `origin` has the given branch. Assumes a `git fetch` isn't required (uses `ls-remote`). */
|
|
95
|
+
export declare function branchExistsOnRemote(branch: string): Promise<boolean>;
|
|
96
|
+
/**
|
|
97
|
+
* Every branch `origin` has, by short name. `ls-remote` rather than `git branch -r` so the answer
|
|
98
|
+
* cannot be narrowed by the checkout's refspec or staleness.
|
|
99
|
+
*/
|
|
100
|
+
export declare function listRemoteBranches(): Promise<string[]>;
|
|
101
|
+
/**
|
|
102
|
+
* Is `maybeAncestor` reachable from `descendant` (true for identical commits)? Not `merge-base
|
|
103
|
+
* --is-ancestor`: it answers via the exit code, and simple-git's `raw` resolves on exit 1, so "not an
|
|
104
|
+
* ancestor" would read as yes. Throws when the commits share no history or a revision cannot resolve.
|
|
105
|
+
*/
|
|
106
|
+
export declare function isAncestor(maybeAncestor: string, descendant: string): Promise<boolean>;
|
|
107
|
+
/** The prefix `git symbolic-ref refs/remotes/origin/HEAD` puts in front of the default branch name. */
|
|
108
|
+
export declare const ORIGIN_HEAD_REF_PREFIX = "refs/remotes/origin/";
|
|
109
|
+
/**
|
|
110
|
+
* The default branch name out of `git symbolic-ref refs/remotes/origin/HEAD` output, or undefined for
|
|
111
|
+
* an unrecognised shape. Strips the prefix; never splits on `/` — branch names may contain slashes
|
|
112
|
+
* (`release/main`), and truncating would protect the wrong branch.
|
|
113
|
+
*/
|
|
114
|
+
export declare function parseOriginHeadRef(symbolicRefOutput: string): string | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* The default branch name out of `git ls-remote --symref origin HEAD` output, or undefined when no
|
|
117
|
+
* symref line is present (some servers omit it). Same slash discipline as {@link parseOriginHeadRef}.
|
|
118
|
+
*/
|
|
119
|
+
export declare function parseLsRemoteSymref(lsRemoteOutput: string): string | undefined;
|
|
120
|
+
/**
|
|
121
|
+
* The remote's own answer for its default branch. Unlike the local `origin/HEAD` symref or enumerating
|
|
122
|
+
* `origin/*`, this cannot be stale or narrowed — only unanswered (undefined hands on to the fallback).
|
|
123
|
+
*/
|
|
124
|
+
export declare function remoteHeadBranch(run?: GitArgsRunner): Promise<string | undefined>;
|
|
125
|
+
/**
|
|
126
|
+
* The git repository's root, or undefined outside a repo. A bit workspace is not necessarily the repo
|
|
127
|
+
* root, and GitHub only discovers workflows at `<repo>/.github/workflows`.
|
|
128
|
+
*/
|
|
129
|
+
export declare function gitRepoRoot(): Promise<string | undefined>;
|
|
130
|
+
/**
|
|
131
|
+
* Reading `git config`, injectable so the identity decision can be unit tested without a repository.
|
|
132
|
+
* There is deliberately no writer — see {@link resolveGitIdentity}.
|
|
133
|
+
*/
|
|
134
|
+
export type GitConfigIO = {
|
|
135
|
+
/** the configured value, or undefined when unset (or when git cannot answer) */
|
|
136
|
+
get(key: string): Promise<string | undefined>;
|
|
137
|
+
};
|
|
138
|
+
export declare const realGitConfigIO: GitConfigIO;
|
|
139
|
+
/**
|
|
140
|
+
* The identity the sync commits with when nothing else says otherwise. A contract: the scaffolded
|
|
141
|
+
* workflow templates (`init-scaffold.ts`) and the GitHub Action's defaults must carry the same pair,
|
|
142
|
+
* or the same repository commits under different authors depending on entry point.
|
|
143
|
+
*/
|
|
144
|
+
export declare const DEFAULT_GIT_USER_NAME = "bit-sync[bot]";
|
|
145
|
+
export declare const DEFAULT_GIT_USER_EMAIL = "bit-sync[bot]@users.noreply.github.com";
|
|
146
|
+
export type GitIdentity = {
|
|
147
|
+
name: string;
|
|
148
|
+
email: string;
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
151
|
+
* Who the sync commits as. Read-only on purpose: writing these keys into the repository's config
|
|
152
|
+
* would outlive the run and re-author the developer's own later commits as the bot. Precedence per
|
|
153
|
+
* key: configured git identity > `GIT_USER_NAME`/`GIT_USER_EMAIL` > default.
|
|
154
|
+
*/
|
|
155
|
+
export declare function resolveGitIdentity(io?: GitConfigIO, env?: NodeJS.ProcessEnv): Promise<GitIdentity>;
|
|
156
|
+
/** The `git -c` pair that applies an identity to ONE invocation, leaving the repo's config alone. */
|
|
157
|
+
export declare function identityArgs(identity: GitIdentity): string[];
|
|
158
|
+
export type IdentityDeps = {
|
|
159
|
+
run?: GitArgsRunner;
|
|
160
|
+
io?: GitConfigIO;
|
|
161
|
+
env?: NodeJS.ProcessEnv;
|
|
162
|
+
};
|
|
163
|
+
/**
|
|
164
|
+
* Run a git command that may author a commit. Every such command needs the identity — a fresh CI
|
|
165
|
+
* checkout has none, and git refuses to commit ("Please tell me who you are") without one.
|
|
166
|
+
*/
|
|
167
|
+
export declare function gitWithIdentity(args: string[], deps?: IdentityDeps): Promise<string>;
|
|
168
|
+
/** `git commit` under the sync identity; `extraArgs` carries flags such as `--allow-empty`. */
|
|
169
|
+
export declare function commitWithIdentity(message: string, opts?: IdentityDeps & {
|
|
170
|
+
extraArgs?: string[];
|
|
171
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.SYNC_EXCLUDED_PATHS = exports.ORIGIN_HEAD_REF_PREFIX = exports.DEFAULT_GIT_USER_NAME = exports.DEFAULT_GIT_USER_EMAIL = exports.ALL_HEADS_REFSPEC = void 0;
|
|
7
|
+
exports.addAllExceptScopeAndModules = addAllExceptScopeAndModules;
|
|
8
|
+
exports.assertCheckoutableBranch = assertCheckoutableBranch;
|
|
9
|
+
exports.branchExistsOnRemote = branchExistsOnRemote;
|
|
10
|
+
exports.checkoutPristine = checkoutPristine;
|
|
11
|
+
exports.checkoutPristineRestore = checkoutPristineRestore;
|
|
12
|
+
exports.cleanUntrackedScoped = cleanUntrackedScoped;
|
|
13
|
+
exports.commitWithIdentity = commitWithIdentity;
|
|
14
|
+
exports.deleteBranchArgs = deleteBranchArgs;
|
|
15
|
+
exports.fetchRemoteHeads = fetchRemoteHeads;
|
|
16
|
+
exports.gitRepoRoot = gitRepoRoot;
|
|
17
|
+
exports.gitWithIdentity = gitWithIdentity;
|
|
18
|
+
exports.identityArgs = identityArgs;
|
|
19
|
+
exports.isAncestor = isAncestor;
|
|
20
|
+
exports.isNonContentPath = isNonContentPath;
|
|
21
|
+
exports.isStaleLeaseRejection = isStaleLeaseRejection;
|
|
22
|
+
exports.listRemoteBranches = listRemoteBranches;
|
|
23
|
+
exports.localBranchExists = localBranchExists;
|
|
24
|
+
exports.parseLsRemoteSymref = parseLsRemoteSymref;
|
|
25
|
+
exports.parseOriginHeadRef = parseOriginHeadRef;
|
|
26
|
+
exports.realGitRaw = exports.realGitConfigIO = void 0;
|
|
27
|
+
exports.refetchBranchTip = refetchBranchTip;
|
|
28
|
+
exports.remoteHeadBranch = remoteHeadBranch;
|
|
29
|
+
exports.resolveGitIdentity = resolveGitIdentity;
|
|
30
|
+
exports.singleHeadRefspec = singleHeadRefspec;
|
|
31
|
+
function _bitError() {
|
|
32
|
+
const data = require("@teambit/bit-error");
|
|
33
|
+
_bitError = function () {
|
|
34
|
+
return data;
|
|
35
|
+
};
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
function _git() {
|
|
39
|
+
const data = require("../git");
|
|
40
|
+
_git = function () {
|
|
41
|
+
return data;
|
|
42
|
+
};
|
|
43
|
+
return data;
|
|
44
|
+
}
|
|
45
|
+
function _syncConfig() {
|
|
46
|
+
const data = require("./sync-config");
|
|
47
|
+
_syncConfig = function () {
|
|
48
|
+
return data;
|
|
49
|
+
};
|
|
50
|
+
return data;
|
|
51
|
+
}
|
|
52
|
+
const _excluded = ["extraArgs"];
|
|
53
|
+
function _objectWithoutProperties(e, t) { if (null == e) return {}; var o, r, i = _objectWithoutPropertiesLoose(e, t); if (Object.getOwnPropertySymbols) { var n = Object.getOwnPropertySymbols(e); for (r = 0; r < n.length; r++) o = n[r], -1 === t.indexOf(o) && {}.propertyIsEnumerable.call(e, o) && (i[o] = e[o]); } return i; }
|
|
54
|
+
function _objectWithoutPropertiesLoose(r, e) { if (null == r) return {}; var t = {}; for (var n in r) if ({}.hasOwnProperty.call(r, n)) { if (-1 !== e.indexOf(n)) continue; t[n] = r[n]; } return t; }
|
|
55
|
+
/**
|
|
56
|
+
* Git primitives shared by the lane and main sync executors; each encodes a decision that must stay
|
|
57
|
+
* identical on both paths.
|
|
58
|
+
*/
|
|
59
|
+
|
|
60
|
+
/** paths the sync executors never treat as workspace content — see `cleanUntrackedScoped` */
|
|
61
|
+
const SYNC_EXCLUDED_PATHS = exports.SYNC_EXCLUDED_PATHS = ['.bit', 'node_modules'];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* How a raw git invocation is run, injectable so a helper whose whole content is its argv can be unit
|
|
65
|
+
* tested without a repository. Production always uses {@link realGitRaw}.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
const realGitRaw = args => _git().git.raw(args);
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Remove untracked files, leaving the local bit scope and installed packages alone. No `-x` (ignored
|
|
72
|
+
* files stay), and `.bit` / `node_modules` are excluded explicitly — without that, the clean deletes
|
|
73
|
+
* the local scope in a workspace whose `.gitignore` lacks Bit's block.
|
|
74
|
+
*/
|
|
75
|
+
exports.realGitRaw = realGitRaw;
|
|
76
|
+
async function cleanUntrackedScoped(run = realGitRaw) {
|
|
77
|
+
await run(['clean', '-fd', ...SYNC_EXCLUDED_PATHS.flatMap(path => ['-e', path])]);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Refuse a branch name git would read as an option or reject as a ref. Not every branch reaching the
|
|
82
|
+
* checkout comes from validated config: the default branch is derived from the remote
|
|
83
|
+
* (`getDefaultBranchName`), so the primitive that builds the argv is where the guard belongs — every
|
|
84
|
+
* caller inherits it.
|
|
85
|
+
*/
|
|
86
|
+
function assertCheckoutableBranch(branch) {
|
|
87
|
+
const problem = (0, _syncConfig().validateBranchName)(branch);
|
|
88
|
+
if (problem) {
|
|
89
|
+
throw new (_bitError().BitError)(`bit ci sync cannot check out "${branch}": ${problem}. Rename the branch, or set the intended name ` + `explicitly in the "teambit.git/ci" sync config.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Put the working tree on `branch` holding nothing but that commit's content, then make the workspace
|
|
95
|
+
* re-read the checked-out `.bitmap`. Order matters: `checkout -f` (leftover tracked changes must not
|
|
96
|
+
* abort the target), then the scoped clean (a forced checkout leaves untracked files in place, and
|
|
97
|
+
* every commit path stages with `-A`), then the reload so it reads the pristine tree. With
|
|
98
|
+
* `startPoint`, `-B` creates-or-resets the branch — refused when the local branch holds commits no
|
|
99
|
+
* remote contains, because moving it would orphan unpushed work; the predicate is remote containment,
|
|
100
|
+
* not start-point ancestry (a fully pushed tip loses nothing in either legitimate reset shape).
|
|
101
|
+
*/
|
|
102
|
+
async function checkoutPristine(branch, startPoint, reload, run = realGitRaw) {
|
|
103
|
+
assertCheckoutableBranch(branch);
|
|
104
|
+
if (startPoint && (await localBranchExists(branch, run))) {
|
|
105
|
+
const containedIn = String((await run(['branch', '-r', '--contains', `refs/heads/${branch}`])) ?? '').trim();
|
|
106
|
+
if (!containedIn) {
|
|
107
|
+
throw new Error(`local branch "${branch}" has commits that no remote branch contains — resetting it would ` + `orphan them (recoverable only from the reflog). Push or back up the local branch, delete ` + `it, or run from a clean checkout`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await run(startPoint ? ['checkout', '-f', '-B', branch, startPoint] : ['checkout', '-f', branch]);
|
|
111
|
+
await cleanUntrackedScoped(run);
|
|
112
|
+
await reload();
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Whether the branch exists locally. Judged by output, never by whether the call threw: simple-git's
|
|
117
|
+
* `raw` resolves with empty output on some non-zero exits instead of rejecting.
|
|
118
|
+
*/
|
|
119
|
+
async function localBranchExists(branch, run = realGitRaw) {
|
|
120
|
+
const out = await run(['rev-parse', '--verify', '--quiet', `refs/heads/${branch}`]).catch(() => '');
|
|
121
|
+
return String(out ?? '').trim().length > 0;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* `checkoutPristine` for the restore paths: a start point only when the branch is absent locally
|
|
126
|
+
* (detached-HEAD/single-branch checkouts) — passing `origin/<branch>` when it exists would `-B`-reset
|
|
127
|
+
* the developer's default branch and discard their unpushed commits.
|
|
128
|
+
*/
|
|
129
|
+
async function checkoutPristineRestore(branch, reload, run = realGitRaw) {
|
|
130
|
+
const startPoint = (await localBranchExists(branch, run)) ? undefined : `origin/${branch}`;
|
|
131
|
+
await checkoutPristine(branch, startPoint, reload, run);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Stage every change except `.bit` / `node_modules` (a bare `add -A` would commit the local scope when
|
|
136
|
+
* `.gitignore` lacks Bit's block). The `:(exclude)` pathspecs make git skip those trees instead of
|
|
137
|
+
* staging them for a reset to undo; `git add` refuses them when a named path IS ignored — the case where
|
|
138
|
+
* the traversal is already cheap — so the add-then-reset pair is the fallback. Both leave the same index,
|
|
139
|
+
* and `git reset -- <paths>` is a no-op for paths absent from it, so neither fallback command can fail.
|
|
140
|
+
*/
|
|
141
|
+
async function addAllExceptScopeAndModules(run = realGitRaw) {
|
|
142
|
+
const stageAll = ['add', '-A', '--', '.'];
|
|
143
|
+
try {
|
|
144
|
+
await run([...stageAll, ...SYNC_EXCLUDED_PATHS.map(path => `:(exclude)${path}`)]);
|
|
145
|
+
} catch {
|
|
146
|
+
await run(stageAll);
|
|
147
|
+
await run(['reset', '-q', '--', ...SYNC_EXCLUDED_PATHS]);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Whether a `git status` path is one the sync executors never treat as workspace content. Applied
|
|
153
|
+
* everywhere a status is interpreted — otherwise `.bit`/`node_modules` files count as drift when
|
|
154
|
+
* `.gitignore` lacks Bit's block.
|
|
155
|
+
*/
|
|
156
|
+
function isNonContentPath(path) {
|
|
157
|
+
return SYNC_EXCLUDED_PATHS.some(excluded => path === excluded || path.startsWith(`${excluded}/`));
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
/**
|
|
161
|
+
* The refspec every sync fetch passes **explicitly**, overriding whatever `remote.origin.fetch` this
|
|
162
|
+
* checkout was configured with.
|
|
163
|
+
*/
|
|
164
|
+
const ALL_HEADS_REFSPEC = exports.ALL_HEADS_REFSPEC = '+refs/heads/*:refs/remotes/origin/*';
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Fetch `origin` so every branch it has is available as `refs/remotes/origin/<branch>`. A bare fetch
|
|
168
|
+
* honours the checkout's configured `remote.origin.fetch`, which in a single-branch clone updates
|
|
169
|
+
* exactly one ref while enumeration (`ls-remote`) sees every branch; an explicit refspec overrides the
|
|
170
|
+
* config. Does not make shallow clones work — depth is a different axis.
|
|
171
|
+
*/
|
|
172
|
+
async function fetchRemoteHeads(run = realGitRaw) {
|
|
173
|
+
await run(['fetch', 'origin', ALL_HEADS_REFSPEC]);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/** Refspec that updates exactly one remote-tracking ref — a mid-run re-read of a single branch. */
|
|
177
|
+
function singleHeadRefspec(branch) {
|
|
178
|
+
return `+refs/heads/${branch}:refs/remotes/origin/${branch}`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* `origin/<branch>`'s tip as the remote has it NOW: every other ref a run reads comes from one fetch at
|
|
183
|
+
* its start. Undefined when the branch is gone or unreadable — never a stale sha, because the answer
|
|
184
|
+
* decides whether a branch deletion is still safe.
|
|
185
|
+
*/
|
|
186
|
+
async function refetchBranchTip(branch, run = realGitRaw) {
|
|
187
|
+
try {
|
|
188
|
+
await run(['fetch', 'origin', singleHeadRefspec(branch)]);
|
|
189
|
+
const out = await run(['rev-parse', `refs/remotes/origin/${branch}`]);
|
|
190
|
+
return String(out ?? '').trim() || undefined;
|
|
191
|
+
} catch {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* `git push` argv that deletes a remote branch only while its tip is still `expectedTipSha`. Full
|
|
198
|
+
* `:refs/heads/<b>` refspec so the branch name can never be read as an option; the lease makes the server
|
|
199
|
+
* itself refuse a racing update rather than lose it.
|
|
200
|
+
*/
|
|
201
|
+
function deleteBranchArgs(branch, expectedTipSha) {
|
|
202
|
+
return ['origin', `--force-with-lease=refs/heads/${branch}:${expectedTipSha}`, `:refs/heads/${branch}`];
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Whether a failed push was the lease refusing. The wording varies by git version and transport:
|
|
207
|
+
* "stale info" (client-side check), "is at X but expected Y" (receive-pack), and "incorrect old value
|
|
208
|
+
* provided" (the local/file transport, which is what CI's e2e remotes use). Over-matching is the safe
|
|
209
|
+
* direction — the only consequence is reporting a branch as kept rather than as a failed delete.
|
|
210
|
+
*/
|
|
211
|
+
function isStaleLeaseRejection(message) {
|
|
212
|
+
return /stale info|force-with-lease|but expected|incorrect old value/i.test(message);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
/** Whether `origin` has the given branch. Assumes a `git fetch` isn't required (uses `ls-remote`). */
|
|
216
|
+
async function branchExistsOnRemote(branch) {
|
|
217
|
+
const out = await _git().git.raw(['ls-remote', '--heads', 'origin', branch]);
|
|
218
|
+
return out.trim().length > 0;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Every branch `origin` has, by short name. `ls-remote` rather than `git branch -r` so the answer
|
|
223
|
+
* cannot be narrowed by the checkout's refspec or staleness.
|
|
224
|
+
*/
|
|
225
|
+
async function listRemoteBranches() {
|
|
226
|
+
const out = await _git().git.raw(['ls-remote', '--heads', 'origin']);
|
|
227
|
+
const prefix = 'refs/heads/';
|
|
228
|
+
return out.split('\n').map(line => line.split('\t')[1]?.trim()).filter(ref => Boolean(ref && ref.startsWith(prefix))).map(ref => ref.slice(prefix.length));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Is `maybeAncestor` reachable from `descendant` (true for identical commits)? Not `merge-base
|
|
233
|
+
* --is-ancestor`: it answers via the exit code, and simple-git's `raw` resolves on exit 1, so "not an
|
|
234
|
+
* ancestor" would read as yes. Throws when the commits share no history or a revision cannot resolve.
|
|
235
|
+
*/
|
|
236
|
+
async function isAncestor(maybeAncestor, descendant) {
|
|
237
|
+
const ancestorSha = (await _git().git.revparse([maybeAncestor])).trim();
|
|
238
|
+
const mergeBase = (await _git().git.raw(['merge-base', maybeAncestor, descendant])).trim();
|
|
239
|
+
if (!ancestorSha || !mergeBase) throw new Error(`could not compare ${maybeAncestor} against ${descendant}`);
|
|
240
|
+
return ancestorSha === mergeBase;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/** The prefix `git symbolic-ref refs/remotes/origin/HEAD` puts in front of the default branch name. */
|
|
244
|
+
const ORIGIN_HEAD_REF_PREFIX = exports.ORIGIN_HEAD_REF_PREFIX = 'refs/remotes/origin/';
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* The default branch name out of `git symbolic-ref refs/remotes/origin/HEAD` output, or undefined for
|
|
248
|
+
* an unrecognised shape. Strips the prefix; never splits on `/` — branch names may contain slashes
|
|
249
|
+
* (`release/main`), and truncating would protect the wrong branch.
|
|
250
|
+
*/
|
|
251
|
+
function parseOriginHeadRef(symbolicRefOutput) {
|
|
252
|
+
const ref = symbolicRefOutput.trim();
|
|
253
|
+
if (!ref.startsWith(ORIGIN_HEAD_REF_PREFIX)) return undefined;
|
|
254
|
+
return ref.slice(ORIGIN_HEAD_REF_PREFIX.length) || undefined;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/** The prefix a symref answer from `git ls-remote --symref origin HEAD` puts before the branch name. */
|
|
258
|
+
const LS_REMOTE_SYMREF_PREFIX = 'ref: refs/heads/';
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The default branch name out of `git ls-remote --symref origin HEAD` output, or undefined when no
|
|
262
|
+
* symref line is present (some servers omit it). Same slash discipline as {@link parseOriginHeadRef}.
|
|
263
|
+
*/
|
|
264
|
+
function parseLsRemoteSymref(lsRemoteOutput) {
|
|
265
|
+
const line = lsRemoteOutput.split('\n').find(l => l.startsWith(LS_REMOTE_SYMREF_PREFIX));
|
|
266
|
+
if (!line) return undefined;
|
|
267
|
+
const name = line.slice(LS_REMOTE_SYMREF_PREFIX.length).split('\t')[0].trim();
|
|
268
|
+
return name || undefined;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* The remote's own answer for its default branch. Unlike the local `origin/HEAD` symref or enumerating
|
|
273
|
+
* `origin/*`, this cannot be stale or narrowed — only unanswered (undefined hands on to the fallback).
|
|
274
|
+
*/
|
|
275
|
+
async function remoteHeadBranch(run = realGitRaw) {
|
|
276
|
+
try {
|
|
277
|
+
const out = await run(['ls-remote', '--symref', 'origin', 'HEAD']);
|
|
278
|
+
return parseLsRemoteSymref(String(out ?? ''));
|
|
279
|
+
} catch {
|
|
280
|
+
return undefined;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* The git repository's root, or undefined outside a repo. A bit workspace is not necessarily the repo
|
|
286
|
+
* root, and GitHub only discovers workflows at `<repo>/.github/workflows`.
|
|
287
|
+
*/
|
|
288
|
+
async function gitRepoRoot() {
|
|
289
|
+
try {
|
|
290
|
+
const root = (await _git().git.raw(['rev-parse', '--show-toplevel'])).trim();
|
|
291
|
+
return root || undefined;
|
|
292
|
+
} catch {
|
|
293
|
+
return undefined;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Reading `git config`, injectable so the identity decision can be unit tested without a repository.
|
|
299
|
+
* There is deliberately no writer — see {@link resolveGitIdentity}.
|
|
300
|
+
*/
|
|
301
|
+
|
|
302
|
+
const realGitConfigIO = exports.realGitConfigIO = {
|
|
303
|
+
get: key => _git().git.raw(['config', '--get', key]).then(out => out.trim().length ? out.trim() : undefined)
|
|
304
|
+
// A missing key and "not a git repository" both exit non-zero; both mean "no identity to keep".
|
|
305
|
+
.catch(() => undefined)
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* The identity the sync commits with when nothing else says otherwise. A contract: the scaffolded
|
|
310
|
+
* workflow templates (`init-scaffold.ts`) and the GitHub Action's defaults must carry the same pair,
|
|
311
|
+
* or the same repository commits under different authors depending on entry point.
|
|
312
|
+
*/
|
|
313
|
+
const DEFAULT_GIT_USER_NAME = exports.DEFAULT_GIT_USER_NAME = 'bit-sync[bot]';
|
|
314
|
+
const DEFAULT_GIT_USER_EMAIL = exports.DEFAULT_GIT_USER_EMAIL = 'bit-sync[bot]@users.noreply.github.com';
|
|
315
|
+
/**
|
|
316
|
+
* Who the sync commits as. Read-only on purpose: writing these keys into the repository's config
|
|
317
|
+
* would outlive the run and re-author the developer's own later commits as the bot. Precedence per
|
|
318
|
+
* key: configured git identity > `GIT_USER_NAME`/`GIT_USER_EMAIL` > default.
|
|
319
|
+
*/
|
|
320
|
+
async function resolveGitIdentity(io = realGitConfigIO, env = process.env) {
|
|
321
|
+
return {
|
|
322
|
+
name: (await io.get('user.name')) || env.GIT_USER_NAME || DEFAULT_GIT_USER_NAME,
|
|
323
|
+
email: (await io.get('user.email')) || env.GIT_USER_EMAIL || DEFAULT_GIT_USER_EMAIL
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/** The `git -c` pair that applies an identity to ONE invocation, leaving the repo's config alone. */
|
|
328
|
+
function identityArgs(identity) {
|
|
329
|
+
return ['-c', `user.name=${identity.name}`, '-c', `user.email=${identity.email}`];
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Run a git command that may author a commit. Every such command needs the identity — a fresh CI
|
|
333
|
+
* checkout has none, and git refuses to commit ("Please tell me who you are") without one.
|
|
334
|
+
*/
|
|
335
|
+
async function gitWithIdentity(args, deps = {}) {
|
|
336
|
+
const {
|
|
337
|
+
run = realGitRaw,
|
|
338
|
+
io = realGitConfigIO,
|
|
339
|
+
env = process.env
|
|
340
|
+
} = deps;
|
|
341
|
+
const identity = await resolveGitIdentity(io, env);
|
|
342
|
+
return String((await run([...identityArgs(identity), ...args])) ?? '');
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** `git commit` under the sync identity; `extraArgs` carries flags such as `--allow-empty`. */
|
|
346
|
+
async function commitWithIdentity(message, opts = {}) {
|
|
347
|
+
const {
|
|
348
|
+
extraArgs = []
|
|
349
|
+
} = opts,
|
|
350
|
+
deps = _objectWithoutProperties(opts, _excluded);
|
|
351
|
+
await gitWithIdentity(['commit', '-m', message, ...extraArgs], deps);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
//# sourceMappingURL=git-ops.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_bitError","data","require","_git","_syncConfig","_excluded","_objectWithoutProperties","e","t","o","r","i","_objectWithoutPropertiesLoose","Object","getOwnPropertySymbols","n","length","indexOf","propertyIsEnumerable","call","hasOwnProperty","SYNC_EXCLUDED_PATHS","exports","realGitRaw","args","git","raw","cleanUntrackedScoped","run","flatMap","path","assertCheckoutableBranch","branch","problem","validateBranchName","BitError","checkoutPristine","startPoint","reload","localBranchExists","containedIn","String","trim","Error","out","catch","checkoutPristineRestore","undefined","addAllExceptScopeAndModules","stageAll","map","isNonContentPath","some","excluded","startsWith","ALL_HEADS_REFSPEC","fetchRemoteHeads","singleHeadRefspec","refetchBranchTip","deleteBranchArgs","expectedTipSha","isStaleLeaseRejection","message","test","branchExistsOnRemote","listRemoteBranches","prefix","split","line","filter","ref","Boolean","slice","isAncestor","maybeAncestor","descendant","ancestorSha","revparse","mergeBase","ORIGIN_HEAD_REF_PREFIX","parseOriginHeadRef","symbolicRefOutput","LS_REMOTE_SYMREF_PREFIX","parseLsRemoteSymref","lsRemoteOutput","find","l","name","remoteHeadBranch","gitRepoRoot","root","realGitConfigIO","get","key","then","DEFAULT_GIT_USER_NAME","DEFAULT_GIT_USER_EMAIL","resolveGitIdentity","io","env","process","GIT_USER_NAME","email","GIT_USER_EMAIL","identityArgs","identity","gitWithIdentity","deps","commitWithIdentity","opts","extraArgs"],"sources":["git-ops.ts"],"sourcesContent":["import { BitError } from '@teambit/bit-error';\nimport { git } from '../git';\nimport { validateBranchName } from './sync-config';\n\n/**\n * Git primitives shared by the lane and main sync executors; each encodes a decision that must stay\n * identical on both paths.\n */\n\n/** paths the sync executors never treat as workspace content — see `cleanUntrackedScoped` */\nexport const SYNC_EXCLUDED_PATHS = ['.bit', 'node_modules'];\n\n/**\n * How a raw git invocation is run, injectable so a helper whose whole content is its argv can be unit\n * tested without a repository. Production always uses {@link realGitRaw}.\n */\nexport type GitArgsRunner = (args: string[]) => Promise<unknown>;\n\nexport const realGitRaw: GitArgsRunner = (args) => git.raw(args);\n\n/**\n * Remove untracked files, leaving the local bit scope and installed packages alone. No `-x` (ignored\n * files stay), and `.bit` / `node_modules` are excluded explicitly — without that, the clean deletes\n * the local scope in a workspace whose `.gitignore` lacks Bit's block.\n */\nexport async function cleanUntrackedScoped(run: GitArgsRunner = realGitRaw): Promise<void> {\n await run(['clean', '-fd', ...SYNC_EXCLUDED_PATHS.flatMap((path) => ['-e', path])]);\n}\n\n/**\n * Refuse a branch name git would read as an option or reject as a ref. Not every branch reaching the\n * checkout comes from validated config: the default branch is derived from the remote\n * (`getDefaultBranchName`), so the primitive that builds the argv is where the guard belongs — every\n * caller inherits it.\n */\nexport function assertCheckoutableBranch(branch: string): void {\n const problem = validateBranchName(branch);\n if (problem) {\n throw new BitError(\n `bit ci sync cannot check out \"${branch}\": ${problem}. Rename the branch, or set the intended name ` +\n `explicitly in the \"teambit.git/ci\" sync config.`\n );\n }\n}\n\n/**\n * Put the working tree on `branch` holding nothing but that commit's content, then make the workspace\n * re-read the checked-out `.bitmap`. Order matters: `checkout -f` (leftover tracked changes must not\n * abort the target), then the scoped clean (a forced checkout leaves untracked files in place, and\n * every commit path stages with `-A`), then the reload so it reads the pristine tree. With\n * `startPoint`, `-B` creates-or-resets the branch — refused when the local branch holds commits no\n * remote contains, because moving it would orphan unpushed work; the predicate is remote containment,\n * not start-point ancestry (a fully pushed tip loses nothing in either legitimate reset shape).\n */\nexport async function checkoutPristine(\n branch: string,\n startPoint: string | undefined,\n reload: () => Promise<void>,\n run: GitArgsRunner = realGitRaw\n): Promise<void> {\n assertCheckoutableBranch(branch);\n if (startPoint && (await localBranchExists(branch, run))) {\n const containedIn = String((await run(['branch', '-r', '--contains', `refs/heads/${branch}`])) ?? '').trim();\n if (!containedIn) {\n throw new Error(\n `local branch \"${branch}\" has commits that no remote branch contains — resetting it would ` +\n `orphan them (recoverable only from the reflog). Push or back up the local branch, delete ` +\n `it, or run from a clean checkout`\n );\n }\n }\n await run(startPoint ? ['checkout', '-f', '-B', branch, startPoint] : ['checkout', '-f', branch]);\n await cleanUntrackedScoped(run);\n await reload();\n}\n\n/**\n * Whether the branch exists locally. Judged by output, never by whether the call threw: simple-git's\n * `raw` resolves with empty output on some non-zero exits instead of rejecting.\n */\nexport async function localBranchExists(branch: string, run: GitArgsRunner = realGitRaw): Promise<boolean> {\n const out = await run(['rev-parse', '--verify', '--quiet', `refs/heads/${branch}`]).catch(() => '');\n return String(out ?? '').trim().length > 0;\n}\n\n/**\n * `checkoutPristine` for the restore paths: a start point only when the branch is absent locally\n * (detached-HEAD/single-branch checkouts) — passing `origin/<branch>` when it exists would `-B`-reset\n * the developer's default branch and discard their unpushed commits.\n */\nexport async function checkoutPristineRestore(\n branch: string,\n reload: () => Promise<void>,\n run: GitArgsRunner = realGitRaw\n): Promise<void> {\n const startPoint = (await localBranchExists(branch, run)) ? undefined : `origin/${branch}`;\n await checkoutPristine(branch, startPoint, reload, run);\n}\n\n/**\n * Stage every change except `.bit` / `node_modules` (a bare `add -A` would commit the local scope when\n * `.gitignore` lacks Bit's block). The `:(exclude)` pathspecs make git skip those trees instead of\n * staging them for a reset to undo; `git add` refuses them when a named path IS ignored — the case where\n * the traversal is already cheap — so the add-then-reset pair is the fallback. Both leave the same index,\n * and `git reset -- <paths>` is a no-op for paths absent from it, so neither fallback command can fail.\n */\nexport async function addAllExceptScopeAndModules(run: GitArgsRunner = realGitRaw): Promise<void> {\n const stageAll = ['add', '-A', '--', '.'];\n try {\n await run([...stageAll, ...SYNC_EXCLUDED_PATHS.map((path) => `:(exclude)${path}`)]);\n } catch {\n await run(stageAll);\n await run(['reset', '-q', '--', ...SYNC_EXCLUDED_PATHS]);\n }\n}\n\n/**\n * Whether a `git status` path is one the sync executors never treat as workspace content. Applied\n * everywhere a status is interpreted — otherwise `.bit`/`node_modules` files count as drift when\n * `.gitignore` lacks Bit's block.\n */\nexport function isNonContentPath(path: string): boolean {\n return SYNC_EXCLUDED_PATHS.some((excluded) => path === excluded || path.startsWith(`${excluded}/`));\n}\n\n/**\n * The refspec every sync fetch passes **explicitly**, overriding whatever `remote.origin.fetch` this\n * checkout was configured with.\n */\nexport const ALL_HEADS_REFSPEC = '+refs/heads/*:refs/remotes/origin/*';\n\n/**\n * Fetch `origin` so every branch it has is available as `refs/remotes/origin/<branch>`. A bare fetch\n * honours the checkout's configured `remote.origin.fetch`, which in a single-branch clone updates\n * exactly one ref while enumeration (`ls-remote`) sees every branch; an explicit refspec overrides the\n * config. Does not make shallow clones work — depth is a different axis.\n */\nexport async function fetchRemoteHeads(run: GitArgsRunner = realGitRaw): Promise<void> {\n await run(['fetch', 'origin', ALL_HEADS_REFSPEC]);\n}\n\n/** Refspec that updates exactly one remote-tracking ref — a mid-run re-read of a single branch. */\nexport function singleHeadRefspec(branch: string): string {\n return `+refs/heads/${branch}:refs/remotes/origin/${branch}`;\n}\n\n/**\n * `origin/<branch>`'s tip as the remote has it NOW: every other ref a run reads comes from one fetch at\n * its start. Undefined when the branch is gone or unreadable — never a stale sha, because the answer\n * decides whether a branch deletion is still safe.\n */\nexport async function refetchBranchTip(branch: string, run: GitArgsRunner = realGitRaw): Promise<string | undefined> {\n try {\n await run(['fetch', 'origin', singleHeadRefspec(branch)]);\n const out = await run(['rev-parse', `refs/remotes/origin/${branch}`]);\n return String(out ?? '').trim() || undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * `git push` argv that deletes a remote branch only while its tip is still `expectedTipSha`. Full\n * `:refs/heads/<b>` refspec so the branch name can never be read as an option; the lease makes the server\n * itself refuse a racing update rather than lose it.\n */\nexport function deleteBranchArgs(branch: string, expectedTipSha: string): string[] {\n return ['origin', `--force-with-lease=refs/heads/${branch}:${expectedTipSha}`, `:refs/heads/${branch}`];\n}\n\n/**\n * Whether a failed push was the lease refusing. The wording varies by git version and transport:\n * \"stale info\" (client-side check), \"is at X but expected Y\" (receive-pack), and \"incorrect old value\n * provided\" (the local/file transport, which is what CI's e2e remotes use). Over-matching is the safe\n * direction — the only consequence is reporting a branch as kept rather than as a failed delete.\n */\nexport function isStaleLeaseRejection(message: string): boolean {\n return /stale info|force-with-lease|but expected|incorrect old value/i.test(message);\n}\n\n/** Whether `origin` has the given branch. Assumes a `git fetch` isn't required (uses `ls-remote`). */\nexport async function branchExistsOnRemote(branch: string): Promise<boolean> {\n const out = await git.raw(['ls-remote', '--heads', 'origin', branch]);\n return out.trim().length > 0;\n}\n\n/**\n * Every branch `origin` has, by short name. `ls-remote` rather than `git branch -r` so the answer\n * cannot be narrowed by the checkout's refspec or staleness.\n */\nexport async function listRemoteBranches(): Promise<string[]> {\n const out = await git.raw(['ls-remote', '--heads', 'origin']);\n const prefix = 'refs/heads/';\n return out\n .split('\\n')\n .map((line) => line.split('\\t')[1]?.trim())\n .filter((ref): ref is string => Boolean(ref && ref.startsWith(prefix)))\n .map((ref) => ref.slice(prefix.length));\n}\n\n/**\n * Is `maybeAncestor` reachable from `descendant` (true for identical commits)? Not `merge-base\n * --is-ancestor`: it answers via the exit code, and simple-git's `raw` resolves on exit 1, so \"not an\n * ancestor\" would read as yes. Throws when the commits share no history or a revision cannot resolve.\n */\nexport async function isAncestor(maybeAncestor: string, descendant: string): Promise<boolean> {\n const ancestorSha = (await git.revparse([maybeAncestor])).trim();\n const mergeBase = (await git.raw(['merge-base', maybeAncestor, descendant])).trim();\n if (!ancestorSha || !mergeBase) throw new Error(`could not compare ${maybeAncestor} against ${descendant}`);\n return ancestorSha === mergeBase;\n}\n\n/** The prefix `git symbolic-ref refs/remotes/origin/HEAD` puts in front of the default branch name. */\nexport const ORIGIN_HEAD_REF_PREFIX = 'refs/remotes/origin/';\n\n/**\n * The default branch name out of `git symbolic-ref refs/remotes/origin/HEAD` output, or undefined for\n * an unrecognised shape. Strips the prefix; never splits on `/` — branch names may contain slashes\n * (`release/main`), and truncating would protect the wrong branch.\n */\nexport function parseOriginHeadRef(symbolicRefOutput: string): string | undefined {\n const ref = symbolicRefOutput.trim();\n if (!ref.startsWith(ORIGIN_HEAD_REF_PREFIX)) return undefined;\n return ref.slice(ORIGIN_HEAD_REF_PREFIX.length) || undefined;\n}\n\n/** The prefix a symref answer from `git ls-remote --symref origin HEAD` puts before the branch name. */\nconst LS_REMOTE_SYMREF_PREFIX = 'ref: refs/heads/';\n\n/**\n * The default branch name out of `git ls-remote --symref origin HEAD` output, or undefined when no\n * symref line is present (some servers omit it). Same slash discipline as {@link parseOriginHeadRef}.\n */\nexport function parseLsRemoteSymref(lsRemoteOutput: string): string | undefined {\n const line = lsRemoteOutput.split('\\n').find((l) => l.startsWith(LS_REMOTE_SYMREF_PREFIX));\n if (!line) return undefined;\n const name = line.slice(LS_REMOTE_SYMREF_PREFIX.length).split('\\t')[0].trim();\n return name || undefined;\n}\n\n/**\n * The remote's own answer for its default branch. Unlike the local `origin/HEAD` symref or enumerating\n * `origin/*`, this cannot be stale or narrowed — only unanswered (undefined hands on to the fallback).\n */\nexport async function remoteHeadBranch(run: GitArgsRunner = realGitRaw): Promise<string | undefined> {\n try {\n const out = await run(['ls-remote', '--symref', 'origin', 'HEAD']);\n return parseLsRemoteSymref(String(out ?? ''));\n } catch {\n return undefined;\n }\n}\n\n/**\n * The git repository's root, or undefined outside a repo. A bit workspace is not necessarily the repo\n * root, and GitHub only discovers workflows at `<repo>/.github/workflows`.\n */\nexport async function gitRepoRoot(): Promise<string | undefined> {\n try {\n const root = (await git.raw(['rev-parse', '--show-toplevel'])).trim();\n return root || undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Reading `git config`, injectable so the identity decision can be unit tested without a repository.\n * There is deliberately no writer — see {@link resolveGitIdentity}.\n */\nexport type GitConfigIO = {\n /** the configured value, or undefined when unset (or when git cannot answer) */\n get(key: string): Promise<string | undefined>;\n};\n\nexport const realGitConfigIO: GitConfigIO = {\n get: (key) =>\n git\n .raw(['config', '--get', key])\n .then((out) => (out.trim().length ? out.trim() : undefined))\n // A missing key and \"not a git repository\" both exit non-zero; both mean \"no identity to keep\".\n .catch(() => undefined),\n};\n\n/**\n * The identity the sync commits with when nothing else says otherwise. A contract: the scaffolded\n * workflow templates (`init-scaffold.ts`) and the GitHub Action's defaults must carry the same pair,\n * or the same repository commits under different authors depending on entry point.\n */\nexport const DEFAULT_GIT_USER_NAME = 'bit-sync[bot]';\nexport const DEFAULT_GIT_USER_EMAIL = 'bit-sync[bot]@users.noreply.github.com';\n\nexport type GitIdentity = { name: string; email: string };\n\n/**\n * Who the sync commits as. Read-only on purpose: writing these keys into the repository's config\n * would outlive the run and re-author the developer's own later commits as the bot. Precedence per\n * key: configured git identity > `GIT_USER_NAME`/`GIT_USER_EMAIL` > default.\n */\nexport async function resolveGitIdentity(\n io: GitConfigIO = realGitConfigIO,\n env: NodeJS.ProcessEnv = process.env\n): Promise<GitIdentity> {\n return {\n name: (await io.get('user.name')) || env.GIT_USER_NAME || DEFAULT_GIT_USER_NAME,\n email: (await io.get('user.email')) || env.GIT_USER_EMAIL || DEFAULT_GIT_USER_EMAIL,\n };\n}\n\n/** The `git -c` pair that applies an identity to ONE invocation, leaving the repo's config alone. */\nexport function identityArgs(identity: GitIdentity): string[] {\n return ['-c', `user.name=${identity.name}`, '-c', `user.email=${identity.email}`];\n}\n\nexport type IdentityDeps = { run?: GitArgsRunner; io?: GitConfigIO; env?: NodeJS.ProcessEnv };\n\n/**\n * Run a git command that may author a commit. Every such command needs the identity — a fresh CI\n * checkout has none, and git refuses to commit (\"Please tell me who you are\") without one.\n */\nexport async function gitWithIdentity(args: string[], deps: IdentityDeps = {}): Promise<string> {\n const { run = realGitRaw, io = realGitConfigIO, env = process.env } = deps;\n const identity = await resolveGitIdentity(io, env);\n return String((await run([...identityArgs(identity), ...args])) ?? '');\n}\n\n/** `git commit` under the sync identity; `extraArgs` carries flags such as `--allow-empty`. */\nexport async function commitWithIdentity(\n message: string,\n opts: IdentityDeps & { extraArgs?: string[] } = {}\n): Promise<void> {\n const { extraArgs = [], ...deps } = opts;\n await gitWithIdentity(['commit', '-m', message, ...extraArgs], deps);\n}\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|