git-chopstick-core 0.1.2 → 0.1.4

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.
Files changed (145) hide show
  1. package/README.md +42 -10
  2. package/dist/git/apply.d.ts +1 -1
  3. package/dist/git/apply.js +1 -1
  4. package/dist/git/apply.js.map +1 -1
  5. package/dist/git/environment.d.ts +1 -1
  6. package/dist/git/environment.js +1 -1
  7. package/dist/git/environment.js.map +1 -1
  8. package/dist/git/exec.js.map +1 -1
  9. package/dist/git/gitignore.js +1 -1
  10. package/dist/git/gitignore.js.map +1 -1
  11. package/dist/git/index.d.ts +1 -0
  12. package/dist/git/index.js +3 -0
  13. package/dist/git/index.js.map +1 -1
  14. package/dist/lib/fatal-error.d.ts +1 -1
  15. package/dist/lib/fatal-error.js +1 -1
  16. package/dist/lib/fatal-error.js.map +1 -1
  17. package/dist/lib/progress/from-process.js.map +1 -1
  18. package/dist/lib/progress/index.d.ts +5 -5
  19. package/dist/lib/progress/index.js +5 -5
  20. package/dist/lib/progress/index.js.map +1 -1
  21. package/dist/lib/progress/revert.d.ts +1 -1
  22. package/dist/lib/progress/revert.js +1 -1
  23. package/dist/lib/progress/revert.js.map +1 -1
  24. package/dist/lib/status-parser.js +0 -12
  25. package/dist/lib/status-parser.js.map +1 -1
  26. package/dist/models/repository.d.ts +1 -1
  27. package/dist/models/repository.js +1 -1
  28. package/dist/models/repository.js.map +1 -1
  29. package/package.json +39 -9
  30. package/src/git/add.ts +0 -16
  31. package/src/git/apply.ts +0 -154
  32. package/src/git/authentication.ts +0 -20
  33. package/src/git/branch.ts +0 -206
  34. package/src/git/checkout-index.ts +0 -40
  35. package/src/git/checkout.ts +0 -235
  36. package/src/git/cherry-pick.ts +0 -504
  37. package/src/git/clean.ts +0 -9
  38. package/src/git/clone.ts +0 -86
  39. package/src/git/coerce-to-buffer.ts +0 -4
  40. package/src/git/coerce-to-string.ts +0 -4
  41. package/src/git/commit.ts +0 -136
  42. package/src/git/config.ts +0 -392
  43. package/src/git/core.ts +0 -625
  44. package/src/git/create-tail-stream.ts +0 -36
  45. package/src/git/credential.ts +0 -83
  46. package/src/git/description.ts +0 -33
  47. package/src/git/diff-check.ts +0 -27
  48. package/src/git/diff-index.ts +0 -116
  49. package/src/git/diff.ts +0 -880
  50. package/src/git/environment.ts +0 -116
  51. package/src/git/exec.ts +0 -285
  52. package/src/git/fetch.ts +0 -141
  53. package/src/git/for-each-ref.ts +0 -160
  54. package/src/git/format-patch.ts +0 -17
  55. package/src/git/git-delimiter-parser.ts +0 -95
  56. package/src/git/gitignore.ts +0 -157
  57. package/src/git/index.ts +0 -46
  58. package/src/git/init.ts +0 -11
  59. package/src/git/interpret-trailers.ts +0 -176
  60. package/src/git/lfs.ts +0 -100
  61. package/src/git/log.ts +0 -376
  62. package/src/git/merge-tree.ts +0 -42
  63. package/src/git/merge.ts +0 -154
  64. package/src/git/multi-operation-terminal-output.ts +0 -68
  65. package/src/git/pull.ts +0 -130
  66. package/src/git/push-terminal-chunk.ts +0 -41
  67. package/src/git/push.ts +0 -119
  68. package/src/git/rebase.ts +0 -627
  69. package/src/git/reflog.ts +0 -127
  70. package/src/git/refs.ts +0 -63
  71. package/src/git/remote.ts +0 -143
  72. package/src/git/reorder.ts +0 -153
  73. package/src/git/reset.ts +0 -101
  74. package/src/git/rev-list.ts +0 -201
  75. package/src/git/rev-parse.ts +0 -92
  76. package/src/git/revert.ts +0 -55
  77. package/src/git/rm.ts +0 -31
  78. package/src/git/show.ts +0 -88
  79. package/src/git/spawn.ts +0 -38
  80. package/src/git/squash.ts +0 -173
  81. package/src/git/stage.ts +0 -97
  82. package/src/git/stash.ts +0 -302
  83. package/src/git/status.ts +0 -502
  84. package/src/git/submodule.ts +0 -212
  85. package/src/git/tag.ts +0 -134
  86. package/src/git/update-index.ts +0 -169
  87. package/src/git/update-ref.ts +0 -50
  88. package/src/git/var.ts +0 -42
  89. package/src/git/worktree-include.ts +0 -146
  90. package/src/git/worktree.ts +0 -219
  91. package/src/index.ts +0 -11
  92. package/src/lib/api.ts +0 -7
  93. package/src/lib/diff-parser.ts +0 -249
  94. package/src/lib/directory-exists.ts +0 -10
  95. package/src/lib/errno-exception.ts +0 -12
  96. package/src/lib/fatal-error.ts +0 -23
  97. package/src/lib/feature-flag.ts +0 -29
  98. package/src/lib/file-system.ts +0 -7
  99. package/src/lib/get-old-path.ts +0 -11
  100. package/src/lib/git/environment.ts +0 -14
  101. package/src/lib/git-perf.ts +0 -3
  102. package/src/lib/helpers/default-branch.ts +0 -3
  103. package/src/lib/helpers/path.ts +0 -5
  104. package/src/lib/hooks/with-hooks-env.ts +0 -7
  105. package/src/lib/merge.ts +0 -3
  106. package/src/lib/noop.ts +0 -1
  107. package/src/lib/patch-formatter.ts +0 -18
  108. package/src/lib/path-exists.ts +0 -7
  109. package/src/lib/progress/from-process.ts +0 -10
  110. package/src/lib/progress/index.ts +0 -43
  111. package/src/lib/progress/revert.ts +0 -17
  112. package/src/lib/rebase.ts +0 -3
  113. package/src/lib/remove-remote-prefix.ts +0 -4
  114. package/src/lib/resolve-git-proxy.ts +0 -3
  115. package/src/lib/round.ts +0 -4
  116. package/src/lib/split-buffer.ts +0 -14
  117. package/src/lib/status-parser.ts +0 -188
  118. package/src/lib/stores/helpers/find-default-remote.ts +0 -3
  119. package/src/lib/trampoline/trampoline-environment.ts +0 -8
  120. package/src/models/branch.ts +0 -78
  121. package/src/models/cherry-pick.ts +0 -12
  122. package/src/models/clone-options.ts +0 -6
  123. package/src/models/commit-identity.ts +0 -35
  124. package/src/models/commit.ts +0 -44
  125. package/src/models/computed-action.ts +0 -6
  126. package/src/models/diff/diff-data.ts +0 -78
  127. package/src/models/diff/diff-line.ts +0 -36
  128. package/src/models/diff/diff-selection.ts +0 -165
  129. package/src/models/diff/image-diff.ts +0 -6
  130. package/src/models/diff/image.ts +0 -8
  131. package/src/models/diff/index.ts +0 -6
  132. package/src/models/diff/raw-diff.ts +0 -41
  133. package/src/models/git-author.ts +0 -16
  134. package/src/models/index.ts +0 -36
  135. package/src/models/manual-conflict-resolution.ts +0 -4
  136. package/src/models/merge.ts +0 -6
  137. package/src/models/multi-commit-operation.ts +0 -6
  138. package/src/models/progress.ts +0 -67
  139. package/src/models/rebase.ts +0 -20
  140. package/src/models/remote.ts +0 -10
  141. package/src/models/repository.ts +0 -16
  142. package/src/models/stash-entry.ts +0 -25
  143. package/src/models/status.ts +0 -275
  144. package/src/models/submodule.ts +0 -13
  145. package/src/models/worktree.ts +0 -11
