just-git 0.1.8 → 0.1.10
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 +97 -74
- package/dist/index.d.ts +75 -1
- package/dist/index.js +227 -227
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,8 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/blindmansion/just-git/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/just-git)
|
|
5
|
+
[](https://bundlejs.com/?q=just-git)
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
Pure TypeScript git implementation. Zero dependencies. 34 commands. Works in Node, Bun, Deno, and the browser.
|
|
8
|
+
|
|
9
|
+
Designed for sandboxed environments where shelling out to real git isn't possible or desirable. Targets faithful reproduction of real git's behavior and output. Operates on an abstract `FileSystem` interface — plug in an in-memory VFS, a real filesystem, or anything else. Pairs with [just-bash](https://github.com/vercel-labs/just-bash), which provides an in-memory filesystem and shell that just-git registers into as a custom command.
|
|
7
10
|
|
|
8
11
|
## Install
|
|
9
12
|
|
|
@@ -37,27 +40,26 @@ await bash.exec("git log --oneline");
|
|
|
37
40
|
|
|
38
41
|
`createGit(options?)` accepts:
|
|
39
42
|
|
|
40
|
-
| Option
|
|
41
|
-
|
|
|
42
|
-
| `identity`
|
|
43
|
-
| `credentials`
|
|
44
|
-
| `disabled`
|
|
45
|
-
| `network`
|
|
43
|
+
| Option | Description |
|
|
44
|
+
| --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| `identity` | Author/committer override. With `locked: true`, always wins over env vars and git config. Without `locked`, acts as a fallback. |
|
|
46
|
+
| `credentials` | `(url) => HttpAuth \| null` callback for Smart HTTP transport auth. |
|
|
47
|
+
| `disabled` | `GitCommandName[]` of subcommands to block (e.g. `["push", "rebase"]`). |
|
|
48
|
+
| `network` | `{ allowed?: string[], fetch?: FetchFunction }` to restrict HTTP access and/or provide a custom `fetch`. `allowed` accepts hostnames (`"github.com"`) or URL prefixes (`"https://github.com/myorg/"`). Set to `false` to block all network access. |
|
|
49
|
+
| `resolveRemote` | `(url) => GitContext \| null` callback for cross-VFS remote resolution. See [Multi-agent collaboration](#multi-agent-collaboration). |
|
|
46
50
|
|
|
47
51
|
```ts
|
|
48
52
|
const git = createGit({
|
|
49
53
|
identity: { name: "Agent Bot", email: "bot@company.com", locked: true },
|
|
50
54
|
credentials: async (url) => ({ type: "bearer", token: "ghp_..." }),
|
|
51
55
|
disabled: ["rebase"],
|
|
52
|
-
network:
|
|
56
|
+
network: false, // no HTTP access
|
|
53
57
|
});
|
|
54
58
|
```
|
|
55
59
|
|
|
56
60
|
## Middleware
|
|
57
61
|
|
|
58
|
-
Middleware wraps every `git <subcommand>` invocation. Each middleware receives a `CommandEvent` and a `next()` function. Call `next()` to proceed, or return an `ExecResult` to short-circuit. Middlewares compose in registration order (first registered = outermost).
|
|
59
|
-
|
|
60
|
-
The `CommandEvent` provides the execution context: `{ command, rawArgs, fs, cwd, env, stdin }`, plus optional `exec` and `signal` when available.
|
|
62
|
+
Middleware wraps every `git <subcommand>` invocation. Each middleware receives a `CommandEvent` and a `next()` function. Call `next()` to proceed, or return an `ExecResult` to short-circuit. Middlewares compose in registration order (first registered = outermost). `git.use()` returns an unsubscribe function.
|
|
61
63
|
|
|
62
64
|
```ts
|
|
63
65
|
// Audit log — record every command the agent runs
|
|
@@ -90,15 +92,11 @@ git.use(async (event, next) => {
|
|
|
90
92
|
});
|
|
91
93
|
```
|
|
92
94
|
|
|
93
|
-
`git.use()` returns an unsubscribe function to remove the middleware dynamically.
|
|
94
|
-
|
|
95
95
|
## Hooks
|
|
96
96
|
|
|
97
97
|
Hooks fire at specific points inside command execution (after middleware, inside operation logic). Register with `git.on(event, handler)`, which returns an unsubscribe function.
|
|
98
98
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
Pre-hooks can abort the operation by returning `{ abort: true, message? }`.
|
|
99
|
+
Pre-hooks can abort the operation by returning `{ abort: true, message? }`. Post-hooks are observational — return value is ignored.
|
|
102
100
|
|
|
103
101
|
```ts
|
|
104
102
|
// Block secrets from being committed
|
|
@@ -115,71 +113,77 @@ git.on("commit-msg", (event) => {
|
|
|
115
113
|
return { abort: true, message: "Commit message must follow conventional commits format" };
|
|
116
114
|
}
|
|
117
115
|
});
|
|
118
|
-
```
|
|
119
116
|
|
|
120
|
-
| Hook | Payload |
|
|
121
|
-
| ------------------ | --------------------------------------------------------------- |
|
|
122
|
-
| `pre-commit` | `{ index, treeHash }` |
|
|
123
|
-
| `commit-msg` | `{ message }` (mutable) |
|
|
124
|
-
| `merge-msg` | `{ message, treeHash, headHash, theirsHash }` (mutable message) |
|
|
125
|
-
| `pre-merge-commit` | `{ mergeMessage, treeHash, headHash, theirsHash }` |
|
|
126
|
-
| `pre-checkout` | `{ target, mode }` |
|
|
127
|
-
| `pre-push` | `{ remote, url, refs[] }` |
|
|
128
|
-
| `pre-fetch` | `{ remote, url, refspecs, prune, tags }` |
|
|
129
|
-
| `pre-clone` | `{ repository, targetPath, bare, branch }` |
|
|
130
|
-
| `pre-pull` | `{ remote, branch }` |
|
|
131
|
-
| `pre-rebase` | `{ upstream, branch }` |
|
|
132
|
-
| `pre-reset` | `{ mode, target }` |
|
|
133
|
-
| `pre-clean` | `{ dryRun, force, removeDirs, removeIgnored, onlyIgnored }` |
|
|
134
|
-
| `pre-rm` | `{ paths, cached, recursive, force }` |
|
|
135
|
-
| `pre-cherry-pick` | `{ mode, commit }` |
|
|
136
|
-
| `pre-revert` | `{ mode, commit }` |
|
|
137
|
-
| `pre-stash` | `{ action, ref }` |
|
|
138
|
-
|
|
139
|
-
### Post-hooks
|
|
140
|
-
|
|
141
|
-
Post-hooks are observational -- return value is ignored. Handlers are awaited in registration order.
|
|
142
|
-
|
|
143
|
-
```ts
|
|
144
117
|
// Feed agent activity to your UI or orchestration layer
|
|
145
118
|
git.on("post-commit", (event) => {
|
|
146
119
|
onAgentCommit({ hash: event.hash, branch: event.branch, message: event.message });
|
|
147
120
|
});
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Available pre-hooks: `pre-commit`, `commit-msg`, `merge-msg`, `pre-merge-commit`, `pre-checkout`, `pre-push`, `pre-fetch`, `pre-clone`, `pre-pull`, `pre-rebase`, `pre-reset`, `pre-clean`, `pre-rm`, `pre-cherry-pick`, `pre-revert`, `pre-stash`. Available post-hooks: `post-commit`, `post-merge`, `post-checkout`, `post-push`, `post-fetch`, `post-clone`, `post-pull`, `post-reset`, `post-clean`, `post-rm`, `post-cherry-pick`, `post-revert`, `post-stash`. Low-level events: `ref:update`, `ref:delete`, `object:write`.
|
|
124
|
+
|
|
125
|
+
See [HOOKS.md](HOOKS.md) for full payload types and the `CommandEvent` shape.
|
|
126
|
+
|
|
127
|
+
## Multi-agent collaboration
|
|
128
|
+
|
|
129
|
+
Multiple agents can work on clones of the same repository in the same process, each with full VFS isolation. The `resolveRemote` option maps remote URLs to `GitContext` instances on other virtual filesystems, so clone/fetch/push/pull cross VFS boundaries without any network or shared filesystem.
|
|
130
|
+
|
|
131
|
+
```ts
|
|
132
|
+
import { Bash, InMemoryFs } from "just-bash";
|
|
133
|
+
import { createGit, findGitDir } from "just-git";
|
|
134
|
+
|
|
135
|
+
// Origin repo on its own filesystem
|
|
136
|
+
const originFs = new InMemoryFs();
|
|
137
|
+
const setupBash = new Bash({
|
|
138
|
+
fs: originFs,
|
|
139
|
+
cwd: "/repo",
|
|
140
|
+
customCommands: [
|
|
141
|
+
createGit({ identity: { name: "Setup", email: "setup@example.com", locked: true } }),
|
|
142
|
+
],
|
|
143
|
+
});
|
|
144
|
+
await setupBash.exec("git init");
|
|
145
|
+
await setupBash.exec("echo 'hello' > README.md");
|
|
146
|
+
await setupBash.exec("git add . && git commit -m 'initial'");
|
|
147
|
+
|
|
148
|
+
const originCtx = await findGitDir(originFs, "/repo");
|
|
149
|
+
const resolve = (url: string) => (url === "/origin" ? originCtx : null);
|
|
150
|
+
|
|
151
|
+
// Each agent gets its own filesystem + resolveRemote pointing to origin
|
|
152
|
+
const alice = new Bash({
|
|
153
|
+
fs: new InMemoryFs(),
|
|
154
|
+
cwd: "/repo",
|
|
155
|
+
customCommands: [
|
|
156
|
+
createGit({
|
|
157
|
+
identity: { name: "Alice", email: "alice@example.com", locked: true },
|
|
158
|
+
resolveRemote: resolve,
|
|
159
|
+
}),
|
|
160
|
+
],
|
|
161
|
+
});
|
|
148
162
|
|
|
149
|
-
|
|
150
|
-
|
|
163
|
+
const bob = new Bash({
|
|
164
|
+
fs: new InMemoryFs(),
|
|
165
|
+
cwd: "/repo",
|
|
166
|
+
customCommands: [
|
|
167
|
+
createGit({
|
|
168
|
+
identity: { name: "Bob", email: "bob@example.com", locked: true },
|
|
169
|
+
resolveRemote: resolve,
|
|
170
|
+
}),
|
|
171
|
+
],
|
|
151
172
|
});
|
|
173
|
+
|
|
174
|
+
await alice.exec("git clone /origin /repo");
|
|
175
|
+
await bob.exec("git clone /origin /repo");
|
|
176
|
+
|
|
177
|
+
// Alice and Bob work independently, push to origin, fetch each other's changes
|
|
152
178
|
```
|
|
153
179
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
| `post-merge` | `{ headHash, theirsHash, strategy, commitHash }` |
|
|
158
|
-
| `post-checkout` | `{ prevHead, newHead, isBranchCheckout }` |
|
|
159
|
-
| `post-push` | same payload as `pre-push` |
|
|
160
|
-
| `post-fetch` | `{ remote, url, refsUpdated }` |
|
|
161
|
-
| `post-clone` | `{ repository, targetPath, bare, branch }` |
|
|
162
|
-
| `post-pull` | `{ remote, branch, strategy, commitHash }` |
|
|
163
|
-
| `post-reset` | `{ mode, targetHash }` |
|
|
164
|
-
| `post-clean` | `{ removed, dryRun }` |
|
|
165
|
-
| `post-rm` | `{ removedPaths, cached }` |
|
|
166
|
-
| `post-cherry-pick` | `{ mode, commitHash, hadConflicts }` |
|
|
167
|
-
| `post-revert` | `{ mode, commitHash, hadConflicts }` |
|
|
168
|
-
| `post-stash` | `{ action, ok }` |
|
|
169
|
-
|
|
170
|
-
### Low-level events
|
|
171
|
-
|
|
172
|
-
Fire-and-forget events emitted on every object/ref write. Handler errors are caught and forwarded to `hooks.onError` (no-op by default).
|
|
173
|
-
|
|
174
|
-
| Event | Payload |
|
|
175
|
-
| -------------- | --------------------------- |
|
|
176
|
-
| `ref:update` | `{ ref, oldHash, newHash }` |
|
|
177
|
-
| `ref:delete` | `{ ref, oldHash }` |
|
|
178
|
-
| `object:write` | `{ type, hash }` |
|
|
180
|
+
Concurrent pushes to the same remote are automatically serialized — if two agents push simultaneously, one succeeds and the other gets a proper non-fast-forward rejection, just like real git.
|
|
181
|
+
|
|
182
|
+
See [`examples/multi-agent.ts`](examples/multi-agent.ts) for a full working example with a coordinator agent that merges feature branches.
|
|
179
183
|
|
|
180
184
|
## Command coverage
|
|
181
185
|
|
|
182
|
-
|
|
186
|
+
See [CLI.md](CLI.md) for full usage details.
|
|
183
187
|
|
|
184
188
|
| Command | Flags / options |
|
|
185
189
|
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
@@ -221,6 +225,7 @@ Fire-and-forget events emitted on every object/ref write. Handler errors are cau
|
|
|
221
225
|
### Transport
|
|
222
226
|
|
|
223
227
|
- **Local paths** -- direct filesystem transfer between repositories.
|
|
228
|
+
- **Cross-VFS** -- clone, fetch, and push between isolated in-memory filesystems via `resolveRemote`. See [Multi-agent collaboration](#multi-agent-collaboration).
|
|
224
229
|
- **Smart HTTP** -- clone, fetch, and push against real Git servers (e.g. GitHub) via Git Smart HTTP protocol. Auth via `credentials` option or `GIT_HTTP_BEARER_TOKEN` / `GIT_HTTP_USER` + `GIT_HTTP_PASSWORD` env vars.
|
|
225
230
|
|
|
226
231
|
### Internals
|
|
@@ -233,12 +238,30 @@ Fire-and-forget events emitted on every object/ref write. Handler errors are cau
|
|
|
233
238
|
- Packfiles with zlib compression for storage and transport
|
|
234
239
|
- Pathspec globs across `add`, `rm`, `diff`, `reset`, `checkout`, `restore`, `log`
|
|
235
240
|
|
|
236
|
-
##
|
|
241
|
+
## Testing
|
|
242
|
+
|
|
243
|
+
Targets high fidelity to real git (2.53.0). Tested with an [oracle framework](test/oracle/README.md) that generates hundreds of randomized git workflows totaling hundreds of thousands of operations, runs them against real git, then replays each step against just-git and compares repository state and command output. State comparison covers HEAD, refs, index, worktree, active operation state, and stash. Output comparison covers exit codes, stdout, and stderr.
|
|
244
|
+
|
|
245
|
+
When backed by a real filesystem (e.g. just-bash `ReadWriteFs`), interoperable with real git on the same repo, though less extensively tested than behavioral correctness.
|
|
237
246
|
|
|
238
|
-
|
|
247
|
+
## Without just-bash
|
|
239
248
|
|
|
240
|
-
|
|
249
|
+
`git.execute()` takes an args array and a `CommandContext`. Provide any `FileSystem` implementation:
|
|
250
|
+
|
|
251
|
+
```ts
|
|
252
|
+
import { createGit } from "just-git";
|
|
253
|
+
|
|
254
|
+
const git = createGit({ identity: { name: "Bot", email: "bot@example.com" } });
|
|
255
|
+
|
|
256
|
+
const result = await git.execute(["init"], {
|
|
257
|
+
fs: myFileSystem, // any FileSystem implementation
|
|
258
|
+
cwd: "/repo",
|
|
259
|
+
env: new Map(),
|
|
260
|
+
stdin: "",
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
console.log(result.exitCode); // 0
|
|
264
|
+
```
|
|
241
265
|
|
|
242
|
-
|
|
266
|
+
The `FileSystem` interface requires: `readFile`, `readFileBuffer`, `writeFile`, `exists`, `stat`, `mkdir`, `readdir`, `rm`. Optional: `lstat`, `readlink`, `symlink`.
|
|
243
267
|
|
|
244
|
-
This project is not affiliated with [just-bash](https://github.com/vercel-labs/just-bash) or Vercel.
|
package/dist/index.d.ts
CHANGED
|
@@ -28,10 +28,37 @@ interface FileSystem {
|
|
|
28
28
|
symlink?(target: string, path: string): Promise<void>;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Git object storage: compressed loose objects for new writes, with
|
|
33
|
+
* retained packfiles from fetch/clone. Reads check loose first,
|
|
34
|
+
* then fall back to pack indices.
|
|
35
|
+
*/
|
|
36
|
+
declare class PackedObjectStore {
|
|
37
|
+
private fs;
|
|
38
|
+
private gitDir;
|
|
39
|
+
private hooks?;
|
|
40
|
+
private packs;
|
|
41
|
+
private loadedPackNames;
|
|
42
|
+
private discoverPromise;
|
|
43
|
+
constructor(fs: FileSystem, gitDir: string, hooks?: HookEmitter | undefined);
|
|
44
|
+
write(type: ObjectType, content: Uint8Array): Promise<ObjectId>;
|
|
45
|
+
read(hash: ObjectId): Promise<RawObject>;
|
|
46
|
+
exists(hash: ObjectId): Promise<boolean>;
|
|
47
|
+
ingestPack(packData: Uint8Array): Promise<number>;
|
|
48
|
+
/** Scan `.git/objects/pack/` for existing pack/idx pairs. */
|
|
49
|
+
private discover;
|
|
50
|
+
private doDiscover;
|
|
51
|
+
}
|
|
52
|
+
|
|
31
53
|
/** 40-character lowercase hex SHA-1 hash. */
|
|
32
54
|
type ObjectId = string;
|
|
33
55
|
/** The four Git object types. */
|
|
34
56
|
type ObjectType = "blob" | "tree" | "commit" | "tag";
|
|
57
|
+
/** An object as stored in .git/objects — type + raw content bytes. */
|
|
58
|
+
interface RawObject {
|
|
59
|
+
type: ObjectType;
|
|
60
|
+
content: Uint8Array;
|
|
61
|
+
}
|
|
35
62
|
/** Author or committer identity with timestamp. */
|
|
36
63
|
interface Identity {
|
|
37
64
|
name: string;
|
|
@@ -68,6 +95,32 @@ interface Index {
|
|
|
68
95
|
version: number;
|
|
69
96
|
entries: IndexEntry[];
|
|
70
97
|
}
|
|
98
|
+
/**
|
|
99
|
+
* Bundles the filesystem handle with resolved repository paths.
|
|
100
|
+
* Threaded through all library functions so they don't need to
|
|
101
|
+
* re-discover the .git directory on every call.
|
|
102
|
+
*/
|
|
103
|
+
interface GitContext {
|
|
104
|
+
fs: FileSystem;
|
|
105
|
+
/** Absolute path to the .git directory. */
|
|
106
|
+
gitDir: string;
|
|
107
|
+
/** Absolute path to the working tree root, or null for bare repos. */
|
|
108
|
+
workTree: string | null;
|
|
109
|
+
/** Hook emitter for operation hooks and low-level events. */
|
|
110
|
+
hooks?: HookEmitter;
|
|
111
|
+
/** Operator-provided credential resolver (bypasses env vars). */
|
|
112
|
+
credentialProvider?: CredentialProvider;
|
|
113
|
+
/** Operator-provided identity override for author/committer. */
|
|
114
|
+
identityOverride?: IdentityOverride;
|
|
115
|
+
/** Custom fetch function for HTTP transport. Falls back to globalThis.fetch. */
|
|
116
|
+
fetchFn?: FetchFunction;
|
|
117
|
+
/** Network access policy. `false` blocks all HTTP access. */
|
|
118
|
+
networkPolicy?: NetworkPolicy | false;
|
|
119
|
+
/** Resolves remote URLs to GitContexts on potentially different VFS instances. */
|
|
120
|
+
resolveRemote?: RemoteResolver;
|
|
121
|
+
/** Cached object store instance. Lazily created by object-db. */
|
|
122
|
+
objectStore?: PackedObjectStore;
|
|
123
|
+
}
|
|
71
124
|
|
|
72
125
|
type HttpAuth = {
|
|
73
126
|
type: "basic";
|
|
@@ -90,6 +143,12 @@ interface IdentityOverride {
|
|
|
90
143
|
email: string;
|
|
91
144
|
locked?: boolean;
|
|
92
145
|
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolves a remote URL to a GitContext, enabling cross-VFS transport.
|
|
148
|
+
* Called before local filesystem lookup for non-HTTP URLs.
|
|
149
|
+
* Return null to fall back to local filesystem resolution.
|
|
150
|
+
*/
|
|
151
|
+
type RemoteResolver = (url: string) => GitContext | null | Promise<GitContext | null>;
|
|
93
152
|
type FetchFunction = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
|
|
94
153
|
interface NetworkPolicy {
|
|
95
154
|
/**
|
|
@@ -366,6 +425,12 @@ interface GitOptions {
|
|
|
366
425
|
disabled?: GitCommandName[];
|
|
367
426
|
/** Network policy. Set to `false` to block all HTTP access. */
|
|
368
427
|
network?: NetworkPolicy | false;
|
|
428
|
+
/**
|
|
429
|
+
* Resolve a remote URL to a GitContext on a potentially different VFS.
|
|
430
|
+
* Called before local filesystem lookup for non-HTTP remote URLs.
|
|
431
|
+
* Return null to fall back to local filesystem resolution.
|
|
432
|
+
*/
|
|
433
|
+
resolveRemote?: RemoteResolver;
|
|
369
434
|
}
|
|
370
435
|
/**
|
|
371
436
|
* Bundle of operator-level extensions threaded into command handlers
|
|
@@ -377,6 +442,7 @@ interface GitExtensions {
|
|
|
377
442
|
identityOverride?: IdentityOverride;
|
|
378
443
|
fetchFn?: FetchFunction;
|
|
379
444
|
networkPolicy?: NetworkPolicy | false;
|
|
445
|
+
resolveRemote?: RemoteResolver;
|
|
380
446
|
}
|
|
381
447
|
declare class Git {
|
|
382
448
|
readonly name = "git";
|
|
@@ -392,4 +458,12 @@ declare class Git {
|
|
|
392
458
|
}
|
|
393
459
|
declare function createGit(options?: GitOptions): Git;
|
|
394
460
|
|
|
395
|
-
|
|
461
|
+
/**
|
|
462
|
+
* Walk up from `startPath` looking for a git repository.
|
|
463
|
+
* Checks for both normal repos (`.git/` subdirectory) and bare repos
|
|
464
|
+
* (`HEAD` + `objects/` + `refs/` directly in the directory).
|
|
465
|
+
* Returns a GitContext if found, null otherwise.
|
|
466
|
+
*/
|
|
467
|
+
declare function findGitDir(fs: FileSystem, startPath: string): Promise<GitContext | null>;
|
|
468
|
+
|
|
469
|
+
export { type AbortResult, type CommandContext, type CommandEvent, type CommandExecOptions, type CommitMsgEvent, type CredentialProvider, type ExecResult, type FetchFunction, type FileStat, type FileSystem, Git, type GitCommandName, type GitContext, type GitExtensions, type GitOptions, type HookEventMap, type HookHandler, type IdentityOverride, type MergeMsgEvent, type Middleware, type NetworkPolicy, type ObjectWriteEvent, type PostCheckoutEvent, type PostCherryPickEvent, type PostCleanEvent, type PostCloneEvent, type PostCommitEvent, type PostFetchEvent, type PostMergeEvent, type PostPullEvent, type PostPushEvent, type PostResetEvent, type PostRevertEvent, type PostRmEvent, type PostStashEvent, type PreCheckoutEvent, type PreCherryPickEvent, type PreCleanEvent, type PreCloneEvent, type PreCommitEvent, type PreFetchEvent, type PreMergeCommitEvent, type PrePullEvent, type PrePushEvent, type PreRebaseEvent, type PreResetEvent, type PreRevertEvent, type PreRmEvent, type PreStashEvent, type RefDeleteEvent, type RefUpdateEvent, type RemoteResolver, createGit, findGitDir };
|