git ssb

0+

cel / pull-git-remote-helper



Commit 677dcfe9bf0a2edad81d8553cbbc62da94b75d95

Start receiving pack

Charles Lehner committed on 2/8/2016, 4:36:42 AM
Parent: 76d7bd15ac81df893e05f465fa9200b7c1be2e1e

Files changed

index.jschanged
test/git-remote-test.jschanged
test/run.jschanged
index.jsView
@@ -61,8 +61,13 @@
6161 str.substr(i + 1)
6262 ]
6363 }
6464
65+function split3(str) {
66+ var args = split2(str)
67+ return [args[0]].concat(split2(args[1]))
68+}
69+
6570 function optionSource(cmd) {
6671 var args = split2(cmd)
6772 var msg = handleOption(args[0], args[1])
6873 msg = (msg === true) ? 'ok'
@@ -86,16 +91,21 @@
8691 })
8792 return hasher
8893 }
8994
90-function uploadPack(read) {
91- return function (abort, cb) {
92- var lines = packLineDecode(read)
93- receiveRefs(lines.packLines, function (err, refs) {
94- console.error('refs', refs, err)
95- if (err) return cb(err)
96- })
97- }
95+function uploadPack(read, objectSource, refSource) {
96+ /* multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress
97+ * include-tag multi_ack_detailed symref=HEAD:refs/heads/master
98+ * agent=git/2.7.0 */
99+ var sendRefs = receivePackHeader([
100+ ], refSource, false)
101+
102+ return packLineEncode(
103+ cat([
104+ sendRefs,
105+ pull.once('')
106+ ])
107+ )
98108 }
99109
100110 function getRefs() {
101111 return pull.values([
@@ -137,39 +147,73 @@
137147 var b = buffered(read)
138148 var readPrefix = b.chunks(4)
139149 var ended
140150
141- b.packLines = function (abort, cb) {
151+ function readPackLine(abort, cb) {
142152 readPrefix(abort, function (end, buf) {
143153 if (ended = end) return cb(end)
144154 var len = parseInt(buf, 16)
145- b.chunks(len)(null, function (end, buf) {
155+ if (!len)
156+ return cb(null, new Buffer(''))
157+ // TODO: figure out this -4 thing
158+ b.chunks(len - 4)(null, function (end, buf) {
146159 if (ended = end) return cb(end)
147160 cb(end, buf)
148161 })
149162 })
150163 }
151164
165+ function readUpdate(abort, cb) {
166+ readPackLine(abort, function (end, line) {
167+ if (end) return cb(end)
168+ console.error('line', line.toString('ascii'))
169+ if (!line.length) return cb(true)
170+ var args = split3(line.toString('ascii'))
171+ cb(null, {
172+ old: args[0],
173+ new: args[1],
174+ name: args[2]
175+ })
176+ })
177+ }
178+
179+ b.packLines = readPackLine
180+ b.updates = readUpdate
181+
152182 return b
153183 }
154184
185+// run a callback when a pipeline ends
186+// TODO: find a better way to do this
187+function onThroughEnd(onEnd) {
188+ return function (read) {
189+ return function (end, cb) {
190+ read(end, function (end, data) {
191+ cb(end, data)
192+ if (end)
193+ onEnd(end === true ? null : end)
194+ })
195+ }
196+ }
197+}
198+
155199 /*
156200 TODO: investigate capabilities
157201 report-status delete-refs side-band-64k quiet atomic ofs-delta
158202 */
159203
160204 // Get a line for each ref that we have. The first line also has capabilities.
161205 // Wrap with packLineEncode.
162-function receivePackHeader(capabilities, refsSource) {
206+function receivePackHeader(capabilities, refSource, usePlaceholder) {
163207 var first = true
164208 var ended
165209 return function (abort, cb) {
166210 if (ended) return cb(true)
167- refsSource(abort, function (end, ref) {
211+ refSource(abort, function (end, ref) {
168212 ended = end
169213 var name = ref && ref.name
170214 var hash = ref && ref.hash
171- if (first) {
215+ if (first && usePlaceholder) {
172216 first = false
173217 if (end) {
174218 // use placeholder data if there are no refs
175219 hash = '0000000000000000000000000000000000000000'
@@ -183,38 +227,24 @@
183227 })
184228 }
185229 }
186230
187-function receiveActualPack(read, objectSink, onEnd) {
231+function decodePack(read) {
188232 var objects = pushable()
189- packCodec.decodePack(function (obj) {
190- if (obj) pushable.push(obj)
191- else pushable.end()
233+ var decode = packCodec.decodePack(function (obj) {
234+ if (obj) objects.push(obj)
235+ else objects.end()
192236 })
193- objectSink(objects)
194-}
195-
196-function receiveRefs(readLine, cb) {
197- var refs = []
198- readLine(null, function next(end, line) {
199- if (end)
200- cb(end)
201- else if (line.length == 0)
202- cb(null, refs)
203- else {
204- var args = split2(line.toString('ascii'))
205- refs.push({
206- hash: args[0],
207- name: args[1]
208- })
209- readLine(null, next)
210- }
237+ read(null, function next(end, data) {
238+ if (end) decode()
239+ else decode(data)
211240 })
241+ return objects
212242 }
213243
214-function receivePack(read, objectSink, refsSource) {
244+function receivePack(read, objectSink, refSource, refSink) {
215245 var ended
216- var sendRefs = receivePackHeader([], refsSource)
246+ var sendRefs = receivePackHeader([], refSource, true)
217247
218248 return packLineEncode(
219249 cat([
220250 // send our refs
@@ -223,17 +253,27 @@
223253 function (abort, cb) {
224254 if (abort) return
225255 // receive their refs
226256 var lines = packLineDecode(read)
227- receiveRefs(lines.packLines, function (err, refs) {
228- // console.error('refs', refs, err)
257+ pull(
258+ lines.updates,
259+ onThroughEnd(refsDone),
260+ refSink
261+ )
262+ function refsDone(err) {
229263 if (err) return cb(err)
230264 // receive the pack
231- receiveActualPack(lines.passthrough, objectSink, function (err) {
232- if (err) return cb(err)
233- cb(true)
234- })
235- })
265+ pull(
266+ lines.passthrough,
267+ decodePack,
268+ onThroughEnd(objectsDone),
269+ objectSink
270+ )
271+ }
272+ function objectsDone(err) {
273+ if (err) return cb(err)
274+ cb(true)
275+ }
236276 },
237277 pull.once('unpack ok')
238278 ])
239279 )
@@ -254,17 +294,20 @@
254294 module.exports = function (opts) {
255295 var ended
256296 var prefix = opts.prefix
257297 var objectSink = opts.objectSink
258- var refsSource = opts.refsSource || pull.empty()
298+ var objectSource = opts.objectSource || pull.empty()
299+ var refSource = opts.refSource || pull.empty()
300+ var refSink = opts.refSink
259301
260302 function handleConnect(cmd, read) {
261303 var args = split2(cmd)
262304 switch (args[0]) {
263305 case 'git-upload-pack':
264- return prepend('\n', uploadPack(read))
306+ return prepend('\n', uploadPack(read, objectSource, refSource))
265307 case 'git-receive-pack':
266- return prepend('\n', receivePack(read, objectSink, refsSource))
308+ return prepend('\n', receivePack(read, objectSink, refSource,
309+ refSink))
267310 default:
268311 return pull.error(new Error('Unknown service ' + args[0]))
269312 }
270313 }
test/git-remote-test.jsView
@@ -8,9 +8,12 @@
88 require('../')({
99 prefix: 'foo',
1010 objectSink: pull.drain(function (obj) {
1111 console.error('obj', obj)
12- })
12+ }),
13+ refSink: pull.drain(function (ref) {
14+ console.error('ref', ref)
15+ }),
1316 }),
1417 toPull(process.stdout, function (err) {
1518 if (err)
1619 throw err
test/run.jsView
@@ -27,8 +27,15 @@
2727 t.end()
2828 })
2929 })
3030
31+tape('push with empty repo', function (t) {
32+ git('push', remote, function (code) {
33+ t.equals(code, 0, 'pushed')
34+ t.end()
35+ })
36+})
37+
3138 tape('make a commit and push', function (t) {
3239 var filename = path.join(tmpDir, 'blah.txt')
3340 fs.writeFile(filename, 'i am a file', function (err) {
3441 t.error(err, 'wrote a file')
@@ -44,8 +51,17 @@
4451 })
4552 })
4653 })
4754
55+/*
56+tape('fetch', function (t) {
57+ git('fetch', '-vv', remote, function (code) {
58+ t.equals(code, 0, 'fetched')
59+ t.end()
60+ })
61+})
62+*/
63+
4864 tape.onFinish(function () {
4965 if (tmpDir)
5066 rimraf.sync(tmpDir)
5167 })

Built with git-ssb-web