git ssb

0+

cel / pull-git-remote-helper



Commit a53fb68ffb75c9fc0ff72ebbe56746e37f323cdc

Start using abstract-pull-git-repo API

Charles Lehner committed on 2/17/2016, 11:09:24 PM
Parent: 9c5fc252c08c46239564a18250cc3d09354a620b

Files changed

README.mdchanged
index.jschanged
package.jsonchanged
test/remote/git-remote-empty.jschanged
test/remote/git-remote-full.jschanged
test/run.jschanged
README.mdView
@@ -11,99 +11,53 @@
1111 var toPull = require('stream-to-pull-stream')
1212 var pull = require('pull-stream')
1313 var gitRemoteHelper = require('.')
1414
15-var options = {
16- updateSink: pull.drain(function (update) {
17- console.error('Updating ' + update.name + ' to ' + update.new)
18- }),
19- objectSink: function (read) {
20- read(null, function next(end, object) {
15+var repo = {
16+ refs: pull.empty(),
17+ hasObject: function (hash, cb) { cb(null, false) },
18+ getObject: function (hash, cb) { cb(null, null) },
19+ update: function (readUpdates, readObjects) {
20+ pull(
21+ readUpdates,
22+ pull.drain(function (update) {
23+ console.error('Updating ' + update.name + ' to ' + update.new)
24+ })
25+ )
26+ readObjects(null, function next(end, object) {
2127 if (end === true) return
2228 if (end) throw end
2329 pull(
2430 object.read,
2531 pull.collect(function (err, bufs) {
2632 if (err) throw err
2733 var buf = Buffer.concat(bufs, object.length)
2834 console.error('Got object', object, buf)
29- read(null, next)
35+ readObjects(null, next)
3036 })
3137 )
3238 })
3339 }
3440 }
3541
3642 pull(
3743 toPull(process.stdin),
38- gitRemoteHelper(options),
44+ gitRemoteHelper(repo),
3945 toPull(process.stdout)
4046 )
47+
4148 ```
4249
4350 ## API
4451
45-The streams in this module are [pull-streams](https://github.com/dominictarr/pull-stream).
52+#### `gitRemoteHelper(repo)`
4653
47-- `gitRemoteHelper(options)`
48-
4954 Create a through-stream for the stdio of a git-remote-helper
5055
51-- `options.refsSource`
56+- `repo`: an [abstract-pull-git-repo][]-compliant git repo object.
5257
53- Readable stream of refs that the remote has.
58+[abstract-pull-git-repo]: https://github.com/clehner/abstract-pull-git-repo
5459
55- Ref object are of the form `{name: name, value: hash}`
56-
57- - `ref.name`: a name like `"HEAD"` or `"refs/heads/master"`
58- - `ref.value`: 20-character SHA1 hash of a commit
59-
60-- `options.updateSink`
61-
62- Reader for updates received from the client during a `git push`.
63-
64- - `update.name`: the name of the ref, e.g. `"refs/heads/master"`
65- - `update.old`: the previous rev (commit SHA1 hash) of the branch.
66- May be null if the branch did not exist before.
67- - `update.new`: the new rev of the branch. null to delete the ref.
68-
69-- `options.objectSink`
70-
71- Reader for git objects received in a `git push`.
72-
73- - `object.type`: the type of the object, either
74- `"tag"`, `"commit"`, `"tree"`, or `"blob"`
75- - `object.length`: the size in bytes of the object
76- - `object.read`: readable stream of the object's data. This has to be
77- drained before `objectSink` can read the next object.
78-
79-- `options.wantSink`
80-
81- Reader for wants received by client during a `git fetch`.
82-
83- - `want.type == "want"`: the client wants this object
84- - `want.type == "shallow"`: the client *has* this object but it is shallow.
85- TODO: put this somewhere else
86- - `want.hash`: SHA1 hash of the object
87-
88-- `options.hasObject`: `function (hash, cb(Boolean))`
89-
90- Query the remote if it has a specific git object. Used in `git fetch` to help
91- the remote decide what objects to send to the client.
92-
93-- `options.getObjects`: `function (id, cb(end, numObjects, readObject))`
94-
95- Get a stream of git objects to send to the client. These should include the
96- objects passed from the client as wants in `wantSink`, and their history
97- (ancestor commits and their objects), but don't have to go further back than
98- the common ancestor object `id`.
99-
100- - `id`: hash of a common ancestor of objects that the client and the remote
101- have.
102- - `end`: read error or `true` if the stream is done
103- - `numObjects`: number of objects that readObject will stream
104- - `readObject`: readable stream of git objects
105-
10660 ## TODO
10761
10862 - Implement tree-walking to simplify `wantSink` and `getObjects`
10963 - Handle shallow and unshallow fetch
index.jsView
@@ -51,12 +51,14 @@
5151 }
5252 }
5353
5454 // upload-pack: fetch to client
55-function uploadPack(read, hasObject, getObjects, refSource, wantSink, options) {
55+function uploadPack(read, repo, options) {
56+ // getObjects, wantSink
5657 /* multi_ack thin-pack side-band side-band-64k ofs-delta shallow no-progress
5758 * include-tag multi_ack_detailed symref=HEAD:refs/heads/master
5859 * agent=git/2.7.0 */
60+ var refSource = repo.refs.bind(repo)
5961 var sendRefs = receivePackHeader([
6062 ], refSource, false)
6163
6264 var lines = pktLine.decode(read, options)
@@ -105,9 +107,10 @@
105107 cb(end)
106108 else if (have.type != 'have')
107109 cb(new Error('Unknown have' + JSON.stringify(have)))
108110 else
109- hasObject(have.hash, function (haveIt) {
111+ repo.hasObject(have.hash, function (err, haveIt) {
112+ if (err) return cb(err)
110113 if (!haveIt)
111114 return readHave(null, next)
112115 commonHash = haveIt
113116 acked = true
@@ -164,10 +167,11 @@
164167 }
165168 }
166169
167170 // receive-pack: push from client
168-function receivePack(read, objectSink, refSource, updateSink, options) {
171+function receivePack(read, repo, options) {
169172 var ended
173+ var refSource = repo.refs.bind(repo)
170174 var sendRefs = receivePackHeader([
171175 'delete-refs',
172176 ], refSource, true)
173177
@@ -181,18 +185,19 @@
181185 // receive their refs
182186 var lines = pktLine.decode(read, options)
183187 pull(
184188 lines.updates,
185- pull.through(null, updatesDone),
186- updateSink
189+ pull.collect(function (err, updates) {
190+ if (err) return cb(err)
191+ repo.update(pull.values(updates), pull(
192+ lines.passthrough,
193+ pack.decode(onEnd)
194+ ), onEnd)
195+ })
187196 )
188- function updatesDone(err) {
189- if (err) return cb(err)
190- pull(
191- lines.passthrough,
192- pack.decode(cb),
193- objectSink
194- )
197+ function onEnd(err) {
198+ if (!ended)
199+ cb(ended = err)
195200 }
196201 },
197202 pull.once('unpack ok')
198203 ])
@@ -210,19 +215,15 @@
210215 }
211216 }
212217 }
213218
214-module.exports = function (opts) {
219+module.exports = function (repo) {
215220 var ended
216- var objectSink = opts.objectSink ||
217- function () { throw new Error('Missing object sink') }
218- var hasObject = opts.hasObject || function (hash, cb) { cb(false) }
221+ /*
219222 var getObjects = opts.getObjects || function (id, cb) {
220223 cb(null, 0, pull.empty())
221224 }
222- var refSource = opts.refSource || pull.empty()
223- var updateSink = opts.updateSink || pull.drain()
224- var wantSink = opts.wantSink || pull.drain()
225+ */
225226
226227 var options = {
227228 verbosity: 1,
228229 progress: false
@@ -231,13 +232,11 @@
231232 function handleConnect(cmd, read) {
232233 var args = util.split2(cmd)
233234 switch (args[0]) {
234235 case 'git-upload-pack':
235- return prepend('\n', uploadPack(read, hasObject, getObjects, refSource,
236- wantSink, options))
236+ return prepend('\n', uploadPack(read, repo, options))
237237 case 'git-receive-pack':
238- return prepend('\n', receivePack(read, objectSink, refSource,
239- updateSink, options))
238+ return prepend('\n', receivePack(read, repo, options))
240239 default:
241240 return pull.error(new Error('Unknown service ' + args[0]))
242241 }
243242 }
package.jsonView
@@ -11,8 +11,9 @@
1111 "url": "git://github.com/clehner/pull-git-remote-helper"
1212 },
1313 "keywords": [
1414 "pull-stream",
15+ "pull-git-repo",
1516 "git",
1617 "git-remote-helper"
1718 ],
1819 "author": "Charles Lehner (http://celehner.com/)",
test/remote/git-remote-empty.jsView
@@ -13,10 +13,21 @@
1313
1414 pull(
1515 toPull(process.stdin),
1616 require('../../')({
17- objectSink: function (read) {
18- read(null, function next(end, object) {
17+ refs: pull.empty(),
18+ hasObject: function (hash, cb) { cb(null, false) },
19+ getObject: function (hash, cb) { cb(null, null) },
20+ update: function (readRefs, readObjects) {
21+ pull(
22+ readRefs,
23+ pull.drain(function (update) {
24+ process.send({update: update})
25+ }, function (err) {
26+ if (err) throw err
27+ })
28+ )
29+ readObjects(null, function next(end, object) {
1930 if (end === true) return
2031 if (end) throw end
2132 var hasher = util.createGitObjectHash(object.type, object.length)
2233 pull(
@@ -30,16 +41,13 @@
3041 data: buf.toString('ascii'),
3142 length: object.length,
3243 hash: hasher.digest('hex')
3344 }})
34- read(null, next)
45+ readObjects(null, next)
3546 })
3647 )
3748 })
38- },
39- updateSink: pull.drain(function (update) {
40- process.send({update: update})
41- })
49+ }
4250 }),
4351 toPull(process.stdout, function (err) {
4452 if (err)
4553 throw err
test/remote/git-remote-full.jsView
@@ -23,42 +23,30 @@
2323 {type: 'blob', object: repo.file}
2424 ]
2525
2626 var hashes = {}
27-hashes[repo.commit.hash] = 1
28-hashes[repo.tree.hash] = 1
29-hashes[repo.file.hash] = 1
27+hashes[repo.commit.hash] = objects[0]
28+hashes[repo.tree.hash] = objects[1]
29+hashes[repo.file.hash] = objects[2]
3030
31-function streamObject(read) {
32- var ended
33- return function readObject(abort, cb) {
34- read(abort, function (end, item) {
35- if (ended = end) return cb(end)
36- var data = item.object.data
37- cb(null, {
38- type: item.type,
39- length: data.length,
40- read: pull.once(data)
41- })
42- })
43- }
44-}
45-
4631 pull(
4732 toPull(process.stdin),
4833 require('../../')({
49- refSource: pull.values(refs),
34+ refs: pull.values(refs),
5035 wantSink: pull.drain(function (want) {
5136 process.send({want: want})
5237 }),
5338 hasObject: function (hash, cb) {
54- cb(hash in hashes)
39+ cb(null, hash in hashes)
5540 },
56- getObjects: function (ancestorHash, cb) {
57- cb(null, objects.length, pull(
58- pull.values(objects),
59- streamObject
60- ))
41+ getObject: function (hash, cb) {
42+ var item = hashes[hash]
43+ if (!item) return cb(null, null)
44+ cb(null, {
45+ type: item.type,
46+ length: item.object.data.length,
47+ read: pull.once(item.object.data)
48+ })
6149 }
6250 }),
6351 toPull(process.stdout, function (err) {
6452 if (err)
test/run.jsView
@@ -135,8 +135,9 @@
135135 t.end()
136136 })
137137 })
138138
139+0 &&
139140 tape('clone into new dir', function (t) {
140141 var dir = path.join(tmpDir, 'clonedir')
141142 t.plan(2)
142143 t.git('clone', remote.full, dir, function (msg) {

Built with git-ssb-web