git-chopstick-core 0.1.2 → 0.1.3
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 +6 -6
- package/dist/git/exec.js.map +1 -1
- package/dist/lib/fatal-error.d.ts +1 -1
- package/dist/lib/fatal-error.js +1 -1
- package/dist/lib/fatal-error.js.map +1 -1
- package/dist/lib/progress/from-process.js.map +1 -1
- package/dist/lib/progress/index.d.ts +5 -5
- package/dist/lib/progress/index.js +5 -5
- package/dist/lib/progress/index.js.map +1 -1
- package/dist/lib/status-parser.js +0 -12
- package/dist/lib/status-parser.js.map +1 -1
- package/package.json +38 -8
- package/src/git/add.ts +0 -16
- package/src/git/apply.ts +0 -154
- package/src/git/authentication.ts +0 -20
- package/src/git/branch.ts +0 -206
- package/src/git/checkout-index.ts +0 -40
- package/src/git/checkout.ts +0 -235
- package/src/git/cherry-pick.ts +0 -504
- package/src/git/clean.ts +0 -9
- package/src/git/clone.ts +0 -86
- package/src/git/coerce-to-buffer.ts +0 -4
- package/src/git/coerce-to-string.ts +0 -4
- package/src/git/commit.ts +0 -136
- package/src/git/config.ts +0 -392
- package/src/git/core.ts +0 -625
- package/src/git/create-tail-stream.ts +0 -36
- package/src/git/credential.ts +0 -83
- package/src/git/description.ts +0 -33
- package/src/git/diff-check.ts +0 -27
- package/src/git/diff-index.ts +0 -116
- package/src/git/diff.ts +0 -880
- package/src/git/environment.ts +0 -116
- package/src/git/exec.ts +0 -285
- package/src/git/fetch.ts +0 -141
- package/src/git/for-each-ref.ts +0 -160
- package/src/git/format-patch.ts +0 -17
- package/src/git/git-delimiter-parser.ts +0 -95
- package/src/git/gitignore.ts +0 -157
- package/src/git/index.ts +0 -46
- package/src/git/init.ts +0 -11
- package/src/git/interpret-trailers.ts +0 -176
- package/src/git/lfs.ts +0 -100
- package/src/git/log.ts +0 -376
- package/src/git/merge-tree.ts +0 -42
- package/src/git/merge.ts +0 -154
- package/src/git/multi-operation-terminal-output.ts +0 -68
- package/src/git/pull.ts +0 -130
- package/src/git/push-terminal-chunk.ts +0 -41
- package/src/git/push.ts +0 -119
- package/src/git/rebase.ts +0 -627
- package/src/git/reflog.ts +0 -127
- package/src/git/refs.ts +0 -63
- package/src/git/remote.ts +0 -143
- package/src/git/reorder.ts +0 -153
- package/src/git/reset.ts +0 -101
- package/src/git/rev-list.ts +0 -201
- package/src/git/rev-parse.ts +0 -92
- package/src/git/revert.ts +0 -55
- package/src/git/rm.ts +0 -31
- package/src/git/show.ts +0 -88
- package/src/git/spawn.ts +0 -38
- package/src/git/squash.ts +0 -173
- package/src/git/stage.ts +0 -97
- package/src/git/stash.ts +0 -302
- package/src/git/status.ts +0 -502
- package/src/git/submodule.ts +0 -212
- package/src/git/tag.ts +0 -134
- package/src/git/update-index.ts +0 -169
- package/src/git/update-ref.ts +0 -50
- package/src/git/var.ts +0 -42
- package/src/git/worktree-include.ts +0 -146
- package/src/git/worktree.ts +0 -219
- package/src/index.ts +0 -11
- package/src/lib/api.ts +0 -7
- package/src/lib/diff-parser.ts +0 -249
- package/src/lib/directory-exists.ts +0 -10
- package/src/lib/errno-exception.ts +0 -12
- package/src/lib/fatal-error.ts +0 -23
- package/src/lib/feature-flag.ts +0 -29
- package/src/lib/file-system.ts +0 -7
- package/src/lib/get-old-path.ts +0 -11
- package/src/lib/git/environment.ts +0 -14
- package/src/lib/git-perf.ts +0 -3
- package/src/lib/helpers/default-branch.ts +0 -3
- package/src/lib/helpers/path.ts +0 -5
- package/src/lib/hooks/with-hooks-env.ts +0 -7
- package/src/lib/merge.ts +0 -3
- package/src/lib/noop.ts +0 -1
- package/src/lib/patch-formatter.ts +0 -18
- package/src/lib/path-exists.ts +0 -7
- package/src/lib/progress/from-process.ts +0 -10
- package/src/lib/progress/index.ts +0 -43
- package/src/lib/progress/revert.ts +0 -17
- package/src/lib/rebase.ts +0 -3
- package/src/lib/remove-remote-prefix.ts +0 -4
- package/src/lib/resolve-git-proxy.ts +0 -3
- package/src/lib/round.ts +0 -4
- package/src/lib/split-buffer.ts +0 -14
- package/src/lib/status-parser.ts +0 -188
- package/src/lib/stores/helpers/find-default-remote.ts +0 -3
- package/src/lib/trampoline/trampoline-environment.ts +0 -8
- package/src/models/branch.ts +0 -78
- package/src/models/cherry-pick.ts +0 -12
- package/src/models/clone-options.ts +0 -6
- package/src/models/commit-identity.ts +0 -35
- package/src/models/commit.ts +0 -44
- package/src/models/computed-action.ts +0 -6
- package/src/models/diff/diff-data.ts +0 -78
- package/src/models/diff/diff-line.ts +0 -36
- package/src/models/diff/diff-selection.ts +0 -165
- package/src/models/diff/image-diff.ts +0 -6
- package/src/models/diff/image.ts +0 -8
- package/src/models/diff/index.ts +0 -6
- package/src/models/diff/raw-diff.ts +0 -41
- package/src/models/git-author.ts +0 -16
- package/src/models/index.ts +0 -36
- package/src/models/manual-conflict-resolution.ts +0 -4
- package/src/models/merge.ts +0 -6
- package/src/models/multi-commit-operation.ts +0 -6
- package/src/models/progress.ts +0 -67
- package/src/models/rebase.ts +0 -20
- package/src/models/remote.ts +0 -10
- package/src/models/repository.ts +0 -16
- package/src/models/stash-entry.ts +0 -25
- package/src/models/status.ts +0 -275
- package/src/models/submodule.ts +0 -13
- package/src/models/worktree.ts +0 -11
package/src/git/rev-list.ts
DELETED
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { GitError } from './exec.js'
|
|
2
|
-
import { git } from './core.js'
|
|
3
|
-
import { Repository } from '../models/repository.js'
|
|
4
|
-
import { Branch, BranchType, IAheadBehind } from '../models/branch.js'
|
|
5
|
-
import { CommitOneLine } from '../models/commit.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Convert two refs into the Git range syntax representing the set of commits
|
|
9
|
-
* that are reachable from `to` but excluding those that are reachable from
|
|
10
|
-
* `from`. This will not be inclusive to the `from` ref, see
|
|
11
|
-
* `revRangeInclusive`.
|
|
12
|
-
*
|
|
13
|
-
* Each parameter can be the commit SHA or a ref name, or specify an empty
|
|
14
|
-
* string to represent HEAD.
|
|
15
|
-
*
|
|
16
|
-
* @param from The start of the range
|
|
17
|
-
* @param to The end of the range
|
|
18
|
-
*/
|
|
19
|
-
export function revRange(from: string, to: string) {
|
|
20
|
-
return `${from}..${to}`
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Convert two refs into the Git range syntax representing the set of commits
|
|
25
|
-
* that are reachable from `to` but excluding those that are reachable from
|
|
26
|
-
* `from`. However as opposed to `revRange`, this will also include `from` ref.
|
|
27
|
-
*
|
|
28
|
-
* Each parameter can be the commit SHA or a ref name, or specify an empty
|
|
29
|
-
* string to represent HEAD.
|
|
30
|
-
*
|
|
31
|
-
* @param from The start of the range
|
|
32
|
-
* @param to The end of the range
|
|
33
|
-
*/
|
|
34
|
-
export function revRangeInclusive(from: string, to: string) {
|
|
35
|
-
return `${from}^..${to}`
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Convert two refs into the Git symmetric difference syntax, which represents
|
|
40
|
-
* the set of commits that are reachable from either `from` or `to` but not
|
|
41
|
-
* from both.
|
|
42
|
-
*
|
|
43
|
-
* Each parameter can be the commit SHA or a ref name, or you can use an empty
|
|
44
|
-
* string to represent HEAD.
|
|
45
|
-
*
|
|
46
|
-
* @param from The start of the range
|
|
47
|
-
* @param to The end of the range
|
|
48
|
-
*/
|
|
49
|
-
export function revSymmetricDifference(from: string, to: string) {
|
|
50
|
-
return `${from}...${to}`
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
/** Calculate the number of commits the range is ahead and behind. */
|
|
54
|
-
export async function getAheadBehind(
|
|
55
|
-
repository: Repository,
|
|
56
|
-
range: string
|
|
57
|
-
): Promise<IAheadBehind | null> {
|
|
58
|
-
// `--left-right` annotates the list of commits in the range with which side
|
|
59
|
-
// they're coming from. When used with `--count`, it tells us how many
|
|
60
|
-
// commits we have from the two different sides of the range.
|
|
61
|
-
const args = ['rev-list', '--left-right', '--count', range, '--']
|
|
62
|
-
const result = await git(args, repository.path, 'getAheadBehind', {
|
|
63
|
-
expectedErrors: new Set([GitError.BadRevision]),
|
|
64
|
-
})
|
|
65
|
-
|
|
66
|
-
// This means one of the refs (most likely the upstream branch) no longer
|
|
67
|
-
// exists. In that case we can't be ahead/behind at all.
|
|
68
|
-
if (result.gitError === GitError.BadRevision) {
|
|
69
|
-
return null
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
const stdout = result.stdout
|
|
73
|
-
const pieces = stdout.split('\t')
|
|
74
|
-
if (pieces.length !== 2) {
|
|
75
|
-
return null
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
const ahead = parseInt(pieces[0], 10)
|
|
79
|
-
if (isNaN(ahead)) {
|
|
80
|
-
return null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const behind = parseInt(pieces[1], 10)
|
|
84
|
-
if (isNaN(behind)) {
|
|
85
|
-
return null
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return { ahead, behind }
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Calculate the number of commits `branch` is ahead/behind its upstream. */
|
|
92
|
-
export async function getBranchAheadBehind(
|
|
93
|
-
repository: Repository,
|
|
94
|
-
branch: Branch
|
|
95
|
-
): Promise<IAheadBehind | null> {
|
|
96
|
-
if (branch.type === BranchType.Remote) {
|
|
97
|
-
return null
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const upstream = branch.upstream
|
|
101
|
-
if (!upstream) {
|
|
102
|
-
return null
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// NB: The three dot form means we'll go all the way back to the merge base
|
|
106
|
-
// of the branch and its upstream. Practically this is important for seeing
|
|
107
|
-
// "through" merges.
|
|
108
|
-
const range = revSymmetricDifference(branch.name, upstream)
|
|
109
|
-
return getAheadBehind(repository, range)
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
/**
|
|
113
|
-
* Get a list of commits from the target branch that do not exist on the base
|
|
114
|
-
* branch, ordered how they will be applied to the base branch.
|
|
115
|
-
* Therefore, this will not include the baseBranchSha commit.
|
|
116
|
-
*
|
|
117
|
-
* This emulates how `git rebase` initially determines what will be applied to
|
|
118
|
-
* the repository.
|
|
119
|
-
*
|
|
120
|
-
* Returns `null` when the rebase is not possible to perform, because of a
|
|
121
|
-
* missing commit ID
|
|
122
|
-
*/
|
|
123
|
-
export async function getCommitsBetweenCommits(
|
|
124
|
-
repository: Repository,
|
|
125
|
-
baseBranchSha: string,
|
|
126
|
-
targetBranchSha: string
|
|
127
|
-
): Promise<ReadonlyArray<CommitOneLine> | null> {
|
|
128
|
-
const range = revRange(baseBranchSha, targetBranchSha)
|
|
129
|
-
|
|
130
|
-
return getCommitsInRange(repository, range)
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Get a list of commits inside the provided range.
|
|
135
|
-
*
|
|
136
|
-
* Returns `null` when it is not possible to perform because of a bad range.
|
|
137
|
-
*/
|
|
138
|
-
export async function getCommitsInRange(
|
|
139
|
-
repository: Repository,
|
|
140
|
-
range: string
|
|
141
|
-
): Promise<ReadonlyArray<CommitOneLine> | null> {
|
|
142
|
-
const args = [
|
|
143
|
-
'rev-list',
|
|
144
|
-
range,
|
|
145
|
-
'--reverse',
|
|
146
|
-
// the combination of these two arguments means each line of the stdout
|
|
147
|
-
// will contain the full commit sha and a commit summary
|
|
148
|
-
`--oneline`,
|
|
149
|
-
`--no-abbrev-commit`,
|
|
150
|
-
'--',
|
|
151
|
-
]
|
|
152
|
-
|
|
153
|
-
const options = {
|
|
154
|
-
expectedErrors: new Set<GitError>([GitError.BadRevision]),
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const result = await git(args, repository.path, 'getCommitsInRange', options)
|
|
158
|
-
|
|
159
|
-
if (result.gitError === GitError.BadRevision) {
|
|
160
|
-
return null
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
const lines = result.stdout.split('\n')
|
|
164
|
-
|
|
165
|
-
const commits = new Array<CommitOneLine>()
|
|
166
|
-
|
|
167
|
-
const commitSummaryRe = /^([a-z0-9]{40}) (.*)$/
|
|
168
|
-
|
|
169
|
-
for (const line of lines) {
|
|
170
|
-
const match = commitSummaryRe.exec(line)
|
|
171
|
-
|
|
172
|
-
if (match !== null && match.length === 3) {
|
|
173
|
-
const sha = match[1]
|
|
174
|
-
const summary = match[2]
|
|
175
|
-
|
|
176
|
-
commits.push({
|
|
177
|
-
sha,
|
|
178
|
-
summary,
|
|
179
|
-
})
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
return commits
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* Determine if merge commits exist in history after given commit
|
|
188
|
-
* If commitRef is null, goes back to HEAD of branch.
|
|
189
|
-
*/
|
|
190
|
-
export async function doMergeCommitsExistAfterCommit(
|
|
191
|
-
repository: Repository,
|
|
192
|
-
commitRef: string | null
|
|
193
|
-
): Promise<boolean> {
|
|
194
|
-
const revision = commitRef === null ? 'HEAD' : revRange(commitRef, 'HEAD')
|
|
195
|
-
const args = ['rev-list', '-1', '--merges', revision, '--']
|
|
196
|
-
|
|
197
|
-
return git(args, repository.path, 'doMergeCommitsExistAfterCommit', {
|
|
198
|
-
// 128 here means there's no HEAD, i.e we're on an unborn branch
|
|
199
|
-
successExitCodes: new Set([0, 128]),
|
|
200
|
-
}).then(x => x.stdout.length > 0)
|
|
201
|
-
}
|
package/src/git/rev-parse.ts
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import { git } from './core.js'
|
|
2
|
-
import { directoryExists } from '../lib/directory-exists.js'
|
|
3
|
-
import { resolve } from 'path'
|
|
4
|
-
|
|
5
|
-
export type RepositoryType =
|
|
6
|
-
| { kind: 'bare' }
|
|
7
|
-
| { kind: 'regular'; topLevelWorkingDirectory: string; gitDir: string }
|
|
8
|
-
| { kind: 'missing' }
|
|
9
|
-
| { kind: 'unsafe'; path: string }
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* Attempts to fulfill the work of isGitRepository and isBareRepository while
|
|
13
|
-
* requiring only one Git process to be spawned.
|
|
14
|
-
*
|
|
15
|
-
* Returns 'bare', 'regular', or 'missing' if the repository couldn't be
|
|
16
|
-
* found.
|
|
17
|
-
*/
|
|
18
|
-
export async function getRepositoryType(path: string): Promise<RepositoryType> {
|
|
19
|
-
if (!(await directoryExists(path))) {
|
|
20
|
-
return { kind: 'missing' }
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
try {
|
|
24
|
-
const result = await git(
|
|
25
|
-
['rev-parse', '--is-bare-repository', '--show-cdup', '--git-dir'],
|
|
26
|
-
path,
|
|
27
|
-
'getRepositoryType',
|
|
28
|
-
{ successExitCodes: new Set([0, 128]) }
|
|
29
|
-
)
|
|
30
|
-
|
|
31
|
-
if (result.exitCode === 0) {
|
|
32
|
-
// Bare repositories will not include gitdir so we handle that separately
|
|
33
|
-
if (result.stdout.startsWith('true\n')) {
|
|
34
|
-
return { kind: 'bare' }
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// --is-bare-repository and --show-cdup each produce a single line but
|
|
38
|
-
// --git-dir could theoretically contain newlines so we parse the known
|
|
39
|
-
// fields first and treat the remainder as the git dir. We use [\s\S]*
|
|
40
|
-
// instead of .* for the git dir capture group because .* doesn't match
|
|
41
|
-
// newlines whereas [\s\S]* matches any character including newlines.
|
|
42
|
-
const match = result.stdout.match(/^(true|false)\n(.*)\n([\s\S]*)\n$/)
|
|
43
|
-
|
|
44
|
-
if (match) {
|
|
45
|
-
const [, isBare, cdup, gitDir] = match
|
|
46
|
-
|
|
47
|
-
return isBare === 'true'
|
|
48
|
-
? { kind: 'bare' }
|
|
49
|
-
: {
|
|
50
|
-
kind: 'regular',
|
|
51
|
-
topLevelWorkingDirectory: resolve(path, cdup),
|
|
52
|
-
gitDir: resolve(path, gitDir),
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const unsafeMatch =
|
|
58
|
-
/fatal: detected dubious ownership in repository at '(.+)'/.exec(
|
|
59
|
-
result.stderr
|
|
60
|
-
)
|
|
61
|
-
if (unsafeMatch) {
|
|
62
|
-
return { kind: 'unsafe', path: unsafeMatch[1] }
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
return { kind: 'missing' }
|
|
66
|
-
} catch (err: any) {
|
|
67
|
-
if (err?.code === 'ENOENT') {
|
|
68
|
-
return { kind: 'missing' }
|
|
69
|
-
}
|
|
70
|
-
throw err
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export async function getUpstreamRefForRef(path: string, ref?: string) {
|
|
75
|
-
const rev = (ref ?? '') + '@{upstream}'
|
|
76
|
-
const args = ['rev-parse', '--symbolic-full-name', rev]
|
|
77
|
-
const opts = { successExitCodes: new Set([0, 128]) }
|
|
78
|
-
const result = await git(args, path, 'getUpstreamRefForRef', opts)
|
|
79
|
-
|
|
80
|
-
return result.exitCode === 0 ? result.stdout.trim() : null
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export async function getUpstreamRemoteNameForRef(path: string, ref?: string) {
|
|
84
|
-
const remoteRef = await getUpstreamRefForRef(path, ref)
|
|
85
|
-
return remoteRef?.match(/^refs\/remotes\/([^/]+)\//)?.[1] ?? null
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export const getCurrentUpstreamRef = (path: string) =>
|
|
89
|
-
getUpstreamRefForRef(path)
|
|
90
|
-
|
|
91
|
-
export const getCurrentUpstreamRemoteName = (path: string) =>
|
|
92
|
-
getUpstreamRemoteNameForRef(path)
|
package/src/git/revert.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { git, IGitStringExecutionOptions } from './core.js'
|
|
2
|
-
|
|
3
|
-
import { Repository } from '../models/repository.js'
|
|
4
|
-
import { Commit } from '../models/commit.js'
|
|
5
|
-
import { IRevertProgress } from '../models/progress.js'
|
|
6
|
-
|
|
7
|
-
import { executionOptionsWithProgress } from '../lib/progress/from-process.js'
|
|
8
|
-
import { RevertProgressParser } from '../lib/progress/revert.js'
|
|
9
|
-
import {
|
|
10
|
-
envForRemoteOperation,
|
|
11
|
-
getFallbackUrlForProxyResolve,
|
|
12
|
-
} from './environment.js'
|
|
13
|
-
import { IRemote } from '../models/remote.js'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Creates a new commit that reverts the changes of a previous commit
|
|
17
|
-
*
|
|
18
|
-
* @param repository - The repository to update
|
|
19
|
-
*
|
|
20
|
-
* @param commit - The SHA of the commit to be reverted
|
|
21
|
-
*/
|
|
22
|
-
export async function revertCommit(
|
|
23
|
-
repository: Repository,
|
|
24
|
-
commit: Commit,
|
|
25
|
-
currentRemote: IRemote | null,
|
|
26
|
-
progressCallback?: (progress: IRevertProgress) => void
|
|
27
|
-
) {
|
|
28
|
-
const args = ['revert']
|
|
29
|
-
if (commit.parentSHAs.length > 1) {
|
|
30
|
-
args.push('-m', '1')
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
args.push(commit.sha)
|
|
34
|
-
|
|
35
|
-
let opts: IGitStringExecutionOptions = {}
|
|
36
|
-
if (progressCallback) {
|
|
37
|
-
const env = await envForRemoteOperation(
|
|
38
|
-
getFallbackUrlForProxyResolve(repository, currentRemote)
|
|
39
|
-
)
|
|
40
|
-
opts = await executionOptionsWithProgress(
|
|
41
|
-
{ env, trackLFSProgress: true },
|
|
42
|
-
new RevertProgressParser(),
|
|
43
|
-
progress => {
|
|
44
|
-
const description =
|
|
45
|
-
progress.kind === 'progress' ? progress.details.text : progress.text
|
|
46
|
-
const title = progress.kind === 'progress' ? progress.details.title : ''
|
|
47
|
-
const value = progress.percent
|
|
48
|
-
|
|
49
|
-
progressCallback({ kind: 'revert', description, value, title })
|
|
50
|
-
}
|
|
51
|
-
)
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
await git(args, repository.path, 'revert', opts)
|
|
55
|
-
}
|
package/src/git/rm.ts
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { git } from './core.js'
|
|
2
|
-
import { Repository } from '../models/repository.js'
|
|
3
|
-
import { WorkingDirectoryFileChange } from '../models/status.js'
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Remove all files from the index
|
|
7
|
-
*
|
|
8
|
-
* @param repository the repository to update
|
|
9
|
-
*/
|
|
10
|
-
export async function unstageAllFiles(repository: Repository): Promise<void> {
|
|
11
|
-
await git(
|
|
12
|
-
// these flags are important:
|
|
13
|
-
// --cached to only remove files from the index
|
|
14
|
-
// -r to recursively remove files, in case files are in folders
|
|
15
|
-
// -f to ignore differences between working directory and index
|
|
16
|
-
// which will block this
|
|
17
|
-
['rm', '--cached', '-r', '-f', '.'],
|
|
18
|
-
repository.path,
|
|
19
|
-
'unstageAllFiles'
|
|
20
|
-
)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Remove conflicted file from working tree and index
|
|
25
|
-
*/
|
|
26
|
-
export async function removeConflictedFile(
|
|
27
|
-
repository: Repository,
|
|
28
|
-
file: WorkingDirectoryFileChange
|
|
29
|
-
) {
|
|
30
|
-
await git(['rm', '--', file.path], repository.path, 'removeConflictedFile')
|
|
31
|
-
}
|
package/src/git/show.ts
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
import { git, isMaxBufferExceededError } from './core.js'
|
|
2
|
-
|
|
3
|
-
import { Repository } from '../models/repository.js'
|
|
4
|
-
import { GitError } from './exec.js'
|
|
5
|
-
import { coerceToBuffer } from './coerce-to-buffer.js'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Retrieve the binary contents of a blob from the repository at a given
|
|
9
|
-
* reference, commit, or tree.
|
|
10
|
-
*
|
|
11
|
-
* Returns a promise that will produce a Buffer instance containing
|
|
12
|
-
* the binary contents of the blob or an error if the file doesn't
|
|
13
|
-
* exists in the given revision.
|
|
14
|
-
*
|
|
15
|
-
* @param repository - The repository from where to read the blob
|
|
16
|
-
*
|
|
17
|
-
* @param commitish - A commit SHA or some other identifier that
|
|
18
|
-
* ultimately dereferences to a commit/tree.
|
|
19
|
-
*
|
|
20
|
-
* @param path - The file path, relative to the repository
|
|
21
|
-
* root from where to read the blob contents
|
|
22
|
-
*/
|
|
23
|
-
export const getBlobContents = (
|
|
24
|
-
repository: Repository,
|
|
25
|
-
commitish: string,
|
|
26
|
-
path: string
|
|
27
|
-
) =>
|
|
28
|
-
git(['show', `${commitish}:${path}`], repository.path, 'getBlobContents', {
|
|
29
|
-
successExitCodes: new Set([0, 1]),
|
|
30
|
-
encoding: 'buffer',
|
|
31
|
-
}).then(r => r.stdout)
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Retrieve some or all binary contents of a blob from the repository
|
|
35
|
-
* at a given reference, commit, or tree. This is almost identical
|
|
36
|
-
* to the getBlobContents method except that it supports only reading
|
|
37
|
-
* a maximum number of bytes.
|
|
38
|
-
*
|
|
39
|
-
* Returns a promise that will produce a Buffer instance containing
|
|
40
|
-
* the binary contents of the blob or an error if the file doesn't
|
|
41
|
-
* exists in the given revision.
|
|
42
|
-
*
|
|
43
|
-
* @param repository - The repository from where to read the blob
|
|
44
|
-
*
|
|
45
|
-
* @param commitish - A commit SHA or some other identifier that
|
|
46
|
-
* ultimately dereferences to a commit/tree.
|
|
47
|
-
*
|
|
48
|
-
* @param path - The file path, relative to the repository
|
|
49
|
-
* root from where to read the blob contents
|
|
50
|
-
*
|
|
51
|
-
* @param length - The maximum number of bytes to read from
|
|
52
|
-
* the blob. Note that the number of bytes
|
|
53
|
-
* returned may always be less than this number.
|
|
54
|
-
*/
|
|
55
|
-
export async function getPartialBlobContents(
|
|
56
|
-
repository: Repository,
|
|
57
|
-
commitish: string,
|
|
58
|
-
path: string,
|
|
59
|
-
length: number
|
|
60
|
-
): Promise<Buffer | null> {
|
|
61
|
-
return getPartialBlobContentsCatchPathNotInRef(
|
|
62
|
-
repository,
|
|
63
|
-
commitish,
|
|
64
|
-
path,
|
|
65
|
-
length
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export async function getPartialBlobContentsCatchPathNotInRef(
|
|
70
|
-
repository: Repository,
|
|
71
|
-
commitish: string,
|
|
72
|
-
path: string,
|
|
73
|
-
length: number
|
|
74
|
-
): Promise<Buffer | null> {
|
|
75
|
-
const args = ['show', `${commitish}:${path}`]
|
|
76
|
-
|
|
77
|
-
return git(args, repository.path, 'getPartialBlobContentsCatchPathNotInRef', {
|
|
78
|
-
maxBuffer: length,
|
|
79
|
-
expectedErrors: new Set([GitError.PathExistsButNotInRef]),
|
|
80
|
-
encoding: 'buffer',
|
|
81
|
-
})
|
|
82
|
-
.then(r =>
|
|
83
|
-
r.gitError === GitError.PathExistsButNotInRef ? null : r.stdout
|
|
84
|
-
)
|
|
85
|
-
.catch(e =>
|
|
86
|
-
isMaxBufferExceededError(e) ? coerceToBuffer(e.stdout) : Promise.reject(e)
|
|
87
|
-
)
|
|
88
|
-
}
|
package/src/git/spawn.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { spawnGit as spawn, IGitSpawnOptions } from './exec.js'
|
|
2
|
-
import * as GitPerf from '../lib/git-perf.js'
|
|
3
|
-
import { withTrampolineEnv } from '../lib/trampoline/trampoline-environment.js'
|
|
4
|
-
|
|
5
|
-
type SpawnOptions = IGitSpawnOptions & {
|
|
6
|
-
/**
|
|
7
|
-
* Whether the command about to run is part of a background task or not.
|
|
8
|
-
* This affects error handling and UI such as credential prompts.
|
|
9
|
-
*/
|
|
10
|
-
readonly isBackgroundTask?: boolean
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Spawn a Git process, deferring all processing work to the caller.
|
|
15
|
-
*
|
|
16
|
-
* @param args Array of strings to pass to the Git executable.
|
|
17
|
-
* @param path The path to execute the command from.
|
|
18
|
-
* @param name The name of the operation - for tracing purposes.
|
|
19
|
-
* @param successExitCodes An optional array of exit codes that indicate success.
|
|
20
|
-
*/
|
|
21
|
-
export const spawnGit = (
|
|
22
|
-
args: string[],
|
|
23
|
-
path: string,
|
|
24
|
-
name: string,
|
|
25
|
-
options?: SpawnOptions
|
|
26
|
-
) =>
|
|
27
|
-
withTrampolineEnv(
|
|
28
|
-
trampolineEnv =>
|
|
29
|
-
GitPerf.measure(`${name}: git ${args.join(' ')}`, async () =>
|
|
30
|
-
spawn(args, path, {
|
|
31
|
-
...options,
|
|
32
|
-
env: { ...options?.env, ...trampolineEnv },
|
|
33
|
-
})
|
|
34
|
-
),
|
|
35
|
-
path,
|
|
36
|
-
options?.isBackgroundTask ?? false,
|
|
37
|
-
options?.env
|
|
38
|
-
)
|
package/src/git/squash.ts
DELETED
|
@@ -1,173 +0,0 @@
|
|
|
1
|
-
import { appendFile, rm, writeFile } from 'fs/promises'
|
|
2
|
-
import { getCommits, revRange } from './index.js'
|
|
3
|
-
import { Commit } from '../models/commit.js'
|
|
4
|
-
import { MultiCommitOperationKind } from '../models/multi-commit-operation.js'
|
|
5
|
-
import { IMultiCommitOperationProgress } from '../models/progress.js'
|
|
6
|
-
import { Repository } from '../models/repository.js'
|
|
7
|
-
import { getTempFilePath } from '../lib/file-system.js'
|
|
8
|
-
import { rebaseInteractive, RebaseResult } from './rebase.js'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Squashes provided commits by calling interactive rebase.
|
|
12
|
-
*
|
|
13
|
-
* Goal is to replay the commits in order from oldest to newest to reduce
|
|
14
|
-
* conflicts with toSquash commits placed in the log at the location of the
|
|
15
|
-
* squashOnto commit.
|
|
16
|
-
*
|
|
17
|
-
* Example: A user's history from oldest to newest is A, B, C, D, E and they
|
|
18
|
-
* want to squash A and E (toSquash) onto C. Our goal: B, A-C-E, D. Thus,
|
|
19
|
-
* maintaining that A came before C and E came after C, placed in history at the
|
|
20
|
-
* the squashOnto of C.
|
|
21
|
-
*
|
|
22
|
-
* Also means if the last 2 commits in history are A, B, whether user squashes A
|
|
23
|
-
* onto B or B onto A. It will always perform based on log history, thus, B onto
|
|
24
|
-
* A.
|
|
25
|
-
*
|
|
26
|
-
* @param toSquash - commits to squash onto another commit and does not contain the squashOnto commit
|
|
27
|
-
* @param squashOnto - commit to squash the `toSquash` commits onto
|
|
28
|
-
* @param lastRetainedCommitRef - sha of commit before commits in squash or null
|
|
29
|
-
* if commit to be squash is the root (first in history) of the branch
|
|
30
|
-
* @param commitMessage - the first line of the string provided will be the
|
|
31
|
-
* summary and rest the body (similar to commit implementation)
|
|
32
|
-
*/
|
|
33
|
-
export async function squash(
|
|
34
|
-
repository: Repository,
|
|
35
|
-
toSquash: ReadonlyArray<Commit>,
|
|
36
|
-
squashOnto: Commit,
|
|
37
|
-
lastRetainedCommitRef: string | null,
|
|
38
|
-
commitMessage: string,
|
|
39
|
-
progressCallback?: (progress: IMultiCommitOperationProgress) => void
|
|
40
|
-
): Promise<RebaseResult> {
|
|
41
|
-
let messagePath, todoPath
|
|
42
|
-
let result: RebaseResult
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
if (toSquash.length === 0) {
|
|
46
|
-
throw new Error('[squash] No commits provided to squash.')
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const toSquashShas = new Set(toSquash.map(c => c.sha))
|
|
50
|
-
if (toSquashShas.has(squashOnto.sha)) {
|
|
51
|
-
throw new Error(
|
|
52
|
-
'[squash] The commits to squash cannot contain the commit to squash onto.'
|
|
53
|
-
)
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
const commits = await getCommits(
|
|
57
|
-
repository,
|
|
58
|
-
lastRetainedCommitRef === null
|
|
59
|
-
? undefined
|
|
60
|
-
: revRange(lastRetainedCommitRef, 'HEAD')
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
if (commits.length === 0) {
|
|
64
|
-
throw new Error(
|
|
65
|
-
'[squash] Could not find commits in log for last retained commit ref.'
|
|
66
|
-
)
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
todoPath = await getTempFilePath('squashTodo')
|
|
70
|
-
let foundSquashOntoCommitInLog = false
|
|
71
|
-
const toReplayAtSquash = []
|
|
72
|
-
const toReplayAfterSquash = []
|
|
73
|
-
// Traversed in reverse so we do oldest to newest (replay commits)
|
|
74
|
-
for (let i = commits.length - 1; i >= 0; i--) {
|
|
75
|
-
const commit = commits[i]
|
|
76
|
-
if (toSquashShas.has(commit.sha)) {
|
|
77
|
-
// If it is toSquash commit and we have found the squashOnto commit, we
|
|
78
|
-
// can go ahead and squash them (as we will hold any picks till after)
|
|
79
|
-
if (foundSquashOntoCommitInLog) {
|
|
80
|
-
await appendFile(todoPath, `squash ${commit.sha} ${commit.summary}\n`)
|
|
81
|
-
} else {
|
|
82
|
-
// However, if we have not found the squashOnto commit yet we want to
|
|
83
|
-
// keep track of them in the order of the log. Thus, we use a new
|
|
84
|
-
// `toReplayAtSquash` array and not trust that what was sent is in the
|
|
85
|
-
// order of the log.
|
|
86
|
-
toReplayAtSquash.push(commit)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
continue
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// If it's the squashOnto commit, replay to the toSquash in the order they
|
|
93
|
-
// appeared on the log to reduce potential conflicts.
|
|
94
|
-
if (commit.sha === squashOnto.sha) {
|
|
95
|
-
foundSquashOntoCommitInLog = true
|
|
96
|
-
toReplayAtSquash.push(commit)
|
|
97
|
-
|
|
98
|
-
for (let j = 0; j < toReplayAtSquash.length; j++) {
|
|
99
|
-
const action = j === 0 ? 'pick' : 'squash'
|
|
100
|
-
await appendFile(
|
|
101
|
-
todoPath,
|
|
102
|
-
`${action} ${toReplayAtSquash[j].sha} ${toReplayAtSquash[j].summary}\n`
|
|
103
|
-
)
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
continue
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// We can't just replay a pick in case there is a commit from the toSquash
|
|
110
|
-
// commits further up in history that need to be replayed with the
|
|
111
|
-
// squashes. Thus, we will keep track of these and replay after traversing
|
|
112
|
-
// the remainder of the log.
|
|
113
|
-
if (foundSquashOntoCommitInLog) {
|
|
114
|
-
toReplayAfterSquash.push(commit)
|
|
115
|
-
continue
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// If it is not one toSquash nor the squashOnto and have not found the
|
|
119
|
-
// squashOnto commit, we simply record it is an unchanged pick (before the
|
|
120
|
-
// squash)
|
|
121
|
-
await appendFile(todoPath, `pick ${commit.sha} ${commit.summary}\n`)
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (toReplayAfterSquash.length > 0) {
|
|
125
|
-
for (let i = 0; i < toReplayAfterSquash.length; i++) {
|
|
126
|
-
await appendFile(
|
|
127
|
-
todoPath,
|
|
128
|
-
`pick ${toReplayAfterSquash[i].sha} ${toReplayAfterSquash[i].summary}\n`
|
|
129
|
-
)
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
if (!foundSquashOntoCommitInLog) {
|
|
134
|
-
throw new Error(
|
|
135
|
-
'[squash] The commit to squash onto was not in the log. Continuing would result in dropping the commits in the toSquash array.'
|
|
136
|
-
)
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (commitMessage.trim() !== '') {
|
|
140
|
-
messagePath = await getTempFilePath('squashCommitMessage')
|
|
141
|
-
await writeFile(messagePath, commitMessage)
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
// if no commit message provided, accept default editor
|
|
145
|
-
const gitEditor =
|
|
146
|
-
messagePath !== undefined ? `cat "${messagePath}" >` : undefined
|
|
147
|
-
|
|
148
|
-
result = await rebaseInteractive(
|
|
149
|
-
repository,
|
|
150
|
-
todoPath,
|
|
151
|
-
lastRetainedCommitRef,
|
|
152
|
-
{
|
|
153
|
-
action: MultiCommitOperationKind.Squash,
|
|
154
|
-
gitEditor,
|
|
155
|
-
progressCallback,
|
|
156
|
-
commits: [...toSquash, squashOnto],
|
|
157
|
-
}
|
|
158
|
-
)
|
|
159
|
-
} catch (e) {
|
|
160
|
-
console.error(e)
|
|
161
|
-
return RebaseResult.Error
|
|
162
|
-
} finally {
|
|
163
|
-
if (todoPath !== undefined) {
|
|
164
|
-
await rm(todoPath, { recursive: true, force: true })
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
if (messagePath !== undefined) {
|
|
168
|
-
await rm(messagePath, { recursive: true, force: true })
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
return result
|
|
173
|
-
}
|