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