From f85e1ab8fc2bb836a6da334f4ffe70bc3f93f99c Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Tue, 12 Mar 2019 18:20:46 -0700 Subject: [PATCH] Save snapshots as tags so they don't get deleted by git gc Creates a new tag for each snapshot hash at `refs/snapshots///v` with the tag name `snapshots///v`. The tag ref is created outside of `refs/tags` so that other methods that iterate the refs don't include snapshots in their iterations (i.e. db.authors() simply returns all nodes in `refs/tags`). It's confirmed that the tag being in `refs/snapshots` still makes it exempt from `git gc`: without the tag, `git gc --prune=all` prunes the snapshot hash, but with the tag it remains after `git gc --prune=all`. Note: This is an incomplete implementation; it only creates the snapshot tag in `lit add`, not on the server during `lit publish` (or any other places where it might also need to be created) --- libs/core.lua | 25 +++++++++++++++++++++++-- libs/db.lua | 14 +++++++++----- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/libs/core.lua b/libs/core.lua index 3f496df7..ae0a6762 100644 --- a/libs/core.lua +++ b/libs/core.lua @@ -156,7 +156,7 @@ local function makeCore(config) local encoded = encoders.tag({ object = hash, type = kind, - tag = author .. '/' .. name .. "/v" .. version, + tag = fullTag, tagger = { name = config.name, email = config.email, @@ -170,6 +170,27 @@ local function makeCore(config) local tagHash = db.saveAs("tag", encoded) db.write(author, name, version, tagHash) log("new tag", fullTag, "success") + + if meta.snapshot then + local snapshotEncoded = encoders.tag({ + object = meta.snapshot, + type = kind, + tag = "snapshots/" .. fullTag, + tagger = { + name = config.name, + email = config.email, + date = getdate() + }, + message = "" + }) + if key then + snapshotEncoded = sshRsa.sign(snapshotEncoded, key) + end + local snapshotTagHash = db.saveAs("tag", snapshotEncoded) + db.write(author, name, version, snapshotTagHash, true) + log("new snapshot", 'snapshots/' .. fullTag, "success") + end + return author, name, version, tagHash end @@ -330,7 +351,7 @@ local function makeCore(config) if fingerprints[fingerprint] then fingerprints[fingerprint]= nil else - log("revoking key", username .. ' ' .. fingerprint, "error") + log("revoking key", username .. ' ' .. fingerprint, "failure") db.revokeKey(username, fingerprint) end end diff --git a/libs/db.lua b/libs/db.lua index 3a0554fd..8855da1d 100644 --- a/libs/db.lua +++ b/libs/db.lua @@ -78,16 +78,20 @@ return function (rootPath) return match, assert(db.read(author, name, match)) end - function db.read(author, name, version) + function db.tagRef(author, name, version, isSnapshot) version = normalize(version) - local ref = string.format("refs/tags/%s/%s/v%s", author, name, version) + local refDir = isSnapshot and "snapshots" or "tags" + return string.format("refs/%s/%s/%s/v%s", refDir, author, name, version) + end + + function db.read(author, name, version, isSnapshot) + local ref = db.tagRef(author, name, version, isSnapshot) return db.getRef(ref) end - function db.write(author, name, version, hash) - version = normalize(version) + function db.write(author, name, version, hash, isSnapshot) assertHash(hash) - local ref = string.format("refs/tags/%s/%s/v%s", author, name, version) + local ref = db.tagRef(author, name, version, isSnapshot) storage.write(ref, hash .. "\n") end