@@ -1,116 +0,0 @@
1
- import { envForAuthentication } from './authentication.js'
2
- import { resolveGitProxy as resolveGitProxyFn } from '../lib/resolve-git-proxy.js'
3
- import { getHTMLURL } from '../lib/api.js'
4
- import { Repository } from '../models/repository.js'
5
- import { IRemote } from '../models/remote.js'
6
-
7
- /**
8
- * For many remote operations it's well known what the primary remote
9
- * url is (clone, push, fetch etc). But in some cases it's not as easy.
10
- *
11
- * Two examples are checkout, and revert where neither would need to
12
- * hit the network in vanilla Git usage but do need to when LFS gets
13
- * involved.
14
- *
15
- * What's the primary url when using LFS then? Most likely it's gonna
16
- * be on the same as the default remote but it could theoretically
17
- * be on a different server as well. That's too advanced for our usage
18
- * at the moment though so we'll just need to figure out some reasonable
19
- * url to fall back on.
20
- *
21
- * @param branchName If the operation we're about to undertake is related to a
22
- * local ref (i.e branch) then we can use that to resolve its
23
- * upstream tracking branch (and thereby its remote) and use
24
- * that as the probable url to resolve a proxy for.
25
- */
26
- export function getFallbackUrlForProxyResolve(
27
- _repository: Repository,
28
- currentRemote: IRemote | null
29
- ) {
30
- if (currentRemote) {
31
- return currentRemote.url
32
- }
33
- return 'https://github.com'
34
- }
35
-
36
- /**
37
- * Create a set of environment variables to use when invoking a Git
38
- * subcommand that needs to communicate with a remote (i.e. fetch, clone,
39
- * push, pull, ls-remote, etc etc).
40
- *
41
- * The environment variables deal with setting up sane defaults, configuring
42
- * authentication, and resolving proxy urls if necessary.
43
- *
44
- * @param account The authentication information (if available) to provide
45
- * to Git for use when connecting to the remote
46
- * @param remoteUrl The primary remote URL for this operation. Note that Git
47
- * might connect to other remotes in order to fulfill the
48
- * operation. As an example, a clone of
49
- * https://github.com/desktop/desktop could contain a submodule
50
- * pointing to another host entirely. Used to resolve which
51
- * proxy (if any) should be used for the operation.
52
- */
53
- export async function envForRemoteOperation(remoteUrl: string | null): Promise<Record<string, string | undefined>> {
54
- return {
55
- ...envForAuthentication(),
56
- ...(await envForProxy(remoteUrl ?? 'https://github.com')),
57
- }
58
- }
59
-
60
- /**
61
- * Not intended to be used directly. Exported only in order to
62
- * allow for testing.
63
- *
64
- * @param remoteUrl The remote url to resolve a proxy for.
65
- * @param env The current environment variables, defaults
66
- * to `process.env`
67
- * @param resolve The method to use when resolving the proxy url,
68
- * defaults to `resolveGitProxy`
69
- */
70
- export async function envForProxy(
71
- remoteUrl: string,
72
- env: NodeJS.ProcessEnv = process.env,
73
- resolve: (url: string) => Promise<string | undefined> = async (url: string) => resolveGitProxyFn() ?? undefined
74
- ): Promise<Record<string, string | undefined> | undefined> {
75
- const protocolMatch = /^(https?):\/\//i.exec(remoteUrl)
76
-
77
- // We can only resolve and use a proxy for the protocols where cURL
78
- // would be involved (i.e http and https). git:// relies on ssh.
79
- if (protocolMatch === null) {
80
- return
81
- }
82
-
83
- // Note that HTTPS here doesn't mean that the proxy is HTTPS, only
84
- // that all requests to HTTPS protocols should be proxied. The
85
- // proxy protocol is defined by the url returned by `this.resolve()`
86
- const proto = protocolMatch[1].toLowerCase() // http or https
87
-
88
- // We'll play it safe and say that if the user has configured
89
- // the ALL_PROXY environment variable they probably know what
90
- // they're doing and wouldn't want us to override it with a
91
- // protocol-specific proxy. cURL supports both lower and upper
92
- // case, see:
93
- // https://github.com/curl/curl/blob/14916a82e/lib/url.c#L2180-L2185
94
- if ('ALL_PROXY' in env || 'all_proxy' in env) {
95
- console.info(`proxy url not resolved, ALL_PROXY already set`)
96
- return
97
- }
98
-
99
- // Lower case environment variables due to
100
- // https://ec.haxx.se/usingcurl/usingcurl-proxies#http_proxy-in-lower-case-only
101
- const envKey = `${proto}_proxy` // http_proxy or https_proxy
102
-
103
- // If the user has already configured a proxy in the environment
104
- // for the protocol we're not gonna override it.
105
- if (envKey in env || (proto === 'https' && 'HTTPS_PROXY' in env)) {
106
- console.info(`proxy url not resolved, ${envKey} already set`)
107
- return
108
- }
109
-
110
- const proxyUrl = await resolve(remoteUrl).catch(err => {
111
- console.error('Failed resolving Git proxy', err)
112
- return undefined
113
- })
114
-
115
- return proxyUrl === undefined ? undefined : { [envKey]: proxyUrl }
116
- }
package/src/git/exec.ts DELETED
@@ -1,285 +0,0 @@
1
- import { spawn, SpawnOptions } from 'child_process'
2
-
3
- /**
4
- * Git error types parsed from stderr output.
5
- * This is a simplified version of dugite's GitError enum.
6
- */
7
- export enum GitError {
8
- // Authentication
9
- SSHAuthenticationFailed = 'SSHAuthenticationFailed',
10
- SSHPermissionDenied = 'SSHPermissionDenied',
11
- HTTPSAuthenticationFailed = 'HTTPSAuthenticationFailed',
12
- SSHKeyAuditUnverified = 'SSHKeyAuditUnverified',
13
-
14
- // Remote
15
- RemoteDisconnection = 'RemoteDisconnection',
16
- HostDown = 'HostDown',
17
- HTTPSRepositoryNotFound = 'HTTPSRepositoryNotFound',
18
- SSHRepositoryNotFound = 'SSHRepositoryNotFound',
19
-
20
- // Push / Pull
21
- PushNotFastForward = 'PushNotFastForward',
22
- PushWithFileSizeExceedingLimit = 'PushWithFileSizeExceedingLimit',
23
- PushWithPrivateEmail = 'PushWithPrivateEmail',
24
- PushWithSecretDetected = 'PushWithSecretDetected',
25
- ForcePushRejected = 'ForcePushRejected',
26
- ProtectedBranchForcePush = 'ProtectedBranchForcePush',
27
- ProtectedBranchRequiresReview = 'ProtectedBranchRequiresReview',
28
- ProtectedBranchDeleteRejected = 'ProtectedBranchDeleteRejected',
29
- ProtectedBranchRequiredStatus = 'ProtectedBranchRequiredStatus',
30
-
31
- // Branch
32
- BranchDeletionFailed = 'BranchDeletionFailed',
33
- DefaultBranchDeletionFailed = 'DefaultBranchDeletionFailed',
34
- BranchAlreadyExists = 'BranchAlreadyExists',
35
- BranchRenameFailed = 'BranchRenameFailed',
36
- HexBranchNameRejected = 'HexBranchNameRejected',
37
- InvalidRefLength = 'InvalidRefLength',
38
-
39
- // Merge / Rebase
40
- MergeConflicts = 'MergeConflicts',
41
- RebaseConflicts = 'RebaseConflicts',
42
- MergeWithLocalChanges = 'MergeWithLocalChanges',
43
- RebaseWithLocalChanges = 'RebaseWithLocalChanges',
44
- InvalidMerge = 'InvalidMerge',
45
- InvalidRebase = 'InvalidRebase',
46
- NonFastForwardMergeIntoEmptyHead = 'NonFastForwardMergeIntoEmptyHead',
47
- CannotMergeUnrelatedHistories = 'CannotMergeUnrelatedHistories',
48
- NoMergeToAbort = 'NoMergeToAbort',
49
- RevertConflicts = 'RevertConflicts',
50
-
51
- // Rebase
52
- EmptyRebasePatch = 'EmptyRebasePatch',
53
-
54
- // Commit
55
- NothingToCommit = 'NothingToCommit',
56
- GPGFailedToSignData = 'GPGFailedToSignData',
57
-
58
- // Bad config
59
- BadConfigValue = 'BadConfigValue',
60
- ConfigLockFileAlreadyExists = 'ConfigLockFileAlreadyExists',
61
-
62
- // Misc
63
- NotAGitRepository = 'NotAGitRepository',
64
- BadRevision = 'BadRevision',
65
- LocalPermissionDenied = 'LocalPermissionDenied',
66
- NoMatchingRemoteBranch = 'NoMatchingRemoteBranch',
67
- NoExistingRemoteBranch = 'NoExistingRemoteBranch',
68
- PatchDoesNotApply = 'PatchDoesNotApply',
69
- NoSubmoduleMapping = 'NoSubmoduleMapping',
70
- SubmoduleRepositoryDoesNotExist = 'SubmoduleRepositoryDoesNotExist',
71
- InvalidSubmoduleSHA = 'InvalidSubmoduleSHA',
72
- LockFileAlreadyExists = 'LockFileAlreadyExists',
73
- UnresolvedConflicts = 'UnresolvedConflicts',
74
- LocalChangesOverwritten = 'LocalChangesOverwritten',
75
- RemoteAlreadyExists = 'RemoteAlreadyExists',
76
- TagAlreadyExists = 'TagAlreadyExists',
77
- PathDoesNotExist = 'PathDoesNotExist',
78
- InvalidObjectName = 'InvalidObjectName',
79
- OutsideRepository = 'OutsideRepository',
80
- ConflictModifyDeletedInBranch = 'ConflictModifyDeletedInBranch',
81
- MergeCommitNoMainlineOption = 'MergeCommitNoMainlineOption',
82
- UnsafeDirectory = 'UnsafeDirectory',
83
- PathExistsButNotInRef = 'PathExistsButNotInRef',
84
- LFSAttributeDoesNotMatch = 'LFSAttributeDoesNotMatch',
85
- }
86
-
87
- export class ExecError extends Error {
88
- public readonly code: string
89
- public readonly stdout: string | Buffer
90
- public readonly stderr: string | Buffer
91
- public readonly cause?: Error
92
-
93
- constructor(
94
- message: string,
95
- stdout: string | Buffer,
96
- stderr: string | Buffer,
97
- cause?: Error
98
- ) {
99
- super(message)
100
- this.name = 'ExecError'
101
- this.code = 'ERR_CHILD_PROCESS_STDIO_MAXBUFFER'
102
- this.stdout = stdout
103
- this.stderr = stderr
104
- this.cause = cause
105
- }
106
- }
107
-
108
- export interface IGitResult {
109
- readonly stdout: string | Buffer
110
- readonly stderr: string | Buffer
111
- readonly exitCode: number
112
- }
113
-
114
- export interface IGitExecutionOptions {
115
- readonly env?: Record<string, string | undefined>
116
- readonly cwd?: string
117
- readonly stdin?: string
118
- readonly maxBuffer?: number
119
- readonly processCallback?: (process: any) => void
120
- readonly encoding?: BufferEncoding
121
- }
122
-
123
- export interface IGitSpawnOptions extends SpawnOptions {
124
- readonly stdin?: string
125
- }
126
-
127
- /**
128
- * Execute a git command and return the result.
129
- */
130
- export async function exec(
131
- args: string[],
132
- path: string,
133
- options?: IGitExecutionOptions
134
- ): Promise<IGitResult> {
135
- return new Promise((resolve, reject) => {
136
- const child = spawn('git', args, {
137
- cwd: path,
138
- env: {
139
- ...process.env,
140
- TERM: 'dumb',
141
- ...options?.env,
142
- } as Record<string, string>,
143
- stdio: ['pipe', 'pipe', 'pipe'],
144
- })
145
-
146
- const stdoutChunks: Buffer[] = []
147
- const stderrChunks: Buffer[] = []
148
-
149
- child.stdout?.on('data', (chunk: Buffer) => stdoutChunks.push(chunk))
150
- child.stderr?.on('data', (chunk: Buffer) => stderrChunks.push(chunk))
151
-
152
- if (options?.processCallback) {
153
- options.processCallback(child)
154
- }
155
-
156
- if (options?.stdin) {
157
- child.stdin?.write(options.stdin)
158
- child.stdin?.end()
159
- }
160
-
161
- child.on('close', (exitCode) => {
162
- const stdoutBuf = Buffer.concat(stdoutChunks)
163
- const stderrBuf = Buffer.concat(stderrChunks)
164
-
165
- const enc = (options as any)?.encoding
166
- const isBuffer = enc === 'buffer'
167
-
168
- resolve({
169
- stdout: isBuffer ? stdoutBuf : stdoutBuf.toString(options?.encoding || 'utf-8'),
170
- stderr: isBuffer ? stderrBuf : stderrBuf.toString(options?.encoding || 'utf-8'),
171
- exitCode: exitCode ?? -1,
172
- })
173
- })
174
-
175
- child.on('error', (err: Error) => {
176
- reject(err)
177
- })
178
- })
179
- }
180
-
181
- /**
182
- * Spawn a git process, returning the ChildProcess for streaming access.
183
- */
184
- export function spawnGit(
185
- args: string[],
186
- path: string,
187
- options?: IGitSpawnOptions
188
- ) {
189
- return spawn('git', args, {
190
- ...options,
191
- cwd: path,
192
- env: {
193
- ...process.env,
194
- TERM: 'dumb',
195
- ...options?.env,
196
- } as Record<string, string>,
197
- })
198
- }
199
-
200
- /**
201
- * Parse git stderr output into a GitError enum value.
202
- */
203
- export function parseError(stderr: string): GitError | null {
204
- if (!stderr) return null
205
-
206
- // Authentication errors
207
- if (stderr.includes('Permission denied (publickey)'))
208
- return GitError.SSHPermissionDenied
209
- if (stderr.includes('fatal: Could not read from remote repository'))
210
- return GitError.SSHAuthenticationFailed
211
- if (stderr.includes('Authentication failed'))
212
- return GitError.HTTPSAuthenticationFailed
213
-
214
- // Merge conflicts
215
- if (stderr.includes('Automatic merge failed'))
216
- return GitError.MergeConflicts
217
- if (stderr.includes('merge failed')) return GitError.MergeConflicts
218
- if (stderr.includes('conflict')) return GitError.MergeConflicts
219
-
220
- // Rebase
221
- if (stderr.includes('could not apply'))
222
- return GitError.RebaseConflicts
223
- if (stderr.includes('interactive rebase already started'))
224
- return GitError.RebaseConflicts
225
-
226
- // Push
227
- if (stderr.includes('push is not fast forward') || stderr.includes('[rejected]'))
228
- return GitError.PushNotFastForward
229
- if (stderr.includes('failed to push'))
230
- return GitError.PushNotFastForward
231
-
232
- // Remote
233
- if (stderr.includes('Could not resolve host'))
234
- return GitError.RemoteDisconnection
235
- if (stderr.includes('host down')) return GitError.HostDown
236
- if (stderr.includes('Repository not found'))
237
- return GitError.HTTPSRepositoryNotFound
238
- if (stderr.includes('not found')) return GitError.HTTPSRepositoryNotFound
239
-
240
- // Branch
241
- if (stderr.includes('branch .* already exists'))
242
- return GitError.BranchAlreadyExists
243
- if (stderr.includes('not a valid branch'))
244
- return GitError.BranchDeletionFailed
245
- if (stderr.includes('could not delete'))
246
- return GitError.BranchDeletionFailed
247
-
248
- // Config
249
- if (stderr.includes('bad config value'))
250
- return GitError.BadConfigValue
251
- if (stderr.includes('bad numeric config value'))
252
- return GitError.BadConfigValue
253
- if (stderr.includes('config file lock'))
254
- return GitError.ConfigLockFileAlreadyExists
255
-
256
- // Misc
257
- if (stderr.includes('fatal: not a git repository'))
258
- return GitError.NotAGitRepository
259
- if (stderr.includes('bad revision'))
260
- return GitError.BadRevision
261
- if (stderr.includes('nothing to commit'))
262
- return GitError.NothingToCommit
263
- if (stderr.includes('Permission denied'))
264
- return GitError.LocalPermissionDenied
265
- if (stderr.includes('pathspec .* did not match'))
266
- return GitError.PathDoesNotExist
267
- if (stderr.includes('did not match any files'))
268
- return GitError.PathDoesNotExist
269
-
270
- return null
271
- }
272
-
273
- /**
274
- * Parse information about a bad config value error.
275
- */
276
- export function parseBadConfigValueErrorInfo(
277
- stderr: string
278
- ): { key: string; value: string } | null {
279
- const match = stderr.match(
280
- /bad config value for '([^']+)' in ([^:]+):?\s*(.*)/
281
- )
282
- if (!match) return null
283
-
284
- return { key: match[1], value: match[3]?.trim() || '' }
285
- }
package/src/git/fetch.ts DELETED
@@ -1,141 +0,0 @@
1
- import { git, IGitStringExecutionOptions } from './core.js'
2
- import { Repository } from '../models/repository.js'
3
- import { IFetchProgress } from '../models/progress.js'
4
- import { FetchProgressParser, executionOptionsWithProgress } from '../lib/progress/index.js'
5
- import { IRemote } from '../models/remote.js'
6
- import { ITrackingBranch } from '../models/branch.js'
7
- import { envForRemoteOperation } from './environment.js'
8
-
9
- async function getFetchArgs(
10
- remote: string,
11
- progressCallback?: (progress: IFetchProgress) => void
12
- ) {
13
- return [
14
- 'fetch',
15
- ...(progressCallback ? ['--progress'] : []),
16
- '--prune',
17
- '--recurse-submodules=on-demand',
18
- remote,
19
- ]
20
- }
21
-
22
- /**
23
- * Fetch from the given remote.
24
- *
25
- * @param repository - The repository to fetch into
26
- *
27
- * @param account - The account to use when authenticating with the remote
28
- *
29
- * @param remote - The remote to fetch from
30
- *
31
- * @param progressCallback - An optional function which will be invoked
32
- * with information about the current progress
33
- * of the fetch operation. When provided this enables
34
- * the '--progress' command line flag for
35
- * 'git fetch'.
36
- * @param isBackgroundTask - Whether the fetch is being performed as a
37
- * background task as opposed to being user initiated
38
- */
39
- export async function fetch(
40
- repository: Repository,
41
- remote: IRemote,
42
- progressCallback?: (progress: IFetchProgress) => void,
43
- isBackgroundTask = false
44
- ): Promise<void> {
45
- let opts: IGitStringExecutionOptions = {
46
- successExitCodes: new Set([0]),
47
- env: await envForRemoteOperation(remote.url),
48
- }
49
-
50
- if (progressCallback) {
51
- const title = `Fetching ${remote.name}`
52
- const kind = 'fetch'
53
-
54
- opts = await executionOptionsWithProgress(
55
- { ...opts, trackLFSProgress: true, isBackgroundTask },
56
- new FetchProgressParser(),
57
- progress => {
58
- // In addition to progress output from the remote end and from
59
- // git itself, the stderr output from pull contains information
60
- // about ref updates. We don't need to bring those into the progress
61
- // stream so we'll just punt on anything we don't know about for now.
62
- if (progress.kind === 'context') {
63
- if (!progress.text.startsWith('remote: Counting objects')) {
64
- return
65
- }
66
- }
67
-
68
- const description =
69
- progress.kind === 'progress' ? progress.details.text : progress.text
70
- const value = progress.percent
71
-
72
- progressCallback({
73
- kind,
74
- title,
75
- description,
76
- value,
77
- remote: remote.name,
78
- })
79
- }
80
- )
81
-
82
- // Initial progress
83
- progressCallback({ kind, title, value: 0, remote: remote.name })
84
- }
85
-
86
- const args = await getFetchArgs(remote.name, progressCallback)
87
-
88
- await git(args, repository.path, 'fetch', opts)
89
- }
90
-
91
- /** Fetch a given refspec from the given remote. */
92
- export async function fetchRefspec(
93
- repository: Repository,
94
- remote: IRemote,
95
- refspec: string
96
- ): Promise<void> {
97
- await git(['fetch', remote.name, refspec], repository.path, 'fetchRefspec', {
98
- successExitCodes: new Set([0, 128]),
99
- env: await envForRemoteOperation(remote.url),
100
- })
101
- }
102
-
103
- export async function fastForwardBranches(
104
- repository: Repository,
105
- branches: ReadonlyArray<ITrackingBranch>
106
- ): Promise<void> {
107
- if (branches.length === 0) {
108
- return
109
- }
110
-
111
- const refPairs = branches.map(branch => `${branch.upstreamRef}:${branch.ref}`)
112
-
113
- await git(
114
- [
115
- 'fetch',
116
- '.',
117
- // Make sure we don't try to update branches that can't be fast-forwarded
118
- // even if the user disabled this via the git config option
119
- // `fetch.showForcedUpdates`
120
- '--show-forced-updates',
121
- // Prevent `git fetch` from touching the `FETCH_HEAD`
122
- '--no-write-fetch-head',
123
- // Take branch refs from stdin to circumvent shell max line length
124
- // limitations (mainly on Windows)
125
- '--stdin',
126
- ],
127
- repository.path,
128
- 'fastForwardBranches',
129
- {
130
- // Fetch exits with an exit code of 1 if one or more refs failed to update
131
- // which is what we expect will happen
132
- successExitCodes: new Set([0, 1]),
133
- env: {
134
- // This will make sure the reflog entries are correct after
135
- // fast-forwarding the branches.
136
- GIT_REFLOG_ACTION: 'pull',
137
- },
138
- stdin: refPairs.join('\n'),
139
- }
140
- )
141
- }
@@ -1,160 +0,0 @@
1
- import { git } from './core.js'
2
- import { GitError } from './exec.js'
3
- import { Repository } from '../models/repository.js'
4
- import {
5
- Branch,
6
- BranchType,
7
- IBranchTip,
8
- ITrackingBranch,
9
- } from '../models/branch.js'
10
- import { createForEachRefParser } from './git-delimiter-parser.js'
11
-
12
- /** Get all the branches. */
13
- export async function getBranches(
14
- repository: Repository,
15
- ...prefixes: string[]
16
- ): Promise<ReadonlyArray<Branch>> {
17
- const { formatArgs, parse } = createForEachRefParser({
18
- fullName: '%(refname)',
19
- shortName: '%(refname:short)',
20
- upstreamShortName: '%(upstream:short)',
21
- upstreamTrackingBranch: '%(upstream:track)',
22
- sha: '%(objectname)',
23
- symRef: '%(symref)',
24
- authorDate: '%(authordate:iso8601)',
25
- })
26
-
27
- if (!prefixes || !prefixes.length) {
28
- prefixes = ['refs/heads', 'refs/remotes']
29
- }
30
-
31
- // TODO: use expectedErrors here to handle a specific error
32
- // see https://github.com/desktop/desktop/pull/5299#discussion_r206603442 for
33
- // discussion about what needs to change
34
- const result = await git(
35
- ['for-each-ref', ...formatArgs, ...prefixes],
36
- repository.path,
37
- 'getBranches',
38
- { expectedErrors: new Set([GitError.NotAGitRepository]) }
39
- )
40
-
41
- if (result.gitError === GitError.NotAGitRepository) {
42
- return []
43
- }
44
-
45
- const branches = []
46
-
47
- for (const ref of parse(result.stdout)) {
48
- // excude symbolic refs from the branch list
49
- if (ref.symRef.length > 0) {
50
- continue
51
- }
52
-
53
- const tip: IBranchTip = {
54
- sha: ref.sha,
55
- author: {
56
- date: new Date(ref.authorDate),
57
- },
58
- }
59
-
60
- const type = ref.fullName.startsWith('refs/heads')
61
- ? BranchType.Local
62
- : BranchType.Remote
63
-
64
- const upstream =
65
- ref.upstreamShortName.length > 0 ? ref.upstreamShortName : null
66
-
67
- const isGone = ['[gone]', '(gone)'].includes(ref.upstreamTrackingBranch)
68
-
69
- branches.push(
70
- new Branch(ref.shortName, upstream, tip, type, ref.fullName, isGone)
71
- )
72
- }
73
-
74
- return branches
75
- }
76
-
77
- /**
78
- * Gets all branches that differ from their upstream (i.e. they're ahead,
79
- * behind or both), excluding the current branch.
80
- * Useful to narrow down a list of branches that could potentially be fast
81
- * forwarded.
82
- *
83
- * @param repository Repository to get the branches from.
84
- */
85
- export async function getBranchesDifferingFromUpstream(
86
- repository: Repository
87
- ): Promise<ReadonlyArray<ITrackingBranch>> {
88
- const { formatArgs, parse } = createForEachRefParser({
89
- fullName: '%(refname)',
90
- sha: '%(objectname)', // SHA
91
- upstream: '%(upstream)',
92
- symref: '%(symref)',
93
- head: '%(HEAD)',
94
- worktreePath: '%(worktreepath)',
95
- })
96
-
97
- const prefixes = ['refs/heads', 'refs/remotes']
98
-
99
- const result = await git(
100
- ['for-each-ref', ...formatArgs, ...prefixes],
101
- repository.path,
102
- 'getBranchesDifferingFromUpstream',
103
- { expectedErrors: new Set([GitError.NotAGitRepository]) }
104
- )
105
-
106
- if (result.gitError === GitError.NotAGitRepository) {
107
- return []
108
- }
109
-
110
- const localBranches = []
111
- const remoteBranchShas = new Map<string, string>()
112
-
113
- // First we need to collect the relevant info from the command output:
114
- // - For local branches with upstream: name, ref, SHA and the upstream.
115
- // - For remote branches we only need the sha (and the ref as key).
116
- for (const ref of parse(result.stdout)) {
117
- if (ref.symref.length > 0 || ref.head === '*') {
118
- // Exclude symbolic refs and the current branch
119
- continue
120
- }
121
- if (ref.worktreePath.length > 0 && ref.worktreePath !== repository.path) {
122
- // Exclude branches checked out in other worktrees, since they can't be fast-forwarded from here
123
- continue
124
- }
125
-
126
- if (ref.fullName.startsWith('refs/heads')) {
127
- if (ref.upstream.length === 0) {
128
- // Exclude local branches without upstream
129
- continue
130
- }
131
-
132
- localBranches.push({
133
- ref: ref.fullName,
134
- sha: ref.sha,
135
- upstream: ref.upstream,
136
- })
137
- } else {
138
- remoteBranchShas.set(ref.fullName, ref.sha)
139
- }
140
- }
141
-
142
- const eligibleBranches = new Array<ITrackingBranch>()
143
-
144
- // Compare the SHA of every local branch with the SHA of its upstream and
145
- // collect the names of local branches that differ from their upstream.
146
- for (const branch of localBranches) {
147
- const remoteSha = remoteBranchShas.get(branch.upstream)
148
-
149
- if (remoteSha !== undefined && remoteSha !== branch.sha) {
150
- eligibleBranches.push({
151
- ref: branch.ref,
152
- sha: branch.sha,
153
- upstreamRef: branch.upstream,
154
- upstreamSha: remoteSha,
155
- })
156
- }
157
- }
158
-
159
- return eligibleBranches
160
- }