@@ -30,7 +30,8 @@ export class GitRefManager {
30
30
symrefs,
31
31
tags,
32
32
refspecs = undefined,
33
-
prune = false
33
+
prune = false,
34
+
pruneTags = false
34
35
}) {
35
36
const fs = new FileSystem(_fs)
36
37
// Validate input
@@ -50,13 +51,25 @@ export class GitRefManager {
50
51
}
51
52
const refspec = GitRefSpecSet.from(refspecs)
52
53
const actualRefsToWrite = new Map()
54
+
// Delete all current tags if the pruneTags argument is true.
55
+
if (pruneTags) {
56
+
const tags = await GitRefManager.listRefs({
57
+
fs,
58
+
gitdir,
59
+
filepath: 'refs/tags'
60
+
})
61
+
await GitRefManager.deleteRefs({
62
+
fs,
63
+
gitdir,
64
+
refs: tags.map(tag => `refs/tags/${tag}`)
65
+
})
66
+
}
53
67
// Add all tags if the fetch tags argument is true.
54
68
if (tags) {
55
69
for (const serverRef of refs.keys()) {
56
70
if (serverRef.startsWith('refs/tags') && !serverRef.endsWith('^{}')) {
57
-
const filename = join(gitdir, serverRef)
58
71
// Git's behavior is to only fetch tags that do not conflict with tags already present.
59
-
if (!(await fs.exists(filename))) {
72
+
if (!(await GitRefManager.exists({ fs, gitdir, ref: serverRef }))) {
60
73
// If there is a dereferenced an annotated tag value available, prefer that.
61
74
const oid = refs.get(serverRef + '^{}') || refs.get(serverRef)
62
75
actualRefsToWrite.set(serverRef, oid)
@@ -82,16 +95,20 @@ export class GitRefManager {
82
95
const pruned = []
83
96
if (prune) {
84
97
for (const filepath of refspec.localNamespaces()) {
85
-
const refs = (await this.listRefs({ fs, gitdir, filepath })).map(
86
-
file => `${filepath}/${file}`
87
-
)
98
+
const refs = (await GitRefManager.listRefs({
99
+
fs,
100
+
gitdir,
101
+
filepath
102
+
})).map(file => `${filepath}/${file}`)
88
103
for (const ref of refs) {
89
104
if (!actualRefsToWrite.has(ref)) {
90
-
this.deleteRef({ fs, gitdir, ref })
91
105
pruned.push(ref)
92
106
}
93
107
}
94
108
}
109
+
if (pruned.length > 0) {
110
+
await GitRefManager.deleteRefs({ fs, gitdir, refs: pruned })
111
+
}
95
112
}
96
113
// Update files
97
114
// TODO: For large repos with a history of thousands of pull requests
@@ -129,15 +146,24 @@ export class GitRefManager {
129
146
await fs.write(join(gitdir, ref), 'ref: ' + `${value.trim()}\n`, 'utf8')
130
147
}
131
148
132
-
static async deleteRef ({ fs: _fs, gitdir, ref }) {
149
+
static async deleteRef ({ fs, gitdir, ref }) {
150
+
return GitRefManager.deleteRefs({ fs, gitdir, refs: [ref] })
151
+
}
152
+
153
+
static async deleteRefs ({ fs: _fs, gitdir, refs }) {
133
154
const fs = new FileSystem(_fs)
134
155
// Delete regular ref
135
-
await fs.rm(join(gitdir, ref))
156
+
await Promise.all(refs.map(ref => fs.rm(join(gitdir, ref))))
136
157
// Delete any packed ref
137
158
let text = await fs.read(`${gitdir}/packed-refs`, { encoding: 'utf8' })
138
159
const packed = GitPackedRefs.from(text)
139
-
if (packed.refs.has(ref)) {
140
-
packed.delete(ref)
160
+
const beforeSize = packed.refs.size
161
+
for (const ref of refs) {
162
+
if (packed.refs.has(ref)) {
163
+
packed.delete(ref)
164
+
}
165
+
}
166
+
if (packed.refs.size < beforeSize) {
141
167
text = packed.toString()
142
168
await fs.write(`${gitdir}/packed-refs`, text, { encoding: 'utf8' })
143
169
}
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4