* Updates remote refs based on the provided refspecs and options. * * @param {Object} args * @param {FSClient} args.fs - A file system implementation. * @param {string} [args.gitdir=join(dir, '.git')] - [required] The [git directory](dir-vs-gitdir.md) path * @param {string} args.remot
({
fs,
gitdir,
remote,
refs,
symrefs,
tags,
refspecs = undefined,
prune = false,
pruneTags = false,
})
| 54 | * @returns {Promise<Object>} - An object containing pruned refs. |
| 55 | */ |
| 56 | static async updateRemoteRefs({ |
| 57 | fs, |
| 58 | gitdir, |
| 59 | remote, |
| 60 | refs, |
| 61 | symrefs, |
| 62 | tags, |
| 63 | refspecs = undefined, |
| 64 | prune = false, |
| 65 | pruneTags = false, |
| 66 | }) { |
| 67 | // Validate input |
| 68 | for (const value of refs.values()) { |
| 69 | if (!value.match(/[0-9a-f]{40}/)) { |
| 70 | throw new InvalidOidError(value) |
| 71 | } |
| 72 | } |
| 73 | const config = await GitConfigManager.get({ fs, gitdir }) |
| 74 | if (!refspecs) { |
| 75 | refspecs = await config.getall(`remote.${remote}.fetch`) |
| 76 | if (refspecs.length === 0) { |
| 77 | throw new NoRefspecError(remote) |
| 78 | } |
| 79 | // There's some interesting behavior with HEAD that doesn't follow the refspec. |
| 80 | refspecs.unshift(`+HEAD:refs/remotes/${remote}/HEAD`) |
| 81 | } |
| 82 | const refspec = GitRefSpecSet.from(refspecs) |
| 83 | const actualRefsToWrite = new Map() |
| 84 | // Delete all current tags if the pruneTags argument is true. |
| 85 | if (pruneTags) { |
| 86 | const tags = await GitRefManager.listRefs({ |
| 87 | fs, |
| 88 | gitdir, |
| 89 | filepath: 'refs/tags', |
| 90 | }) |
| 91 | await GitRefManager.deleteRefs({ |
| 92 | fs, |
| 93 | gitdir, |
| 94 | refs: tags.map(tag => `refs/tags/${tag}`), |
| 95 | }) |
| 96 | } |
| 97 | // Add all tags if the fetch tags argument is true. |
| 98 | if (tags) { |
| 99 | for (const serverRef of refs.keys()) { |
| 100 | if (serverRef.startsWith('refs/tags') && !serverRef.endsWith('^{}')) { |
| 101 | // Git's behavior is to only fetch tags that do not conflict with tags already present. |
| 102 | if (!(await GitRefManager.exists({ fs, gitdir, ref: serverRef }))) { |
| 103 | // Always use the object id of the tag itself, and not the peeled object id. |
| 104 | const oid = refs.get(serverRef) |
| 105 | actualRefsToWrite.set(serverRef, oid) |
| 106 | } |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | // Combine refs and symrefs giving symrefs priority |
| 111 | const refTranslations = refspec.translate([...refs.keys()]) |
| 112 | for (const [serverRef, translatedRef] of refTranslations) { |
| 113 | const value = refs.get(serverRef) |
no test coverage detected