1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 package org.eclipse.jgit.transport;
45
46 import static org.junit.Assert.assertEquals;
47 import static org.junit.Assert.assertFalse;
48 import static org.junit.Assert.assertNotNull;
49 import static org.junit.Assert.assertNull;
50 import static org.junit.Assert.assertSame;
51 import static org.junit.Assert.assertTrue;
52 import static org.junit.Assert.fail;
53
54 import java.io.ByteArrayInputStream;
55 import java.io.IOException;
56 import java.net.URISyntaxException;
57 import java.security.MessageDigest;
58 import java.util.Collections;
59 import java.util.HashMap;
60 import java.util.Map;
61 import java.util.Set;
62 import java.util.concurrent.atomic.AtomicReference;
63 import java.util.zip.Deflater;
64
65 import org.eclipse.jgit.errors.MissingObjectException;
66 import org.eclipse.jgit.errors.UnpackException;
67 import org.eclipse.jgit.internal.storage.file.ObjectDirectory;
68 import org.eclipse.jgit.internal.storage.pack.BinaryDelta;
69 import org.eclipse.jgit.junit.LocalDiskRepositoryTestCase;
70 import org.eclipse.jgit.junit.TestRepository;
71 import org.eclipse.jgit.lib.Constants;
72 import org.eclipse.jgit.lib.NullProgressMonitor;
73 import org.eclipse.jgit.lib.ObjectId;
74 import org.eclipse.jgit.lib.ObjectInserter;
75 import org.eclipse.jgit.lib.ObjectLoader;
76 import org.eclipse.jgit.lib.Ref;
77 import org.eclipse.jgit.lib.Repository;
78 import org.eclipse.jgit.revwalk.RevBlob;
79 import org.eclipse.jgit.revwalk.RevCommit;
80 import org.eclipse.jgit.revwalk.RevTree;
81 import org.eclipse.jgit.revwalk.RevWalk;
82 import org.eclipse.jgit.util.NB;
83 import org.eclipse.jgit.util.TemporaryBuffer;
84 import org.junit.After;
85 import org.junit.Before;
86 import org.junit.Test;
87
88 public class ReceivePackAdvertiseRefsHookTest extends LocalDiskRepositoryTestCase {
89 private static final NullProgressMonitor PM = NullProgressMonitor.INSTANCE;
90
91 private static final String R_MASTER = Constants.R_HEADS + Constants.MASTER;
92
93 private static final String R_PRIVATE = Constants.R_HEADS + "private";
94
95 private Repository src;
96
97 private Repository dst;
98
99 private RevCommit A, B, P;
100
101 private RevBlob a, b;
102
103 @Override
104 @Before
105 public void setUp() throws Exception {
106 super.setUp();
107
108 src = createBareRepository();
109 dst = createBareRepository();
110
111
112
113 TestRepository<Repository> d = new TestRepository<>(dst);
114 a = d.blob("a");
115 A = d.commit(d.tree(d.file("a", a)));
116 B = d.commit().parent(A).create();
117 d.update(R_MASTER, B);
118
119
120
121 try (Transport t = Transport.open(src, uriOf(dst))) {
122 t.fetch(PM, Collections.singleton(new RefSpec("+refs/*:refs/*")));
123 assertEquals(B, src.resolve(R_MASTER));
124 }
125
126
127
128 b = d.blob("b");
129 P = d.commit(d.tree(d.file("b", b)), A);
130 d.update(R_PRIVATE, P);
131 }
132
133 @Test
134 public void testFilterHidesPrivate() throws Exception {
135 Map<String, Ref> refs;
136 try (TransportLocal t = new TransportLocal(src, uriOf(dst),
137 dst.getDirectory()) {
138 @Override
139 ReceivePack createReceivePack(Repository db) {
140 db.close();
141 dst.incrementOpen();
142
143 final ReceivePack rp = super.createReceivePack(dst);
144 rp.setAdvertiseRefsHook(new HidePrivateHook());
145 return rp;
146 }
147 }) {
148 try (PushConnection c = t.openPush()) {
149 refs = c.getRefsMap();
150 }
151 }
152
153 assertNotNull(refs);
154 assertNull("no private", refs.get(R_PRIVATE));
155 assertNull("no HEAD", refs.get(Constants.HEAD));
156 assertEquals(1, refs.size());
157
158 Ref master = refs.get(R_MASTER);
159 assertNotNull("has master", master);
160 assertEquals(B, master.getObjectId());
161 }
162
163 @Test
164 public void resetsHaves() throws Exception {
165 AtomicReference<Set<ObjectId>> haves = new AtomicReference<>();
166 try (TransportLocal t = new TransportLocal(src, uriOf(dst),
167 dst.getDirectory()) {
168 @Override
169 ReceivePack createReceivePack(Repository db) {
170 dst.incrementOpen();
171
172 ReceivePack rp = super.createReceivePack(dst);
173 rp.setAdvertiseRefsHook(new AdvertiseRefsHook() {
174 @Override
175 public void advertiseRefs(BaseReceivePack rp2)
176 throws ServiceMayNotContinueException {
177 rp.setAdvertisedRefs(rp.getRepository().getAllRefs(),
178 null);
179 new HidePrivateHook().advertiseRefs(rp);
180 haves.set(rp.getAdvertisedObjects());
181 }
182
183 @Override
184 public void advertiseRefs(UploadPack uploadPack)
185 throws ServiceMayNotContinueException {
186 throw new UnsupportedOperationException();
187 }
188 });
189 return rp;
190 }
191 }) {
192 try (PushConnection c = t.openPush()) {
193
194 }
195 }
196
197 assertEquals(1, haves.get().size());
198 assertTrue(haves.get().contains(B));
199 assertFalse(haves.get().contains(P));
200 }
201
202 private TransportLocal newTransportLocalWithStrictValidation()
203 throws Exception {
204 return new TransportLocal(src, uriOf(dst), dst.getDirectory()) {
205 @Override
206 ReceivePack createReceivePack(Repository db) {
207 db.close();
208 dst.incrementOpen();
209
210 final ReceivePack rp = super.createReceivePack(dst);
211 rp.setCheckReceivedObjects(true);
212 rp.setCheckReferencedObjectsAreReachable(true);
213 rp.setAdvertiseRefsHook(new HidePrivateHook());
214 return rp;
215 }
216 };
217 }
218
219 @Test
220 public void testSuccess() throws Exception {
221
222
223 TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
224
225 packHeader(pack, 2);
226 pack.write((Constants.OBJ_BLOB) << 4 | 1);
227 deflate(pack, new byte[] { 'a' });
228
229 pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
230 a.copyRawTo(pack);
231 deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
232
233 digest(pack);
234 openPack(pack);
235
236
237
238 ObjectDirectory od = (ObjectDirectory) src.getObjectDatabase();
239 assertTrue("has b", src.hasObject(b));
240 assertFalse("b not loose", od.fileFor(b).exists());
241
242
243
244 TestRepository<Repository> s = new TestRepository<>(src);
245 RevCommit N = s.commit().parent(B).add("q", b).create();
246 s.update(R_MASTER, N);
247
248
249
250 PushResult r;
251 RemoteRefUpdate u = new RemoteRefUpdate(
252 src,
253 R_MASTER,
254 R_MASTER,
255 false,
256 null,
257 null
258 );
259 try (TransportLocal t = newTransportLocalWithStrictValidation()) {
260 t.setPushThin(true);
261 r = t.push(PM, Collections.singleton(u));
262 dst.close();
263 }
264
265 assertNotNull("have result", r);
266 assertNull("private not advertised", r.getAdvertisedRef(R_PRIVATE));
267 assertSame("master updated", RemoteRefUpdate.Status.OK, u.getStatus());
268 assertEquals(N, dst.resolve(R_MASTER));
269 }
270
271 @Test
272 public void testCreateBranchAtHiddenCommitFails() throws Exception {
273 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(64);
274 packHeader(pack, 0);
275 digest(pack);
276
277 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(256);
278 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
279 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + P.name() + ' '
280 + "refs/heads/s" + '\0'
281 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
282 inPckLine.end();
283 pack.writeTo(inBuf, PM);
284
285 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
286 final ReceivePack rp = new ReceivePack(dst);
287 rp.setCheckReceivedObjects(true);
288 rp.setCheckReferencedObjectsAreReachable(true);
289 rp.setAdvertiseRefsHook(new HidePrivateHook());
290 try {
291 receive(rp, inBuf, outBuf);
292 fail("Expected UnpackException");
293 } catch (UnpackException failed) {
294 Throwable err = failed.getCause();
295 assertTrue(err instanceof MissingObjectException);
296 MissingObjectException moe = (MissingObjectException) err;
297 assertEquals(P, moe.getObjectId());
298 }
299
300 final PacketLineIn r = asPacketLineIn(outBuf);
301 String master = r.readString();
302 int nul = master.indexOf('\0');
303 assertTrue("has capability list", nul > 0);
304 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
305 assertSame(PacketLineIn.END, r.readString());
306
307 assertEquals("unpack error Missing commit " + P.name(), r.readString());
308 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
309 assertSame(PacketLineIn.END, r.readString());
310 }
311
312 private static void receive(final ReceivePack rp,
313 final TemporaryBuffer.Heap inBuf, final TemporaryBuffer.Heap outBuf)
314 throws IOException {
315 rp.receive(new ByteArrayInputStream(inBuf.toByteArray()), outBuf, null);
316 }
317
318 @Test
319 public void testUsingHiddenDeltaBaseFails() throws Exception {
320 byte[] delta = { 0x1, 0x1, 0x1, 'c' };
321 TestRepository<Repository> s = new TestRepository<>(src);
322 RevCommit N = s.commit().parent(B).add("q",
323 s.blob(BinaryDelta.apply(dst.open(b).getCachedBytes(), delta)))
324 .create();
325
326 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
327 packHeader(pack, 3);
328 copy(pack, src.open(N));
329 copy(pack, src.open(s.parseBody(N).getTree()));
330 pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
331 b.copyRawTo(pack);
332 deflate(pack, delta);
333 digest(pack);
334
335 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
336 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
337 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' '
338 + "refs/heads/s" + '\0'
339 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
340 inPckLine.end();
341 pack.writeTo(inBuf, PM);
342
343 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
344 final ReceivePack rp = new ReceivePack(dst);
345 rp.setCheckReceivedObjects(true);
346 rp.setCheckReferencedObjectsAreReachable(true);
347 rp.setAdvertiseRefsHook(new HidePrivateHook());
348 try {
349 receive(rp, inBuf, outBuf);
350 fail("Expected UnpackException");
351 } catch (UnpackException failed) {
352 Throwable err = failed.getCause();
353 assertTrue(err instanceof MissingObjectException);
354 MissingObjectException moe = (MissingObjectException) err;
355 assertEquals(b, moe.getObjectId());
356 }
357
358 final PacketLineIn r = asPacketLineIn(outBuf);
359 String master = r.readString();
360 int nul = master.indexOf('\0');
361 assertTrue("has capability list", nul > 0);
362 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
363 assertSame(PacketLineIn.END, r.readString());
364
365 assertEquals("unpack error Missing blob " + b.name(), r.readString());
366 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
367 assertSame(PacketLineIn.END, r.readString());
368 }
369
370 @Test
371 public void testUsingHiddenCommonBlobFails() throws Exception {
372
373
374 TestRepository<Repository> s = new TestRepository<>(src);
375 RevCommit N = s.commit().parent(B).add("q", s.blob("b")).create();
376
377
378
379 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
380 packHeader(pack, 2);
381 copy(pack, src.open(N));
382 copy(pack,src.open(s.parseBody(N).getTree()));
383 digest(pack);
384
385 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
386 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
387 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' '
388 + "refs/heads/s" + '\0'
389 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
390 inPckLine.end();
391 pack.writeTo(inBuf, PM);
392
393 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
394 final ReceivePack rp = new ReceivePack(dst);
395 rp.setCheckReceivedObjects(true);
396 rp.setCheckReferencedObjectsAreReachable(true);
397 rp.setAdvertiseRefsHook(new HidePrivateHook());
398 try {
399 receive(rp, inBuf, outBuf);
400 fail("Expected UnpackException");
401 } catch (UnpackException failed) {
402 Throwable err = failed.getCause();
403 assertTrue(err instanceof MissingObjectException);
404 MissingObjectException moe = (MissingObjectException) err;
405 assertEquals(b, moe.getObjectId());
406 }
407
408 final PacketLineIn r = asPacketLineIn(outBuf);
409 String master = r.readString();
410 int nul = master.indexOf('\0');
411 assertTrue("has capability list", nul > 0);
412 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
413 assertSame(PacketLineIn.END, r.readString());
414
415 assertEquals("unpack error Missing blob " + b.name(), r.readString());
416 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
417 assertSame(PacketLineIn.END, r.readString());
418 }
419
420 @Test
421 public void testUsingUnknownBlobFails() throws Exception {
422
423
424 TestRepository<Repository> s = new TestRepository<>(src);
425 RevBlob n = s.blob("n");
426 RevCommit N = s.commit().parent(B).add("q", n).create();
427
428
429
430 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
431 packHeader(pack, 2);
432 copy(pack, src.open(N));
433 copy(pack,src.open(s.parseBody(N).getTree()));
434 digest(pack);
435
436 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
437 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
438 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' '
439 + "refs/heads/s" + '\0'
440 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
441 inPckLine.end();
442 pack.writeTo(inBuf, PM);
443
444 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
445 final ReceivePack rp = new ReceivePack(dst);
446 rp.setCheckReceivedObjects(true);
447 rp.setCheckReferencedObjectsAreReachable(true);
448 rp.setAdvertiseRefsHook(new HidePrivateHook());
449 try {
450 receive(rp, inBuf, outBuf);
451 fail("Expected UnpackException");
452 } catch (UnpackException failed) {
453 Throwable err = failed.getCause();
454 assertTrue(err instanceof MissingObjectException);
455 MissingObjectException moe = (MissingObjectException) err;
456 assertEquals(n, moe.getObjectId());
457 }
458
459 final PacketLineIn r = asPacketLineIn(outBuf);
460 String master = r.readString();
461 int nul = master.indexOf('\0');
462 assertTrue("has capability list", nul > 0);
463 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
464 assertSame(PacketLineIn.END, r.readString());
465
466 assertEquals("unpack error Missing blob " + n.name(), r.readString());
467 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
468 assertSame(PacketLineIn.END, r.readString());
469 }
470
471 @Test
472 public void testIncludesInvalidGitmodules() throws Exception {
473 final TemporaryBuffer.Heap inBuf = setupSourceRepoInvalidGitmodules();
474 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
475 final ReceivePack rp = new ReceivePack(dst);
476 rp.setCheckReceivedObjects(true);
477 rp.setCheckReferencedObjectsAreReachable(true);
478 rp.setAdvertiseRefsHook(new HidePrivateHook());
479 try {
480 receive(rp, inBuf, outBuf);
481 fail("Expected UnpackException");
482 } catch (UnpackException failed) {
483 Throwable err = failed.getCause();
484 assertTrue(err instanceof IOException);
485 }
486
487 final PacketLineIn r = asPacketLineIn(outBuf);
488 String master = r.readString();
489 int nul = master.indexOf('\0');
490 assertTrue("has capability list", nul > 0);
491 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
492 assertSame(PacketLineIn.END, r.readString());
493
494 String errorLine = r.readString();
495 assertTrue(errorLine.startsWith("unpack error"));
496 assertTrue(errorLine.contains("Invalid submodule URL '-"));
497 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
498 assertSame(PacketLineIn.END, r.readString());
499 }
500
501 private TemporaryBuffer.Heap setupSourceRepoInvalidGitmodules()
502 throws IOException, Exception, MissingObjectException {
503 String fakeGitmodules = new StringBuilder()
504 .append("[submodule \"test\"]\n")
505 .append(" path = xlib\n")
506 .append(" url = https://example.com/repo/xlib.git\n\n")
507 .append("[submodule \"test2\"]\n")
508 .append(" path = zlib\n")
509 .append(" url = -upayload.sh\n")
510 .toString();
511
512 TestRepository<Repository> s = new TestRepository<>(src);
513 RevBlob blob = s.blob(fakeGitmodules);
514 RevCommit N = s.commit().parent(B)
515 .add(".gitmodules", blob).create();
516 RevTree t = s.parseBody(N).getTree();
517
518 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
519 packHeader(pack, 3);
520 copy(pack, src.open(N));
521 copy(pack, src.open(t));
522 copy(pack, src.open(blob));
523 digest(pack);
524
525 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
526 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
527 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' '
528 + "refs/heads/s" + '\0'
529 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
530 inPckLine.end();
531 pack.writeTo(inBuf, PM);
532 return inBuf;
533 }
534
535 @Test
536 public void testUsingUnknownTreeFails() throws Exception {
537 TestRepository<Repository> s = new TestRepository<>(src);
538 RevCommit N = s.commit().parent(B).add("q", s.blob("a")).create();
539 RevTree t = s.parseBody(N).getTree();
540
541
542
543 final TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
544 packHeader(pack, 1);
545 copy(pack, src.open(N));
546 digest(pack);
547
548 final TemporaryBuffer.Heap inBuf = new TemporaryBuffer.Heap(1024);
549 final PacketLineOut inPckLine = new PacketLineOut(inBuf);
550 inPckLine.writeString(ObjectId.zeroId().name() + ' ' + N.name() + ' '
551 + "refs/heads/s" + '\0'
552 + BasePackPushConnection.CAPABILITY_REPORT_STATUS);
553 inPckLine.end();
554 pack.writeTo(inBuf, PM);
555
556 final TemporaryBuffer.Heap outBuf = new TemporaryBuffer.Heap(1024);
557 final ReceivePack rp = new ReceivePack(dst);
558 rp.setCheckReceivedObjects(true);
559 rp.setCheckReferencedObjectsAreReachable(true);
560 rp.setAdvertiseRefsHook(new HidePrivateHook());
561 try {
562 receive(rp, inBuf, outBuf);
563 fail("Expected UnpackException");
564 } catch (UnpackException failed) {
565 Throwable err = failed.getCause();
566 assertTrue(err instanceof MissingObjectException);
567 MissingObjectException moe = (MissingObjectException) err;
568 assertEquals(t, moe.getObjectId());
569 }
570
571 final PacketLineIn r = asPacketLineIn(outBuf);
572 String master = r.readString();
573 int nul = master.indexOf('\0');
574 assertTrue("has capability list", nul > 0);
575 assertEquals(B.name() + ' ' + R_MASTER, master.substring(0, nul));
576 assertSame(PacketLineIn.END, r.readString());
577
578 assertEquals("unpack error Missing tree " + t.name(), r.readString());
579 assertEquals("ng refs/heads/s n/a (unpacker error)", r.readString());
580 assertSame(PacketLineIn.END, r.readString());
581 }
582
583 private static void packHeader(TemporaryBuffer.Heap tinyPack, int cnt)
584 throws IOException {
585 final byte[] hdr = new byte[8];
586 NB.encodeInt32(hdr, 0, 2);
587 NB.encodeInt32(hdr, 4, cnt);
588
589 tinyPack.write(Constants.PACK_SIGNATURE);
590 tinyPack.write(hdr, 0, 8);
591 }
592
593 private static void copy(TemporaryBuffer.Heap tinyPack, ObjectLoader ldr)
594 throws IOException {
595 final byte[] buf = new byte[64];
596 final byte[] content = ldr.getCachedBytes();
597 int dataLength = content.length;
598 int nextLength = dataLength >>> 4;
599 int size = 0;
600 buf[size++] = (byte) ((nextLength > 0 ? 0x80 : 0x00)
601 | (ldr.getType() << 4) | (dataLength & 0x0F));
602 dataLength = nextLength;
603 while (dataLength > 0) {
604 nextLength >>>= 7;
605 buf[size++] = (byte) ((nextLength > 0 ? 0x80 : 0x00) | (dataLength & 0x7F));
606 dataLength = nextLength;
607 }
608 tinyPack.write(buf, 0, size);
609 deflate(tinyPack, content);
610 }
611
612 private static void deflate(TemporaryBuffer.Heap tinyPack,
613 final byte[] content)
614 throws IOException {
615 final Deflater deflater = new Deflater();
616 final byte[] buf = new byte[128];
617 deflater.setInput(content, 0, content.length);
618 deflater.finish();
619 do {
620 final int n = deflater.deflate(buf, 0, buf.length);
621 if (n > 0)
622 tinyPack.write(buf, 0, n);
623 } while (!deflater.finished());
624 }
625
626 private static void digest(TemporaryBuffer.Heap buf) throws IOException {
627 MessageDigest md = Constants.newMessageDigest();
628 md.update(buf.toByteArray());
629 buf.write(md.digest());
630 }
631
632 private ObjectInserter inserter;
633
634 @After
635 public void release() {
636 if (inserter != null) {
637 inserter.close();
638 }
639 }
640
641 private void openPack(TemporaryBuffer.Heap buf) throws IOException {
642 if (inserter == null)
643 inserter = src.newObjectInserter();
644
645 final byte[] raw = buf.toByteArray();
646 PackParser p = inserter.newPackParser(new ByteArrayInputStream(raw));
647 p.setAllowThin(true);
648 p.parse(PM);
649 }
650
651 private static PacketLineIn asPacketLineIn(TemporaryBuffer.Heap buf)
652 throws IOException {
653 return new PacketLineIn(new ByteArrayInputStream(buf.toByteArray()));
654 }
655
656 private static final class HidePrivateHook extends AbstractAdvertiseRefsHook {
657 @Override
658 public Map<String, Ref> getAdvertisedRefs(Repository r, RevWalk revWalk) {
659 Map<String, Ref> refs = new HashMap<>(r.getAllRefs());
660 assertNotNull(refs.remove(R_PRIVATE));
661 return refs;
662 }
663 }
664
665 private static URIish uriOf(Repository r) throws URISyntaxException {
666 return new URIish(r.getDirectory().getAbsolutePath());
667 }
668 }