git ssb

39+

cel / git-ssb



Tree: 403bed97ce3c8f93b87fa33b014b7f20e5e5670d

Files: 403bed97ce3c8f93b87fa33b014b7f20e5e5670d / lib / reconstruct.js

3999 bytesRaw
1var fs = require('fs')
2var proc = require('child_process')
3var pull = require('pull-stream')
4var toPull = require('stream-to-pull-stream')
5var paramap = require('pull-paramap')
6var multicb = require('multicb')
7var u = require('./util')
8var ssbRef = require('ssb-ref')
9
10exports.help = `
11Usage: git ssb reconstruct <msg>...
12
13 Reconstruct pack/idx blobs referenced by git-update messages.
14 On success, output the message ids and their pack and index blob ids.
15
16Arguments:
17 msg ssb message id
18`
19
20function reconstructBlobsForMsg(sbot, msg, cb) {
21 var c = msg.value.content
22 if (!c) return cb(new TypeError('Bad message: ' + JSON.stringify(msg)))
23 var packs = Array.isArray(c.packs) && c.packs.length === 1 && c.packs
24 var idxs = Array.isArray(c.indexes) && c.indexes.length === 1 && c.indexes
25 var packId = packs && packs[0] && packs[0].link
26 var idxId = idxs && idxs[0] && idxs[0].link
27 if (!packId || !idxId) return cb(new TypeError('Message should have ' +
28 'exactly one pack link and idx link'))
29 var commits = Array.isArray(c.commits) ? c.commits : []
30 var commitIds = commits.map(function (commit) { return commit.sha1 })
31 var objectIds = Array.isArray(c.object_ids) ? c.object_ids : []
32 var allObjectIds = commitIds.concat(objectIds)
33 if (c.num_objects && c.num_objects !== allObjectIds.length) {
34 return cb(new Error('Message ' + msg.key + ' ' +
35 'does not have information to reconstruct its blobs'))
36 }
37 // replace incorrectly hashed empty blob id
38 allObjectIds = allObjectIds.map(function (id) {
39 return id === '77e98a59e190ce51ab7ec86deb24492d1434247e'
40 ? 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391' : id
41 })
42 var tmpName = 'git-ssb-reconstruct'
43 var child = proc.spawn('git', ['pack-objects', '-q', tmpName], {
44 stdio: ['pipe', 'pipe', process.stderr],
45 })
46 child.stdin.end(allObjectIds.join('\n'))
47 var bufs = []
48 child.stdout.on('data', bufs.push.bind(bufs))
49 child.on('error', onError)
50 function onError(err) {
51 if (!cb) return console.trace(err)
52 var _cb = cb
53 cb = null
54 _cb(err)
55 }
56 var done = multicb()
57 child.on('exit', done())
58 child.stdout.on('end', done())
59 done(function (code) {
60 if (code) return onError(new Error('failed to pack git objects. code: ' + code))
61 if (!cb) return
62 var hash = Buffer.concat(bufs).toString('utf8').trim()
63 if (!hash) return cb(new Error('missing hash'))
64 var packFile = tmpName + '-' + hash + '.pack'
65 var idxFile = tmpName + '-' + hash + '.idx'
66 var done = multicb()
67 pull(
68 toPull(fs.createReadStream(packFile)),
69 sbot.blobs.add(packId, done())
70 )
71 pull(
72 toPull(fs.createReadStream(idxFile)),
73 sbot.blobs.add(idxId, done())
74 )
75 done(function (err) {
76 var done = multicb()
77 fs.unlink(packFile, done())
78 fs.unlink(idxFile, done())
79 done()(err)
80 done(function (err) {
81 if (err) return cb(err)
82 cb(null, {msg: msg, packId: packId, idxId: idxId})
83 })
84 })
85 })
86}
87
88exports.fn = function (argv) {
89 if (argv._.length < 1) return u.help('reconstruct')
90
91 var msgIds = argv._
92 if (!msgIds.every(ssbRef.isMsgId)) throw 'invalid message ids: ' +
93 JSON.stringify(argv._)
94
95 u.getSbot(argv, function (err, sbot) {
96 if (err) throw err
97 pull(
98 pull.values(msgIds),
99 paramap(function (id, cb) {
100 u.getMsg(sbot, id, function (err, msg) {
101 if (err) throw 'failed to get message ' + id + ': ' + (err.stack||err)
102 cb(null, msg)
103 })
104 }, 8),
105 paramap(function (msg, cb) {
106 u.unbox(sbot, msg, function (err, msg) {
107 if (err) throw 'failed to get decrypt message ' + id
108 cb(null, msg)
109 })
110 }, 4),
111 pull.asyncMap(function (msg, cb) {
112 reconstructBlobsForMsg(sbot, msg, cb)
113 }),
114 pull.drain(function (obj) {
115 console.log(obj.msg.key + ' ' + obj.packId + ' ' + obj.idxId)
116 }, function (err) {
117 if (err) throw err
118 sbot.close()
119 })
120 )
121 })
122}
123

Built with git-ssb-web